From a52ef72f924e88453fae490225f0f4e23ee8724a Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Mon, 26 Feb 2024 10:58:52 +0100 Subject: [PATCH 001/377] introduce owned buffers --- include/zenoh_commons.h | 19 +++++++++-- include/zenoh_macros.h | 10 ++++++ src/attachment.rs | 4 ++- src/collections.rs | 70 ++++++++++++++++++++++++++++++++++++-- src/commons.rs | 21 +++--------- src/config.rs | 7 +--- src/get.rs | 2 +- src/keyexpr.rs | 20 ++--------- src/lib.rs | 22 +++++++++++- src/publication_cache.rs | 25 ++------------ src/publisher.rs | 4 +-- src/pull_subscriber.rs | 15 +------- src/queryable.rs | 21 ++---------- src/querying_subscriber.rs | 26 +++----------- src/session.rs | 22 ++---------- src/subscriber.rs | 23 ++----------- 16 files changed, 144 insertions(+), 167 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 9bf02fe81..c7d46f932 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -155,8 +155,8 @@ typedef enum zcu_reply_keyexpr_t { * and empty slices are represented using a possibly dangling pointer for `start`. */ typedef struct z_bytes_t { - size_t len; const uint8_t *start; + size_t len; } z_bytes_t; /** * The body of a loop over an attachment's key-value pairs. @@ -189,6 +189,15 @@ typedef struct z_attachment_t { const void *data; z_attachment_iter_driver_t iteration_driver; } z_attachment_t; +/** + * A buffer owned by Zenoh. + */ +typedef struct z_owned_buffer_t { + size_t _inner[5]; +} z_owned_buffer_t; +typedef struct z_buffer_t { + size_t _inner; +} z_buffer_t; /** * A map of maybe-owned vector of bytes to owned vector of bytes. * @@ -862,7 +871,7 @@ typedef struct zc_owned_liveliness_get_options_t { */ typedef struct zc_owned_payload_t { struct z_bytes_t payload; - size_t _owner[5]; + struct z_owned_buffer_t _owner; } zc_owned_payload_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; @@ -1027,6 +1036,12 @@ int8_t z_attachment_iterate(struct z_attachment_t this_, * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); +ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); +ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); +ZENOHC_API struct z_bytes_t z_buffer_payload(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index fa6668d48..494d01fb9 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -14,6 +14,7 @@ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ + z_owned_buffer_t: z_buffer_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ )(&x) @@ -42,6 +43,7 @@ z_owned_reply_channel_t * : z_reply_channel_drop, \ z_owned_query_channel_t * : z_query_channel_drop, \ z_owned_bytes_map_t * : z_bytes_map_drop, \ + z_owned_buffer_t * : z_buffer_drop, \ zc_owned_payload_t * : zc_payload_drop, \ zc_owned_shmbuf_t * : zc_shmbuf_drop, \ zc_owned_shm_manager_t * : zc_shm_manager_drop, \ @@ -73,6 +75,7 @@ z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ z_owned_reply_channel_t * : z_reply_channel_null, \ z_owned_bytes_map_t * : z_bytes_map_null, \ + z_owned_buffer_t * : z_buffer_null, \ z_attachment_t * : z_attachment_null, \ zc_owned_payload_t * : zc_payload_null, \ zc_owned_shmbuf_t * : zc_shmbuf_null, \ @@ -98,6 +101,7 @@ z_owned_query_t : z_query_check, \ z_owned_str_t : z_str_check, \ z_owned_bytes_map_t : z_bytes_map_check, \ + z_owned_buffer_t : z_buffer_check, \ z_attachment_t : z_attachment_check, \ zc_owned_payload_t : zc_payload_check, \ zc_owned_shmbuf_t : zc_shmbuf_check, \ @@ -141,6 +145,7 @@ template<> struct zenoh_loan_type{ typedef z_pull_sub template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; +template<> struct zenoh_loan_type{ typedef z_buffer_t type; }; template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } @@ -153,6 +158,7 @@ template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_en template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } +template<> inline z_buffer_t z_loan(const z_owned_buffer_t& x) { return z_buffer_loan(&x); } template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } template struct zenoh_drop_type { typedef T type; }; @@ -171,6 +177,7 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -200,6 +207,7 @@ template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } +template<> inline void z_drop(z_owned_buffer_t* v) { z_buffer_drop(v); } template<> inline void z_drop(zc_owned_payload_t* v) { zc_payload_drop(v); } template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } @@ -229,6 +237,7 @@ inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } +inline void z_null(z_owned_buffer_t& v) { v = z_buffer_null(); } inline void z_null(zc_owned_payload_t& v) { v = zc_payload_null(); } inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } @@ -263,6 +272,7 @@ inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } +inline bool z_check(const z_owned_buffer_t& v) { return z_buffer_check(&v); } inline bool z_check(const z_owned_bytes_map_t& v) { return z_bytes_map_check(&v); } inline bool z_check(const z_attachment_t& v) { return z_attachment_check(&v); } inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } diff --git a/src/attachment.rs b/src/attachment.rs index 5dbbfec5c..051edafdc 100644 --- a/src/attachment.rs +++ b/src/attachment.rs @@ -13,6 +13,7 @@ use zenoh::sample::{Attachment, AttachmentBuilder}; /// /// Returning `0` is treated as `continue`. /// Returning any other value is treated as `break`. +#[allow(non_camel_case_types)] pub type z_attachment_iter_body_t = extern "C" fn(key: z_bytes_t, value: z_bytes_t, context: *mut c_void) -> i8; @@ -20,6 +21,7 @@ pub type z_attachment_iter_body_t = /// /// This function is expected to call `loop_body` once for each key-value pair /// within `iterator`, passing `context`, and returning any non-zero value immediately (breaking iteration). +#[allow(non_camel_case_types)] pub type z_attachment_iter_driver_t = Option< extern "C" fn( iterator: *const c_void, @@ -124,7 +126,7 @@ pub struct z_owned_bytes_map_t { _1: [usize; 4], } -impl_guarded_transmute!( +impl_guarded_transmute!(noderefs Option, Cow<'static, [u8]>>>, z_owned_bytes_map_t ); diff --git a/src/collections.rs b/src/collections.rs index 9fd0c3c16..9ac7831c0 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -11,8 +11,14 @@ // Contributors: // ZettaScale Zenoh team, // + use libc::{c_char, size_t}; -use zenoh::prelude::ZenohId; +use zenoh::{ + buffers::{buffer::SplitBuffer, ZBuf}, + prelude::ZenohId, +}; + +use crate::impl_guarded_transmute; /// A contiguous view of bytes owned by some other entity. /// @@ -21,8 +27,8 @@ use zenoh::prelude::ZenohId; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct z_bytes_t { - pub len: size_t, pub start: *const u8, + pub len: size_t, } impl z_bytes_t { @@ -155,3 +161,63 @@ impl From<&[u8]> for z_bytes_t { } } } + +/// A buffer owned by Zenoh. +#[repr(C)] +pub struct z_owned_buffer_t { + _inner: [usize; 5], +} +impl_guarded_transmute!(Option, z_owned_buffer_t); + +#[no_mangle] +pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { + None.into() +} +#[no_mangle] +pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { + core::mem::drop(buffer.take()) +} + +#[no_mangle] +pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { + buffer.is_some() +} +#[no_mangle] +pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { + buffer.as_ref().into() +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct z_buffer_t { + _inner: usize, +} +impl_guarded_transmute!(noderefs Option<&ZBuf>, z_buffer_t); +impl From for Option<&'static ZBuf> { + fn from(value: z_buffer_t) -> Self { + unsafe { core::mem::transmute(value) } + } +} +impl From> for z_buffer_t { + fn from(value: Option<&ZBuf>) -> Self { + unsafe { core::mem::transmute(value) } + } +} +#[no_mangle] +pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { + unsafe { Some(core::mem::transmute::<_, &ZBuf>(buffer).clone()).into() } +} + +#[no_mangle] +pub extern "C" fn z_buffer_payload(buffer: z_buffer_t) -> z_bytes_t { + let Some(buffer): Option<&ZBuf> = buffer.into() else { + return z_bytes_null(); + }; + match buffer.contiguous() { + std::borrow::Cow::Borrowed(buffer) => buffer.into(), + std::borrow::Cow::Owned(_) => { + log::error!("A non-contiguous buffer reached user code, this is definitely a bug, please inform us at https://github.com/eclipse-zenoh/zenoh-c/issues/new"); + z_bytes_null() + } + } +} diff --git a/src/commons.rs b/src/commons.rs index 8ac21cb11..f96b9b09b 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -104,7 +104,7 @@ impl From> for z_timestamp_t { #[repr(C)] pub struct zc_owned_payload_t { pub payload: z_bytes_t, - pub _owner: [usize; 5], + pub _owner: z_owned_buffer_t, } impl Default for zc_owned_payload_t { fn default() -> Self { @@ -130,7 +130,9 @@ impl zc_owned_payload_t { } let start = std::mem::replace(&mut self.payload.start, std::ptr::null()); let len = std::mem::replace(&mut self.payload.len, 0); - let mut buf: ZBuf = unsafe { std::mem::transmute(self._owner) }; + let Some(mut buf) = self._owner.take() else { + return None; + }; { let mut slices = buf.zslices_mut(); let slice = slices.next().unwrap(); @@ -153,7 +155,7 @@ impl zc_owned_payload_t { if !z_bytes_check(&self.payload) { return None; } - unsafe { std::mem::transmute(&self._owner) } + self._owner.as_ref() } } impl Drop for zc_owned_payload_t { @@ -198,19 +200,6 @@ pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { pub struct z_qos_t(u8); impl_guarded_transmute!(QoS, z_qos_t); -impl_guarded_transmute!(z_qos_t, QoS); - -impl From for z_qos_t { - fn from(qos: QoS) -> Self { - qos.transmute() - } -} - -impl From for QoS { - fn from(qos: z_qos_t) -> QoS { - qos.transmute() - } -} /// Returns message priority. #[no_mangle] diff --git a/src/config.rs b/src/config.rs index 6e259f3b5..80e3a38f1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -15,7 +15,7 @@ use libc::{c_char, c_uint}; use std::ffi::CStr; use zenoh::config::{Config, ValidatedMap, WhatAmI}; -use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null, GuardedTransmute}; +use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -76,11 +76,6 @@ pub struct z_config_t(*const z_owned_config_t); pub struct z_owned_config_t(*mut ()); impl_guarded_transmute!(Option>, z_owned_config_t); -impl From>> for z_owned_config_t { - fn from(v: Option>) -> Self { - v.transmute() - } -} /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t { diff --git a/src/get.rs b/src/get.rs index 07bf0de65..41e3cf204 100644 --- a/src/get.rs +++ b/src/get.rs @@ -60,7 +60,7 @@ pub struct z_owned_reply_t([u64; 30]); #[repr(C, align(8))] pub struct z_owned_reply_t([u64; 19]); -impl_guarded_transmute!(ReplyInner, z_owned_reply_t); +impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); impl From for z_owned_reply_t { fn from(mut val: ReplyInner) -> Self { diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 04efe0c99..06784a8dc 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -62,27 +62,11 @@ pub struct z_owned_keyexpr_t([u32; 5]); impl_guarded_transmute!(Option>, z_owned_keyexpr_t); -impl From>> for z_owned_keyexpr_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} impl From> for z_owned_keyexpr_t { fn from(val: KeyExpr<'static>) -> Self { Some(val).into() } } -impl Deref for z_owned_keyexpr_t { - type Target = Option>; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl DerefMut for z_owned_keyexpr_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute(self) } - } -} impl z_owned_keyexpr_t { pub fn null() -> Self { None::.into() @@ -156,8 +140,8 @@ pub struct z_keyexpr_t([u64; 4]); #[repr(C, align(4))] pub struct z_keyexpr_t([u32; 5]); -impl_guarded_transmute!(Option>, z_keyexpr_t); -impl_guarded_transmute!(z_keyexpr_t, z_owned_keyexpr_t); +impl_guarded_transmute!(noderefs Option>, z_keyexpr_t); +impl_guarded_transmute!(noderefs z_keyexpr_t, z_owned_keyexpr_t); impl<'a> From> for z_keyexpr_t { fn from(val: KeyExpr<'a>) -> Self { diff --git a/src/lib.rs b/src/lib.rs index 718475444..19c22fa2e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -61,6 +61,26 @@ trait GuardedTransmute { #[macro_export] macro_rules! impl_guarded_transmute { ($src_type:ty, $dst_type:ty) => { + impl_guarded_transmute!(noderefs $src_type, $dst_type); + impl From<$src_type> for $dst_type { + fn from(value: $src_type) -> $dst_type { + unsafe { core::mem::transmute(value) } + } + } + impl core::ops::Deref for $dst_type { + type Target = $src_type; + fn deref(&self) -> &$src_type { + unsafe { core::mem::transmute(self) } + } + } + impl core::ops::DerefMut for $dst_type { + fn deref_mut(&mut self) -> &mut $src_type { + unsafe { core::mem::transmute(self) } + } + } + + }; + (noderefs $src_type:ty, $dst_type:ty) => { const _: () = { let src = std::mem::align_of::<$src_type>(); let dst = std::mem::align_of::<$dst_type>(); @@ -77,7 +97,7 @@ macro_rules! impl_guarded_transmute { }); } }; - impl $crate::GuardedTransmute<$dst_type> for $src_type { + impl $crate::GuardedTransmute<$dst_type> for $src_type { fn transmute(self) -> $dst_type { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 5b96a904c..ee4c85959 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -20,7 +20,7 @@ use zenoh_util::core::SyncResolve; use crate::{ impl_guarded_transmute, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t, - GuardedTransmute, UninitializedKeyExprError, + UninitializedKeyExprError, }; /// Options passed to the :c:func:`ze_declare_publication_cache` function. @@ -53,8 +53,6 @@ pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache } } -type PublicationCache = Option>>; - /// An owned zenoh publication_cache. /// /// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. @@ -68,26 +66,9 @@ type PublicationCache = Option>>; #[repr(C)] pub struct ze_owned_publication_cache_t([usize; 1]); +type PublicationCache = Option>>; impl_guarded_transmute!(PublicationCache, ze_owned_publication_cache_t); -impl From for ze_owned_publication_cache_t { - fn from(val: PublicationCache) -> Self { - val.transmute() - } -} - -impl AsRef for ze_owned_publication_cache_t { - fn as_ref(&self) -> &PublicationCache { - unsafe { std::mem::transmute(self) } - } -} - -impl AsMut for ze_owned_publication_cache_t { - fn as_mut(&mut self) -> &mut PublicationCache { - unsafe { std::mem::transmute(self) } - } -} - impl ze_owned_publication_cache_t { pub fn new(pub_cache: zenoh_ext::PublicationCache<'static>) -> Self { Some(Box::new(pub_cache)).into() @@ -187,7 +168,7 @@ pub extern "C" fn ze_publication_cache_check(pub_cache: &ze_owned_publication_ca pub extern "C" fn ze_undeclare_publication_cache( pub_cache: &mut ze_owned_publication_cache_t, ) -> i8 { - if let Some(p) = pub_cache.as_mut().take() { + if let Some(p) = pub_cache.take() { if let Err(e) = p.close().res_sync() { log::error!("{}", e); return e.errno().get(); diff --git a/src/publisher.rs b/src/publisher.rs index 42681093f..f49d8cd31 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -75,7 +75,7 @@ pub struct z_owned_publisher_t([u64; 7]); #[repr(C, align(4))] pub struct z_owned_publisher_t([u32; 8]); -impl_guarded_transmute!(Option>, z_owned_publisher_t); +impl_guarded_transmute!(noderefs Option>, z_owned_publisher_t); impl<'a> From>> for z_owned_publisher_t { fn from(val: Option) -> Self { @@ -387,7 +387,7 @@ pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_owned_keyex #[repr(C, align(8))] pub struct zcu_owned_matching_listener_t([u64; 4]); -impl_guarded_transmute!( +impl_guarded_transmute!(noderefs Option>, zcu_owned_matching_listener_t ); diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index 931b48d84..0eee4bc94 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -1,4 +1,3 @@ -use crate::GuardedTransmute; // // Copyright (c) 2017, 2022 ZettaScale Technology. // @@ -56,21 +55,9 @@ impl_guarded_transmute!(PullSubscriber, z_owned_pull_subscriber_t); #[allow(non_camel_case_types)] pub struct z_pull_subscriber_t<'a>(&'a z_owned_pull_subscriber_t); -impl From for z_owned_pull_subscriber_t { - fn from(val: PullSubscriber) -> Self { - val.transmute() - } -} - -impl AsRef for z_owned_pull_subscriber_t { - fn as_ref(&self) -> &PullSubscriber { - unsafe { std::mem::transmute(self) } - } -} - impl<'a> AsRef for z_pull_subscriber_t<'a> { fn as_ref(&self) -> &PullSubscriber { - self.0.as_ref() + self.0 } } diff --git a/src/queryable.rs b/src/queryable.rs index 5a7112afc..1906dc735 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -17,8 +17,7 @@ use crate::attachment::{ }; use crate::{ impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, GuardedTransmute, - LOG_INVALID_SESSION, + z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, LOG_INVALID_SESSION, }; use libc::c_void; use std::ops::{Deref, DerefMut}; @@ -52,22 +51,6 @@ pub struct z_owned_queryable_t([u32; 4]); impl_guarded_transmute!(Queryable, z_owned_queryable_t); -impl From for z_owned_queryable_t { - fn from(val: Queryable) -> Self { - val.transmute() - } -} -impl AsRef for z_owned_queryable_t { - fn as_ref(&self) -> &Queryable { - unsafe { std::mem::transmute(self) } - } -} -impl AsMut for z_owned_queryable_t { - fn as_mut(&mut self) -> &mut Queryable { - unsafe { std::mem::transmute(self) } - } -} - impl z_owned_queryable_t { pub fn null() -> Self { None.into() @@ -263,7 +246,7 @@ pub extern "C" fn z_declare_queryable( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> i8 { - if let Some(qable) = qable.as_mut().take() { + if let Some(qable) = qable.take() { if let Err(e) = qable.undeclare().res_sync() { log::error!("{}", e); return e.errno().get(); diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index d407f9646..cdec44f0f 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -25,10 +25,10 @@ use crate::{ z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, z_query_target_default, z_query_target_t, z_reliability_t, z_sample_t, z_session_t, zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, - GuardedTransmute, LOG_INVALID_SESSION, + LOG_INVALID_SESSION, }; -struct FetchingSubscriberWrapper { +pub struct FetchingSubscriberWrapper { fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, session: z_session_t, } @@ -54,27 +54,9 @@ impl_guarded_transmute!(FetchingSubscriber, ze_owned_querying_subscriber_t); #[allow(non_camel_case_types)] pub struct ze_querying_subscriber_t<'a>(&'a ze_owned_querying_subscriber_t); -impl From for ze_owned_querying_subscriber_t { - fn from(val: FetchingSubscriber) -> Self { - val.transmute() - } -} - -impl AsRef for ze_owned_querying_subscriber_t { - fn as_ref(&self) -> &FetchingSubscriber { - unsafe { std::mem::transmute(self) } - } -} - impl<'a> AsRef for ze_querying_subscriber_t<'a> { fn as_ref(&self) -> &FetchingSubscriber { - self.0.as_ref() - } -} - -impl AsMut for ze_owned_querying_subscriber_t { - fn as_mut(&mut self) -> &mut FetchingSubscriber { - unsafe { std::mem::transmute(self) } + self.0 } } @@ -276,7 +258,7 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn ze_undeclare_querying_subscriber(sub: &mut ze_owned_querying_subscriber_t) -> i8 { - if let Some(s) = sub.as_mut().take() { + if let Some(s) = sub.take() { if let Err(e) = s.fetching_subscriber.close().res_sync() { log::warn!("{}", e); return e.errno().get(); diff --git a/src/session.rs b/src/session.rs index a4329fbf6..2caab85ea 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh team, // -use crate::{config::*, impl_guarded_transmute, zc_init_logger, GuardedTransmute}; +use crate::{config::*, impl_guarded_transmute, zc_init_logger}; use std::sync::{Arc, Weak}; use zenoh::prelude::sync::SyncResolve; use zenoh::Session; @@ -33,24 +33,6 @@ pub struct z_owned_session_t(usize); impl_guarded_transmute!(Option>, z_owned_session_t); -impl From>> for z_owned_session_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} - -impl AsRef>> for z_owned_session_t { - fn as_ref(&self) -> &Option> { - unsafe { std::mem::transmute(self) } - } -} - -impl AsMut>> for z_owned_session_t { - fn as_mut(&mut self) -> &mut Option> { - unsafe { std::mem::transmute(self) } - } -} - impl AsRef>> for z_session_t { fn as_ref(&self) -> &Option> { unsafe { std::mem::transmute(self) } @@ -150,7 +132,7 @@ pub extern "C" fn z_session_check(session: &z_owned_session_t) -> bool { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { - let Some(s) = session.as_mut().take() else { + let Some(s) = session.take() else { return 0; }; let s = match Arc::try_unwrap(s) { diff --git a/src/subscriber.rs b/src/subscriber.rs index 910ec424b..b9488960a 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -18,7 +18,6 @@ use crate::keyexpr::*; use crate::session::*; use crate::z_closure_sample_call; use crate::z_owned_closure_sample_t; -use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; @@ -84,24 +83,6 @@ pub struct z_owned_subscriber_t([u32; 1]); impl_guarded_transmute!(Subscriber, z_owned_subscriber_t); -impl From for z_owned_subscriber_t { - fn from(sub: Subscriber) -> Self { - sub.transmute() - } -} - -impl AsRef for z_owned_subscriber_t { - fn as_ref(&self) -> &Subscriber { - unsafe { std::mem::transmute(self) } - } -} - -impl AsMut for z_owned_subscriber_t { - fn as_mut(&mut self) -> &mut Subscriber { - unsafe { std::mem::transmute(self) } - } -} - impl z_owned_subscriber_t { pub fn new(sub: zenoh::subscriber::Subscriber<'static, ()>) -> Self { Some(Box::new(sub)).into() @@ -125,7 +106,7 @@ pub struct z_subscriber_t(*const z_owned_subscriber_t); impl AsRef for z_subscriber_t { fn as_ref(&self) -> &Subscriber { - unsafe { (*self.0).as_ref() } + unsafe { &(*self.0) } } } @@ -240,7 +221,7 @@ pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_owned_ke #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_subscriber(sub: &mut z_owned_subscriber_t) -> i8 { - if let Some(s) = sub.as_mut().take() { + if let Some(s) = sub.take() { if let Err(e) = s.undeclare().res_sync() { log::warn!("{}", e); return e.errno().get(); From 8dbbf37dc2d8848d23ea0efcc572d656fd586168 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Mon, 26 Feb 2024 15:02:36 +0100 Subject: [PATCH 002/377] privatize sample --- examples/z_get.c | 5 +- examples/z_get_liveliness.c | 2 +- examples/z_non_blocking_get.c | 5 +- examples/z_pong.c | 10 +- examples/z_pull.c | 7 +- examples/z_query_sub.c | 7 +- examples/z_sub.c | 7 +- examples/z_sub_attachment.c | 14 +- examples/z_sub_liveliness.c | 4 +- include/zenoh_commons.h | 163 +++++++++++--------- include/zenoh_macros.h | 3 - src/collections.rs | 54 +++++-- src/commons.rs | 194 ++++++++++-------------- src/get.rs | 2 +- src/lib.rs | 24 +++ src/liveliness.rs | 12 +- src/pull_subscriber.rs | 12 +- src/querying_subscriber.rs | 12 +- src/subscriber.rs | 12 +- tests/z_api_alignment_test.c | 4 +- tests/z_int_pub_cache_query_sub_test.c | 4 +- tests/z_int_pub_sub_attachment_test.c | 9 +- tests/z_int_pub_sub_test.c | 10 +- tests/z_int_queryable_attachment_test.c | 6 +- tests/z_int_queryable_test.c | 4 +- 25 files changed, 311 insertions(+), 275 deletions(-) diff --git a/examples/z_get.c b/examples/z_get.c index 272bef89a..853366210 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -65,8 +65,9 @@ int main(int argc, char **argv) { for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, sample.payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_bytes_t payload = z_sample_payload(&sample); + printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)payload.len, payload.start); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_get_liveliness.c b/examples/z_get_liveliness.c index c667cb03a..9a00f3ca3 100644 --- a/examples/z_get_liveliness.c +++ b/examples/z_get_liveliness.c @@ -53,7 +53,7 @@ int main(int argc, char **argv) { for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); printf(">> Alive token ('%s')\n", z_loan(keystr)); z_drop(z_move(keystr)); } else { diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index c0b02a274..a741d6071 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -58,8 +58,9 @@ int main(int argc, char **argv) { } if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, sample.payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_bytes_t payload = z_sample_payload(&sample); + printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)payload.len, payload.start); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_pong.c b/examples/z_pong.c index 8dbb2631e..4047ff3d2 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -6,7 +6,7 @@ void callback(const z_sample_t* sample, void* context) { z_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); #ifdef ZENOH_C // The zc_owned_payload_t API is exclusive to zenoh-c, but allows avoiding some copies. - zc_owned_payload_t payload = zc_sample_payload_rcinc(sample); + z_owned_buffer_t payload = z_sample_owned_payload(sample); zc_publisher_put_owned(pub, z_move(payload), NULL); #else z_publisher_put(pub, sample->payload.start, sample->payload.len, NULL); @@ -21,15 +21,17 @@ void drop(void* context) { // valid. } struct args_t { - char* config_path; // -c - uint8_t help_requested; // -h + char* config_path; // -c + uint8_t help_requested; // -h }; struct args_t parse_args(int argc, char** argv); int main(int argc, char** argv) { struct args_t args = parse_args(argc, argv); if (args.help_requested) { - printf("-c (optional, string): the path to a configuration file for the session. If this option isn't passed, the default configuration will be used.\n"); + printf( + "-c (optional, string): the path to a configuration file for the session. If this option isn't passed, the " + "default configuration will be used.\n"); return 1; } z_owned_config_t config = args.config_path ? zc_config_from_file(args.config_path) : z_config_default(); diff --git a/examples/z_pull.c b/examples/z_pull.c index d7039e902..badbd6f44 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -23,9 +23,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_bytes_t payload = z_sample_payload(sample); + printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + (int)payload.len, payload.start); z_drop(z_move(keystr)); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index 680cfd973..7653a6c77 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -23,9 +23,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_bytes_t payload = z_sample_payload(sample); + printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + (int)payload.len, payload.start); z_drop(z_move(keystr)); } diff --git a/examples/z_sub.c b/examples/z_sub.c index ccfb32825..b52db8850 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -23,9 +23,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_bytes_t payload = z_sample_payload(sample); + printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + (int)payload.len, payload.start); z_drop(z_move(keystr)); } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 26cc95ed8..c3d22e39f 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -29,17 +29,19 @@ int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { } void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_bytes_t payload = z_sample_payload(sample); + printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + (int)payload.len, payload.start); + z_attachment_t attachment = z_sample_attachment(sample); // checks if attachment exists - if (z_check(sample->attachment)) { + if (z_check(attachment)) { // reads full attachment - z_attachment_iterate(sample->attachment, attachment_reader, NULL); + z_attachment_iterate(attachment, attachment_reader, NULL); // reads particular attachment item - z_bytes_t index = z_attachment_get(sample->attachment, z_bytes_from_str("index")); + z_bytes_t index = z_attachment_get(attachment, z_bytes_from_str("index")); if (z_check(index)) { printf(" message number: %.*s\n", (int)index.len, index.start); } diff --git a/examples/z_sub_liveliness.c b/examples/z_sub_liveliness.c index f67ac5a68..67c87001a 100644 --- a/examples/z_sub_liveliness.c +++ b/examples/z_sub_liveliness.c @@ -21,8 +21,8 @@ #include "zenoh.h" void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - switch (sample->kind) { + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + switch (z_sample_kind(sample)) { case Z_SAMPLE_KIND_PUT: printf(">> [LivelinessSubscriber] New alive token ('%s')\n", z_loan(keystr)); break; diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index c7d46f932..1d56fe95f 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -196,7 +196,7 @@ typedef struct z_owned_buffer_t { size_t _inner[5]; } z_owned_buffer_t; typedef struct z_buffer_t { - size_t _inner; + const void *_inner; } z_buffer_t; /** * A map of maybe-owned vector of bytes to owned vector of bytes. @@ -368,52 +368,6 @@ typedef struct z_owned_closure_reply_t { void (*call)(struct z_owned_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; -/** - * A loaned key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, - * both for local processing and network-wise. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_keyexpr_t { - uint64_t _0[4]; -} z_keyexpr_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_keyexpr_t { - uint32_t _0[5]; -} z_keyexpr_t; -#endif -/** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. - * - * Members: - * z_encoding_prefix_t prefix: The integer prefix of this encoding. - * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. - */ -typedef struct z_encoding_t { - enum z_encoding_prefix_t prefix; - struct z_bytes_t suffix; -} z_encoding_t; -typedef struct z_timestamp_t { - uint64_t time; - struct z_id_t id; -} z_timestamp_t; -/** - * QoS settings of zenoh message. - * - */ -typedef struct z_qos_t { - uint8_t _0; -} z_qos_t; /** * A data sample. * @@ -428,14 +382,7 @@ typedef struct z_qos_t { * z_attachment_t attachment: The attachment of this data sample. */ typedef struct z_sample_t { - struct z_keyexpr_t keyexpr; - struct z_bytes_t payload; - struct z_encoding_t encoding; - const void *_zc_buf; - enum z_sample_kind_t kind; - struct z_timestamp_t timestamp; - struct z_qos_t qos; - struct z_attachment_t attachment; + const void *_inner; } z_sample_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. @@ -550,6 +497,28 @@ typedef struct ALIGN(4) z_owned_keyexpr_t { uint32_t _0[5]; } z_owned_keyexpr_t; #endif +/** + * A loaned key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, + * both for local processing and network-wise. + */ +#if !defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_keyexpr_t { + uint64_t _0[4]; +} z_keyexpr_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_keyexpr_t { + uint32_t _0[5]; +} z_keyexpr_t; +#endif /** * An owned zenoh publisher. * @@ -618,6 +587,19 @@ typedef struct z_delete_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_delete_options_t; +/** + * The encoding of a payload, in a MIME-like format. + * + * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + * + * Members: + * z_encoding_prefix_t prefix: The integer prefix of this encoding. + * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. + */ +typedef struct z_encoding_t { + uint64_t prefix; + struct z_bytes_t suffix; +} z_encoding_t; /** * An owned payload encoding. * @@ -632,7 +614,7 @@ typedef struct z_delete_options_t { * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ typedef struct z_owned_encoding_t { - enum z_encoding_prefix_t prefix; + uint64_t prefix; struct z_bytes_t suffix; bool _dropped; } z_owned_encoding_t; @@ -746,6 +728,13 @@ typedef struct z_put_options_t { enum z_priority_t priority; struct z_attachment_t attachment; } z_put_options_t; +/** + * QoS settings of zenoh message. + * + */ +typedef struct z_qos_t { + uint8_t _0; +} z_qos_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -808,6 +797,10 @@ typedef struct z_owned_reply_channel_t { struct z_owned_closure_reply_t send; struct z_owned_reply_channel_closure_t recv; } z_owned_reply_channel_t; +typedef struct z_timestamp_t { + uint64_t time; + struct z_id_t id; +} z_timestamp_t; typedef struct z_owned_scouting_config_t { struct z_owned_config_t _config; unsigned long zc_timeout_ms; @@ -869,10 +862,7 @@ typedef struct zc_owned_liveliness_get_options_t { * Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` * functions, then the operation will fail (but the passed value will still be consumed). */ -typedef struct zc_owned_payload_t { - struct z_bytes_t payload; - struct z_owned_buffer_t _owner; -} zc_owned_payload_t; +typedef struct z_owned_buffer_t zc_owned_payload_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; } zc_owned_shmbuf_t; @@ -1982,6 +1972,41 @@ ZENOHC_API struct z_owned_reply_t z_reply_null(void); */ ZENOHC_API struct z_sample_t z_reply_ok(const struct z_owned_reply_t *reply); +/** + * The sample's attachment. + * + * `sample` is aliased by the return value. + */ +ZENOHC_API struct z_attachment_t z_sample_attachment(const struct z_sample_t *sample); +/** + * The encoding of the payload. + */ +ZENOHC_API struct z_encoding_t z_sample_encoding(const struct z_sample_t *sample); +/** + * The Key Expression of the sample. + * + * `sample` is aliased by its return value. + */ +ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); +/** + * The sample's kind (put or delete). + */ +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); +/** + * Returns the sample's payload after incrementing its internal reference count. + * + * Note that other samples may have received the same buffer, meaning that mutating this buffer may + * affect the samples received by other subscribers. + */ +ZENOHC_API struct z_owned_buffer_t z_sample_owned_payload(const struct z_sample_t *sample); +/** + * The sample's data, the return value aliases the sample. + * + * If you need ownership of the buffer, you may use `z_sample_owned_payload`. + */ +ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API struct z_qos_t z_sample_qos(const struct z_sample_t *sample); +ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); /** * Scout for routers and/or peers. * @@ -2277,19 +2302,19 @@ ZENOHC_API void zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t /** * Returns `false` if `payload` is the gravestone value. */ -ZENOHC_API bool zc_payload_check(const struct zc_owned_payload_t *payload); +ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); /** * Decrements `payload`'s backing refcount, releasing the memory if appropriate. */ -ZENOHC_API void zc_payload_drop(struct zc_owned_payload_t *payload); +ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); /** * Constructs `zc_owned_payload_t`'s gravestone value. */ -ZENOHC_API struct zc_owned_payload_t zc_payload_null(void); +ZENOHC_API zc_owned_payload_t zc_payload_null(void); /** * Clones the `payload` by incrementing its reference counter. */ -ZENOHC_API struct zc_owned_payload_t zc_payload_rcinc(const struct zc_owned_payload_t *payload); +ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); /** * Sends a `PUT` message onto the publisher's key expression, transfering the buffer ownership. * @@ -2309,7 +2334,7 @@ ZENOHC_API struct zc_owned_payload_t zc_payload_rcinc(const struct zc_owned_payl */ ZENOHC_API int8_t zc_publisher_put_owned(struct z_publisher_t publisher, - struct zc_owned_payload_t *payload, + zc_owned_payload_t *payload, const struct z_publisher_put_options_t *options); /** * Put data, transfering the buffer ownership. @@ -2331,7 +2356,7 @@ int8_t zc_publisher_put_owned(struct z_publisher_t publisher, ZENOHC_API int8_t zc_put_owned(struct z_session_t session, struct z_keyexpr_t keyexpr, - struct zc_owned_payload_t *payload, + zc_owned_payload_t *payload, const struct z_put_options_t *opts); /** * Creates a new blocking fifo channel, returned as a pair of closures. @@ -2385,10 +2410,6 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); */ ZENOHC_API struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); -/** - * Clones the sample's payload by incrementing its backing refcount (this doesn't imply any copies). - */ -ZENOHC_API struct zc_owned_payload_t zc_sample_payload_rcinc(const struct z_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ @@ -2443,7 +2464,7 @@ ZENOHC_API void zc_shmbuf_drop(struct zc_owned_shmbuf_t *buf); /** * Constructs an owned payload from an owned SHM buffer. */ -ZENOHC_API struct zc_owned_payload_t zc_shmbuf_into_payload(struct zc_owned_shmbuf_t *buf); +ZENOHC_API zc_owned_payload_t zc_shmbuf_into_payload(struct zc_owned_shmbuf_t *buf); /** * Returns the length of the SHM buffer. * diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 494d01fb9..dba68f29a 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -44,7 +44,6 @@ z_owned_query_channel_t * : z_query_channel_drop, \ z_owned_bytes_map_t * : z_bytes_map_drop, \ z_owned_buffer_t * : z_buffer_drop, \ - zc_owned_payload_t * : zc_payload_drop, \ zc_owned_shmbuf_t * : zc_shmbuf_drop, \ zc_owned_shm_manager_t * : zc_shm_manager_drop, \ zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ @@ -77,7 +76,6 @@ z_owned_bytes_map_t * : z_bytes_map_null, \ z_owned_buffer_t * : z_buffer_null, \ z_attachment_t * : z_attachment_null, \ - zc_owned_payload_t * : zc_payload_null, \ zc_owned_shmbuf_t * : zc_shmbuf_null, \ zc_owned_shm_manager_t * : zc_shm_manager_null, \ ze_owned_publication_cache_t * : ze_publication_cache_null, \ @@ -103,7 +101,6 @@ z_owned_bytes_map_t : z_bytes_map_check, \ z_owned_buffer_t : z_buffer_check, \ z_attachment_t : z_attachment_check, \ - zc_owned_payload_t : zc_payload_check, \ zc_owned_shmbuf_t : zc_shmbuf_check, \ zc_owned_shm_manager_t : zc_shm_manager_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ diff --git a/src/collections.rs b/src/collections.rs index 9ac7831c0..7f34a8fdd 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -60,7 +60,7 @@ pub extern "C" fn z_bytes_check(b: &z_bytes_t) -> bool { /// Returns the gravestone value for `z_bytes_t` #[no_mangle] -pub extern "C" fn z_bytes_null() -> z_bytes_t { +pub const extern "C" fn z_bytes_null() -> z_bytes_t { z_bytes_t { len: 0, start: core::ptr::null(), @@ -167,11 +167,45 @@ impl From<&[u8]> for z_bytes_t { pub struct z_owned_buffer_t { _inner: [usize; 5], } -impl_guarded_transmute!(Option, z_owned_buffer_t); +impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); +impl Default for z_owned_buffer_t { + fn default() -> Self { + z_buffer_null() + } +} +impl From for z_owned_buffer_t { + fn from(value: ZBuf) -> Self { + let value = match value.contiguous() { + std::borrow::Cow::Borrowed(_) => value, + std::borrow::Cow::Owned(value) => value.into(), + }; + unsafe { core::mem::transmute(Some(value)) } + } +} +impl From> for z_owned_buffer_t { + fn from(value: Option) -> Self { + match value { + Some(value) => value.into(), + None => z_buffer_null(), + } + } +} +impl core::ops::Deref for z_owned_buffer_t { + type Target = Option; + + fn deref(&self) -> &Self::Target { + unsafe { core::mem::transmute(self) } + } +} +impl core::ops::DerefMut for z_owned_buffer_t { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { core::mem::transmute(self) } + } +} #[no_mangle] pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { - None.into() + unsafe { core::mem::transmute(None::) } } #[no_mangle] pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { @@ -189,20 +223,16 @@ pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { #[repr(C)] #[derive(Clone, Copy)] -pub struct z_buffer_t { - _inner: usize, +pub struct z_buffer_t<'a> { + _inner: &'a (), } -impl_guarded_transmute!(noderefs Option<&ZBuf>, z_buffer_t); -impl From for Option<&'static ZBuf> { +impl_guarded_transmute!(Option<&'a ZBuf>, z_buffer_t<'a>, 'a); +impl<'a> From> for Option<&'a ZBuf> { fn from(value: z_buffer_t) -> Self { unsafe { core::mem::transmute(value) } } } -impl From> for z_buffer_t { - fn from(value: Option<&ZBuf>) -> Self { - unsafe { core::mem::transmute(value) } - } -} + #[no_mangle] pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { unsafe { Some(core::mem::transmute::<_, &ZBuf>(buffer).clone()).into() } diff --git a/src/commons.rs b/src/commons.rs index f96b9b09b..6ca6e19b4 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -20,7 +20,6 @@ use crate::z_priority_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; -use zenoh::buffers::ZBuf; use zenoh::prelude::SampleKind; use zenoh::prelude::SplitBuffer; use zenoh::query::ReplyKeyExpr; @@ -101,97 +100,27 @@ impl From> for z_timestamp_t { /// Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` /// functions, then the operation will fail (but the passed value will still be consumed). #[allow(non_camel_case_types)] -#[repr(C)] -pub struct zc_owned_payload_t { - pub payload: z_bytes_t, - pub _owner: z_owned_buffer_t, -} -impl Default for zc_owned_payload_t { - fn default() -> Self { - zc_payload_null() - } -} -impl TryFrom for zc_owned_payload_t { - type Error = (); - fn try_from(buf: ZBuf) -> Result { - let std::borrow::Cow::Borrowed(payload) = buf.contiguous() else { - return Err(()); - }; - Ok(Self { - payload: payload.into(), - _owner: unsafe { std::mem::transmute(buf) }, - }) - } -} -impl zc_owned_payload_t { - pub fn take(&mut self) -> Option { - if !z_bytes_check(&self.payload) { - return None; - } - let start = std::mem::replace(&mut self.payload.start, std::ptr::null()); - let len = std::mem::replace(&mut self.payload.len, 0); - let Some(mut buf) = self._owner.take() else { - return None; - }; - { - let mut slices = buf.zslices_mut(); - let slice = slices.next().unwrap(); - assert!( - slices.next().is_none(), - "A multi-slice buffer reached zenoh-c, which is definitely a bug, please report it." - ); - let start_offset = unsafe { start.offset_from(slice.as_slice().as_ptr()) }; - let Ok(start_offset) = start_offset.try_into() else { - return None; - }; - *slice = match slice.subslice(start_offset, start_offset + len) { - Some(s) => s, - None => return None, - }; - } - Some(buf) - } - fn owner(&self) -> Option<&ZBuf> { - if !z_bytes_check(&self.payload) { - return None; - } - self._owner.as_ref() - } -} -impl Drop for zc_owned_payload_t { - fn drop(&mut self) { - self.take(); - } -} +pub type zc_owned_payload_t = z_owned_buffer_t; /// Clones the `payload` by incrementing its reference counter. #[no_mangle] pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { - match payload.owner() { - None => Default::default(), - Some(payload) => payload.clone().try_into().unwrap_or_default(), - } + z_buffer_clone(z_buffer_loan(payload)) } /// Returns `false` if `payload` is the gravestone value. #[no_mangle] pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { - !payload.payload.start.is_null() + z_buffer_check(payload) } /// Decrements `payload`'s backing refcount, releasing the memory if appropriate. #[no_mangle] pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { - unsafe { std::ptr::replace(payload, zc_payload_null()) }; + z_buffer_drop(payload) } /// Constructs `zc_owned_payload_t`'s gravestone value. #[no_mangle] pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { - zc_owned_payload_t { - payload: z_bytes_t { - len: 0, - start: std::ptr::null(), - }, - _owner: unsafe { core::mem::MaybeUninit::zeroed().assume_init() }, - } + z_buffer_null() } /// QoS settings of zenoh message. @@ -235,50 +164,77 @@ pub extern "C" fn z_qos_default() -> z_qos_t { /// z_attachment_t attachment: The attachment of this data sample. #[repr(C)] pub struct z_sample_t<'a> { - pub keyexpr: z_keyexpr_t, - pub payload: z_bytes_t, - pub encoding: z_encoding_t, - pub _zc_buf: &'a c_void, - pub kind: z_sample_kind_t, - pub timestamp: z_timestamp_t, - pub qos: z_qos_t, - pub attachment: z_attachment_t, + _inner: &'a (), +} +impl<'a> core::ops::Deref for z_sample_t<'a> { + type Target = Sample; + fn deref(&self) -> &Self::Target { + unsafe { core::mem::transmute::<&(), &Sample>(self._inner) } + } } impl<'a> z_sample_t<'a> { - pub fn new(sample: &'a Sample, owner: &'a ZBuf) -> Self { - let std::borrow::Cow::Borrowed(payload) = owner.contiguous() else { + pub fn new(sample: &'a Sample) -> Self { + if !sample.value.payload.zslices().count() <= 1 { panic!("Attempted to construct z_sample_t from discontiguous buffer, this is definitely a bug in zenoh-c, please report it.") }; z_sample_t { - keyexpr: (&sample.key_expr).into(), - payload: z_bytes_t::from(payload), - encoding: (&sample.encoding).into(), - _zc_buf: unsafe { std::mem::transmute(owner) }, - kind: sample.kind.into(), - timestamp: sample.timestamp.as_ref().into(), - qos: sample.qos.into(), - attachment: match &sample.attachment { - Some(attachment) => z_attachment_t { - data: attachment as *const _ as *mut c_void, - iteration_driver: Some(attachment_iteration_driver), - }, - None => z_attachment_null(), - }, + _inner: unsafe { core::mem::transmute(sample) }, } } } -/// Clones the sample's payload by incrementing its backing refcount (this doesn't imply any copies). +/// The Key Expression of the sample. +/// +/// `sample` is aliased by its return value. #[no_mangle] -pub extern "C" fn zc_sample_payload_rcinc(sample: Option<&z_sample_t>) -> zc_owned_payload_t { - let Some(sample) = sample else { - return zc_payload_null(); - }; - let buf = unsafe { std::mem::transmute::<_, &ZBuf>(sample._zc_buf).clone() }; - zc_owned_payload_t { - payload: sample.payload, - _owner: unsafe { std::mem::transmute(buf) }, +pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { + (&sample.key_expr).into() +} +/// The encoding of the payload. +#[no_mangle] +pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { + (&sample.encoding).into() +} +/// The sample's data, the return value aliases the sample. +/// +/// If you need ownership of the buffer, you may use `z_sample_owned_payload`. +#[no_mangle] +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { + sample.payload.slices().next().unwrap_or(b"").into() +} +/// Returns the sample's payload after incrementing its internal reference count. +/// +/// Note that other samples may have received the same buffer, meaning that mutating this buffer may +/// affect the samples received by other subscribers. +#[no_mangle] +pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> z_owned_buffer_t { + sample.payload.clone().into() +} +/// The sample's kind (put or delete). +#[no_mangle] +pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { + sample.kind.into() +} +#[no_mangle] +pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { + sample.timestamp.as_ref().into() +} +#[no_mangle] +pub extern "C" fn z_sample_qos(sample: &z_sample_t) -> z_qos_t { + sample.qos.into() +} +/// The sample's attachment. +/// +/// `sample` is aliased by the return value. +#[no_mangle] +pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { + match &sample.attachment { + Some(attachment) => z_attachment_t { + data: attachment as *const _ as *mut c_void, + iteration_driver: Some(attachment_iteration_driver), + }, + None => z_attachment_null(), } } @@ -425,21 +381,24 @@ impl From for z_encoding_prefix_t { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct z_encoding_t { - pub prefix: z_encoding_prefix_t, + pub prefix: u64, pub suffix: z_bytes_t, } impl From for zenoh_protocol::core::Encoding { fn from(enc: z_encoding_t) -> Self { if enc.suffix.len == 0 { - zenoh_protocol::core::Encoding::Exact(enc.prefix.into()) + zenoh_protocol::core::Encoding::Exact((enc.prefix as u8).try_into().unwrap()) } else { let suffix = unsafe { let slice: &'static [u8] = std::slice::from_raw_parts(enc.suffix.start, enc.suffix.len); std::str::from_utf8_unchecked(slice) }; - zenoh_protocol::core::Encoding::WithSuffix(enc.prefix.into(), suffix.into()) + zenoh_protocol::core::Encoding::WithSuffix( + (enc.prefix as u8).try_into().unwrap(), + suffix.into(), + ) } } } @@ -448,7 +407,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { fn from(val: &zenoh_protocol::core::Encoding) -> Self { let suffix = val.suffix(); z_encoding_t { - prefix: (*val.prefix()).into(), + prefix: u8::from(*val.prefix()) as u64, suffix: z_bytes_t { start: suffix.as_ptr(), len: suffix.len(), @@ -470,7 +429,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. #[repr(C)] pub struct z_owned_encoding_t { - pub prefix: z_encoding_prefix_t, + pub prefix: u64, pub suffix: z_bytes_t, pub _dropped: bool, } @@ -478,7 +437,7 @@ pub struct z_owned_encoding_t { impl z_owned_encoding_t { pub fn null() -> Self { z_owned_encoding_t { - prefix: z_encoding_prefix_t::Empty, + prefix: 0, suffix: z_bytes_t::default(), _dropped: true, } @@ -506,7 +465,10 @@ pub unsafe extern "C" fn z_encoding( len: libc::strlen(suffix), } }; - z_encoding_t { prefix, suffix } + z_encoding_t { + prefix: prefix as u64, + suffix, + } } /// Constructs a default :c:type:`z_encoding_t`. diff --git a/src/get.rs b/src/get.rs index 41e3cf204..423810a4f 100644 --- a/src/get.rs +++ b/src/get.rs @@ -108,7 +108,7 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { if let Cow::Owned(_) = sample.payload.contiguous() { unreachable!("z_reply_ok found a payload that wasn't contiguous by the time it was reached, which breaks some crate assertions. This is definitely a bug with zenoh, please contact us.") } - z_sample_t::new(sample, &sample.payload) + z_sample_t::new(sample) } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Ok despite that not being the case") } diff --git a/src/lib.rs b/src/lib.rs index 19c22fa2e..9c01e4aa2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,6 +103,30 @@ macro_rules! impl_guarded_transmute { } } }; + ($src_type:ty, $dst_type:ty, $($gen: tt)*) => { + impl<$($gen)*> $crate::GuardedTransmute<$dst_type> for $src_type { + fn transmute(self) -> $dst_type { + unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } + } + } + impl<$($gen)*> From<$src_type> for $dst_type { + fn from(value: $src_type) -> $dst_type { + unsafe { core::mem::transmute(value) } + } + } + impl<$($gen)*> core::ops::Deref for $dst_type { + type Target = $src_type; + fn deref(&self) -> &$src_type { + unsafe { core::mem::transmute(self) } + } + } + impl<$($gen)*> core::ops::DerefMut for $dst_type { + fn deref_mut(&mut self) -> &mut $src_type { + unsafe { core::mem::transmute(self) } + } + } + + }; } pub(crate) const LOG_INVALID_SESSION: &str = "Invalid session"; diff --git a/src/liveliness.rs b/src/liveliness.rs index 040205892..69ee2d2e2 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -176,13 +176,11 @@ pub extern "C" fn zc_liveliness_declare_subscriber( match session .liveliness() .declare_subscriber(key) - .callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + .callback(move |mut sample| { + if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { + sample.payload = v.into(); + } + let sample = z_sample_t::new(&sample); z_closure_sample_call(&callback, &sample) }) .res() diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index 0eee4bc94..247484cb1 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -149,13 +149,11 @@ pub extern "C" fn z_declare_pull_subscriber( Some(s) => { let mut res = s .declare_subscriber(keyexpr) - .callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + .callback(move |mut sample| { + if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { + sample.payload = v.into(); + } + let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) .pull_mode(); diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index cdec44f0f..a4681b4e9 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -185,13 +185,11 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( } } match sub - .callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + .callback(move |mut sample| { + if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { + sample.payload = v.into(); + } + let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) .res() diff --git a/src/subscriber.rs b/src/subscriber.rs index b9488960a..7d15e740a 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -179,13 +179,11 @@ pub extern "C" fn z_declare_subscriber( match session.upgrade() { Some(s) => { - let mut res = s.declare_subscriber(keyexpr).callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + let mut res = s.declare_subscriber(keyexpr).callback(move |mut sample| { + if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { + sample.payload = v.into(); + } + let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }); if let Some(opts) = opts { diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index ee63017c2..8dcff3317 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -76,7 +76,7 @@ void reply_handler(z_owned_reply_t *reply, void *arg) { if (z_reply_is_ok(reply)) { z_sample_t sample = z_reply_ok(reply); - z_owned_str_t k_str = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample.keyexpr); @@ -95,7 +95,7 @@ volatile unsigned int datas = 0; void data_handler(const z_sample_t *sample, void *arg) { datas++; - z_owned_str_t k_str = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(sample)); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample->keyexpr); diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 6674aec55..7495939f2 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -85,14 +85,14 @@ int run_publisher() { void data_handler(const z_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - ASSERT_STR_BYTES_EQUAL(values[val_num], sample->payload); + ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(sample)); printf("data_handler: %i\n", val_num); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index 75ae88547..554d1fd57 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -66,22 +66,23 @@ int run_publisher() { void data_handler(const z_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - if (strncmp(values[val_num], (const char *)sample->payload.start, (int)sample->payload.len)) { + z_bytes_t payload = z_sample_payload(sample); + if (strncmp(values[val_num], (const char *)payload.start, (int)payload.len)) { perror("Unexpected value received"); exit(-1); } - z_bytes_t v_const = z_attachment_get(sample->attachment, z_bytes_from_str(K_CONST)); + z_bytes_t v_const = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_bytes_t v_var = z_attachment_get(sample->attachment, z_bytes_from_str(K_VAR)); + z_bytes_t v_var = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[val_num], v_var); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index cf005a80f..6e48fef5a 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -59,21 +59,21 @@ int run_publisher() { void data_handler(const z_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - if (strncmp(values[val_num], (const char *)sample->payload.start, (int)sample->payload.len)) { + z_bytes_t payload = z_sample_payload(sample); + if (strncmp(values[val_num], (const char *)payload.start, (int)payload.len)) { perror("Unexpected value received"); exit(-1); } - if (z_qos_get_congestion_control(sample->qos) != Z_CONGESTION_CONTROL_BLOCK - || z_qos_get_priority(sample->qos) != Z_PRIORITY_DATA - ) { + if (z_qos_get_congestion_control(z_sample_qos(sample)) != Z_CONGESTION_CONTROL_BLOCK || + z_qos_get_priority(z_sample_qos(sample)) != Z_PRIORITY_DATA) { perror("Unexpected QoS values"); exit(-1); } diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index b2f2a7ab8..836f8d988 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -109,11 +109,11 @@ int run_get() { assert(z_reply_is_ok(&reply)); z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - ASSERT_STR_BYTES_EQUAL(values[val_num], sample.payload); + ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(&sample)); - z_bytes_t v_const = z_attachment_get(sample.attachment, z_bytes_from_str(K_CONST)); + z_bytes_t v_const = z_attachment_get(z_sample_attachment(&sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 4244af2c7..67c690f8e 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -85,9 +85,9 @@ int run_get() { assert(z_reply_is_ok(&reply)); z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - ASSERT_STR_BYTES_EQUAL(values[val_num], sample.payload); + ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(&sample)); z_drop(z_move(keystr)); } From 3551d3843f2980556e9edc54db17cf4b3fa03013 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Thu, 29 Feb 2024 11:40:39 +0100 Subject: [PATCH 003/377] add support for owned samples --- Cargo.toml | 2 +- include/zenoh_commons.h | 34 ++++++++++++++++++++++++++++++++ src/commons.rs | 43 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 52deaa71c..638c6422d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ serde_yaml = "0.9.19" [lib] path="src/lib.rs" -name = "zenohc" +name = "zenohcd" crate-type = ["cdylib", "staticlib"] doctest = false diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 1d56fe95f..3fa477cd3 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -863,6 +863,12 @@ typedef struct zc_owned_liveliness_get_options_t { * functions, then the operation will fail (but the passed value will still be consumed). */ typedef struct z_owned_buffer_t zc_owned_payload_t; +typedef struct zc_owned_sample_t { + struct z_owned_keyexpr_t _0; + struct z_owned_buffer_t _1; + struct z_owned_buffer_t _2; + size_t _3[12]; +} zc_owned_sample_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; } zc_owned_shmbuf_t; @@ -2005,7 +2011,13 @@ ZENOHC_API struct z_owned_buffer_t z_sample_owned_payload(const struct z_sample_ * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +/** + * The qos with which the sample was received. + */ ZENOHC_API struct z_qos_t z_sample_qos(const struct z_sample_t *sample); +/** + * The samples timestamp + */ ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); /** * Scout for routers and/or peers. @@ -2410,6 +2422,28 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); */ ZENOHC_API struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); +/** + * Returns `true` if `sample` is valid. + * + * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * unless the value has been dropped already. + */ +ZENOHC_API +bool zc_sample_check(const struct zc_owned_sample_t *sample); +/** + * Clone a sample in the cheapest way available. + */ +ZENOHC_API struct zc_owned_sample_t zc_sample_clone(const struct z_sample_t *sample); +/** + * Destroy the sample. + */ +ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); +/** + * Borrow the sample, allowing calling its accessor methods. + * + * Calling this function using a dropped sample is undefined behaviour. + */ +ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ diff --git a/src/commons.rs b/src/commons.rs index 6ca6e19b4..085a0df5a 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -12,6 +12,8 @@ // ZettaScale Zenoh team, // +use std::ops::Deref; + use crate::collections::*; use crate::keyexpr::*; use crate::z_congestion_control_t; @@ -216,10 +218,12 @@ pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> z_owned_buffer_ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { sample.kind.into() } +/// The samples timestamp #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { sample.timestamp.as_ref().into() } +/// The qos with which the sample was received. #[no_mangle] pub extern "C" fn z_sample_qos(sample: &z_sample_t) -> z_qos_t { sample.qos.into() @@ -238,6 +242,45 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } } +#[repr(C)] +pub struct zc_owned_sample_t { + _0: z_owned_keyexpr_t, + _1: z_owned_buffer_t, + _2: z_owned_buffer_t, + _3: [usize; 12], +} + +impl_guarded_transmute!(Option, zc_owned_sample_t); + +/// Clone a sample in the cheapest way available. +#[no_mangle] +pub extern "C" fn zc_sample_clone(sample: &z_sample_t) -> zc_owned_sample_t { + Some(sample.deref().clone()).into() +} + +/// Returns `true` if `sample` is valid. +/// +/// Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed +/// unless the value has been dropped already. +#[no_mangle] +pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { + sample.is_some() +} + +/// Borrow the sample, allowing calling its accessor methods. +/// +/// Calling this function using a dropped sample is undefined behaviour. +#[no_mangle] +pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> z_sample_t { + z_sample_t::new(unsafe { sample.as_ref().unwrap_unchecked() }) +} + +/// Destroy the sample. +#[no_mangle] +pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { + core::mem::drop(sample.take()); +} + /// A :c:type:`z_encoding_t` integer `prefix`. /// /// - **Z_ENCODING_PREFIX_EMPTY** From 7148d5b57ab81907621c1c4c0202735fb36c12b5 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Thu, 29 Feb 2024 14:18:57 +0100 Subject: [PATCH 004/377] document the owned sample type itself --- include/zenoh_commons.h | 6 ++++++ src/commons.rs | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 3fa477cd3..53c80c75c 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -863,6 +863,12 @@ typedef struct zc_owned_liveliness_get_options_t { * functions, then the operation will fail (but the passed value will still be consumed). */ typedef struct z_owned_buffer_t zc_owned_payload_t; +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ typedef struct zc_owned_sample_t { struct z_owned_keyexpr_t _0; struct z_owned_buffer_t _1; diff --git a/src/commons.rs b/src/commons.rs index 085a0df5a..555a380be 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -242,6 +242,10 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } } +/// An owned sample. +/// +/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. #[repr(C)] pub struct zc_owned_sample_t { _0: z_owned_keyexpr_t, From 9c9f1ac5ad6eaa0b9939e70d473031fa210afe63 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Thu, 29 Feb 2024 14:53:08 +0100 Subject: [PATCH 005/377] fix macro usages --- src/platform/synchronization.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index dbd9d94b8..a16664352 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -22,8 +22,8 @@ pub struct ZMutexPtr { #[derive(Clone, Copy)] pub struct z_mutex_t(usize); -impl_guarded_transmute!(z_mutex_t, ZMutexPtr); -impl_guarded_transmute!(ZMutexPtr, z_mutex_t); +impl_guarded_transmute!(noderefs z_mutex_t, ZMutexPtr); +impl_guarded_transmute!(noderefs ZMutexPtr, z_mutex_t); // using the same error codes as in GNU pthreads, but with negative sign // due to convention to return negative values on error @@ -141,8 +141,8 @@ struct ZCondvarPtr { #[derive(Clone, Copy)] pub struct z_condvar_t(usize); -impl_guarded_transmute!(z_condvar_t, ZCondvarPtr); -impl_guarded_transmute!(ZCondvarPtr, z_condvar_t); +impl_guarded_transmute!(noderefs z_condvar_t, ZCondvarPtr); +impl_guarded_transmute!(noderefs ZCondvarPtr, z_condvar_t); #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -233,8 +233,8 @@ pub struct z_task_t(usize); #[derive(Clone, Copy)] pub struct z_task_attr_t(usize); -impl_guarded_transmute!(z_task_t, ZTaskPtr); -impl_guarded_transmute!(ZTaskPtr, z_task_t); +impl_guarded_transmute!(noderefs z_task_t, ZTaskPtr); +impl_guarded_transmute!(noderefs ZTaskPtr, z_task_t); struct FunArgPair { fun: unsafe extern "C" fn(arg: *mut c_void), From 3eb72362b564c04734d46c2bc05227a80e55f2d7 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Fri, 1 Mar 2024 16:07:56 +0100 Subject: [PATCH 006/377] fix auto-generated zenohcd --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 638c6422d..52deaa71c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ serde_yaml = "0.9.19" [lib] path="src/lib.rs" -name = "zenohcd" +name = "zenohc" crate-type = ["cdylib", "staticlib"] doctest = false From 769d824adf227f013f2f6f1f0b666f152a5aeeb4 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Tue, 5 Mar 2024 17:09:53 +0100 Subject: [PATCH 007/377] introduce split buffers in zenoh-c --- include/zenoh_commons.h | 55 +++++++++++++++++++++++++++++++++- src/collections.rs | 66 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 115 insertions(+), 6 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 53c80c75c..5e3af4644 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -190,11 +190,22 @@ typedef struct z_attachment_t { z_attachment_iter_driver_t iteration_driver; } z_attachment_t; /** - * A buffer owned by Zenoh. + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + * + * You can use `z_buffer_contiguous` to obtain a contiguous version of a buffer. + * If the buffer was already contiguous, the reference count will simply be increased. + * Otherwise, the split buffer's entire content will be copied in a newly allocated buffer. */ typedef struct z_owned_buffer_t { size_t _inner[5]; } z_owned_buffer_t; +/** + * A loan of a `z_owned_buffer_t`. + * + * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. + */ typedef struct z_buffer_t { const void *_inner; } z_buffer_t; @@ -1038,12 +1049,54 @@ int8_t z_attachment_iterate(struct z_attachment_t this_, * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); +/** + * Returns `true` if the buffer is in a valid state. + */ ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); +/** + * Increments the buffer's reference count, returning an owned version of the buffer. + */ ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); +/** + * Returns an owned version of this buffer whose data is guaranteed to be contiguous in memory. + * + * This is achieved by increasing the reference count if the buffer is already contiguous, and by copying its data in a new contiguous buffer if it wasn't. + */ +ZENOHC_API +struct z_owned_buffer_t z_buffer_contiguous(struct z_buffer_t buffer); +/** + * Decrements the buffer's reference counter, destroying it if applicable. + * + * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +/** + * Loans the buffer, allowing you to call functions that only need a loan of it. + */ ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); +/** + * The gravestone value for `z_owned_buffer_t`. + */ ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); +/** + * Returns the payload of the buffer if it is contiguous, aliasling it. + * + * If the payload was not contiguous in memory, `z_bytes_null` will be returned instead. + */ ZENOHC_API struct z_bytes_t z_buffer_payload(struct z_buffer_t buffer); +/** + * Returns the `index`th slice of the buffer, aliasing it. + * + * Out of bounds accesses will return `z_bytes_null`. + */ +ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); +/** + * Returns the number of slices in the buffer. + * + * If the return value is 0 or 1, then the buffer's data is contiguous in memory and `z_buffer_contiguous` will succeed. + */ +ZENOHC_API +size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ diff --git a/src/collections.rs b/src/collections.rs index 7f34a8fdd..89c0e0438 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -162,7 +162,13 @@ impl From<&[u8]> for z_bytes_t { } } -/// A buffer owned by Zenoh. +/// A split buffer that owns all of its data. +/// +/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. +/// +/// You can use `z_buffer_contiguous` to obtain a contiguous version of a buffer. +/// If the buffer was already contiguous, the reference count will simply be increased. +/// Otherwise, the split buffer's entire content will be copied in a newly allocated buffer. #[repr(C)] pub struct z_owned_buffer_t { _inner: [usize; 5], @@ -203,24 +209,35 @@ impl core::ops::DerefMut for z_owned_buffer_t { } } +/// The gravestone value for `z_owned_buffer_t`. #[no_mangle] pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { unsafe { core::mem::transmute(None::) } } + +/// Decrements the buffer's reference counter, destroying it if applicable. +/// +/// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. #[no_mangle] pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { core::mem::drop(buffer.take()) } +/// Returns `true` if the buffer is in a valid state. #[no_mangle] pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { buffer.is_some() } + +/// Loans the buffer, allowing you to call functions that only need a loan of it. #[no_mangle] pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { buffer.as_ref().into() } +/// A loan of a `z_owned_buffer_t`. +/// +/// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. #[repr(C)] #[derive(Clone, Copy)] pub struct z_buffer_t<'a> { @@ -233,11 +250,15 @@ impl<'a> From> for Option<&'a ZBuf> { } } +/// Increments the buffer's reference count, returning an owned version of the buffer. #[no_mangle] pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { unsafe { Some(core::mem::transmute::<_, &ZBuf>(buffer).clone()).into() } } +/// Returns the payload of the buffer if it is contiguous, aliasling it. +/// +/// If the payload was not contiguous in memory, `z_bytes_null` will be returned instead. #[no_mangle] pub extern "C" fn z_buffer_payload(buffer: z_buffer_t) -> z_bytes_t { let Some(buffer): Option<&ZBuf> = buffer.into() else { @@ -245,9 +266,44 @@ pub extern "C" fn z_buffer_payload(buffer: z_buffer_t) -> z_bytes_t { }; match buffer.contiguous() { std::borrow::Cow::Borrowed(buffer) => buffer.into(), - std::borrow::Cow::Owned(_) => { - log::error!("A non-contiguous buffer reached user code, this is definitely a bug, please inform us at https://github.com/eclipse-zenoh/zenoh-c/issues/new"); - z_bytes_null() - } + std::borrow::Cow::Owned(_) => z_bytes_null(), + } +} + +/// Returns an owned version of this buffer whose data is guaranteed to be contiguous in memory. +/// +/// This is achieved by increasing the reference count if the buffer is already contiguous, and by copying its data in a new contiguous buffer if it wasn't. +#[no_mangle] +pub extern "C" fn z_buffer_contiguous(buffer: z_buffer_t) -> z_owned_buffer_t { + let Some(buf): Option<&ZBuf> = buffer.into() else { + return z_buffer_null(); + }; + match buf.contiguous() { + std::borrow::Cow::Borrowed(_) => buf.clone().into(), + std::borrow::Cow::Owned(buf) => ZBuf::from(buf).into(), + } +} + +/// Returns the number of slices in the buffer. +/// +/// If the return value is 0 or 1, then the buffer's data is contiguous in memory and `z_buffer_contiguous` will succeed. +#[no_mangle] +pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).len(), + } +} + +/// Returns the `index`th slice of the buffer, aliasing it. +/// +/// Out of bounds accesses will return `z_bytes_null`. +#[no_mangle] +pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { + match buffer.into() { + None => z_bytes_null(), + Some(buf) => ZBuf::slices(buf) + .nth(index) + .map_or(z_bytes_null(), |slice| slice.into()), } } From 1b09b308accafcbb4c9e54675bf6e878072d18de Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Fri, 8 Mar 2024 11:16:02 +0100 Subject: [PATCH 008/377] address pr comments --- include/zenoh_commons.h | 9 +-------- src/commons.rs | 16 +++++----------- src/lib.rs | 8 ++++++++ 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 5e3af4644..e0b405014 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -383,14 +383,6 @@ typedef struct z_owned_closure_reply_t { * A data sample. * * A sample is the value associated to a given resource at a given point in time. - * - * Members: - * z_keyexpr_t keyexpr: The resource key of this data sample. - * z_bytes_t payload: The value of this data sample. - * z_encoding_t encoding: The encoding of the value of this data sample. - * z_sample_kind_t kind: The kind of this data sample (PUT or DELETE). - * z_timestamp_t timestamp: The timestamp of this data sample. - * z_attachment_t attachment: The attachment of this data sample. */ typedef struct z_sample_t { const void *_inner; @@ -2503,6 +2495,7 @@ ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); * Calling this function using a dropped sample is undefined behaviour. */ ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); +ZENOHC_API struct zc_owned_sample_t zc_sample_null(void); /** * Increments the session's reference count, returning a new owning handle. */ diff --git a/src/commons.rs b/src/commons.rs index 555a380be..d23618846 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -156,14 +156,6 @@ pub extern "C" fn z_qos_default() -> z_qos_t { /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. -/// -/// Members: -/// z_keyexpr_t keyexpr: The resource key of this data sample. -/// z_bytes_t payload: The value of this data sample. -/// z_encoding_t encoding: The encoding of the value of this data sample. -/// z_sample_kind_t kind: The kind of this data sample (PUT or DELETE). -/// z_timestamp_t timestamp: The timestamp of this data sample. -/// z_attachment_t attachment: The attachment of this data sample. #[repr(C)] pub struct z_sample_t<'a> { _inner: &'a (), @@ -177,9 +169,6 @@ impl<'a> core::ops::Deref for z_sample_t<'a> { impl<'a> z_sample_t<'a> { pub fn new(sample: &'a Sample) -> Self { - if !sample.value.payload.zslices().count() <= 1 { - panic!("Attempted to construct z_sample_t from discontiguous buffer, this is definitely a bug in zenoh-c, please report it.") - }; z_sample_t { _inner: unsafe { core::mem::transmute(sample) }, } @@ -285,6 +274,11 @@ pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { core::mem::drop(sample.take()); } +#[no_mangle] +pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { + None.into() +} + /// A :c:type:`z_encoding_t` integer `prefix`. /// /// - **Z_ENCODING_PREFIX_EMPTY** diff --git a/src/lib.rs b/src/lib.rs index 9c01e4aa2..2ff9259c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,6 +58,14 @@ trait GuardedTransmute { fn transmute(self) -> D; } +/// For internal use only. +/// +/// This macro is used to establish the equivalence between a Rust type (first parameter) and a C layout (second parameter). +/// +/// It automatically implements `From`, `Deref` and `DerefMut` to make writing code around these equivalent types. +/// +/// Because carrying around the proper semantics of lifetimes is hard, this macro fails to produce working code when lifetimes are +/// present in either parameter. You may then call it with the `noderefs` prefix to avoid the offending implementations being defined. #[macro_export] macro_rules! impl_guarded_transmute { ($src_type:ty, $dst_type:ty) => { From 4d1816b6b0ee1ae1a290a6d11131afa9993ae90c Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 28 Mar 2024 12:25:27 +0100 Subject: [PATCH 009/377] merge --- Cargo.lock | 548 ++++++++++++------------ Cargo.toml | 2 + Cargo.toml.in | 2 + docs/api.rst | 8 +- docs/requirements.txt | 8 +- examples/z_liveliness.c | 8 +- examples/z_ping.c | 19 +- examples/z_pub.c | 12 +- examples/z_pub_attachment.c | 8 +- examples/z_pub_cache.c | 8 +- examples/z_pub_shm.c | 8 +- examples/z_pull.c | 8 +- examples/z_query_sub.c | 8 +- examples/z_queryable.c | 8 +- examples/z_queryable_with_channels.c | 6 - examples/z_scout.c | 20 +- examples/z_sub.c | 8 +- examples/z_sub_attachment.c | 8 +- examples/z_sub_liveliness.c | 8 +- examples/z_sub_thr.c | 25 +- include/zenoh_commons.h | 132 +++++- src/attachment.rs | 66 +++ src/get.rs | 6 +- src/keyexpr.rs | 97 +++++ src/lib.rs | 27 ++ src/liveliness.rs | 22 +- src/platform/clock.rs | 127 ++++++ src/platform/mod.rs | 9 +- src/platform/random.rs | 34 ++ src/platform/sleep.rs | 19 + src/scouting.rs | 31 +- tests/z_api_alignment_test.c | 48 +-- tests/z_api_attachment_test.c | 14 + tests/z_api_keyexpr_test.c | 30 ++ tests/z_int_pub_cache_query_sub_test.c | 2 +- tests/z_int_pub_sub_attachment_test.c | 2 +- tests/z_int_queryable_attachment_test.c | 2 +- tests/z_int_queryable_test.c | 2 +- 38 files changed, 922 insertions(+), 478 deletions(-) create mode 100644 src/platform/clock.rs create mode 100644 src/platform/random.rs create mode 100644 src/platform/sleep.rs diff --git a/Cargo.lock b/Cargo.lock index 6d2575fae..1c62eb1df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,11 +55,26 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" dependencies = [ "anstyle", "anstyle-parse", @@ -71,9 +86,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -115,16 +130,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "async-channel" version = "1.9.0" @@ -213,23 +218,12 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "async-rustls" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29479d362e242e320fa8f5c831940a5b83c1679af014068196cd20d4bf497b6b" -dependencies = [ - "futures-io", - "rustls", -] - [[package]] name = "async-std" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ - "async-attributes", "async-channel", "async-global-executor", "async-io", @@ -393,7 +387,7 @@ version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d" dependencies = [ - "clap 3.2.25", + "clap", "heck", "indexmap 1.9.3", "log", @@ -421,6 +415,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.0", +] + [[package]] name = "cipher" version = "0.4.4" @@ -439,47 +447,13 @@ checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", "bitflags 1.3.2", - "clap_lex 0.2.4", + "clap_lex", "indexmap 1.9.3", "strsim", "termcolor", "textwrap", ] -[[package]] -name = "clap" -version = "4.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" -dependencies = [ - "anstream", - "anstyle", - "clap_lex 0.6.0", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.33", -] - [[package]] name = "clap_lex" version = "0.2.4" @@ -489,12 +463,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - [[package]] name = "colorchoice" version = "1.0.0" @@ -636,11 +604,21 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -649,6 +627,19 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -657,23 +648,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -704,9 +684,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "fixedbitset" @@ -906,12 +886,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - [[package]] name = "gloo-timers" version = "0.2.6" @@ -970,12 +944,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - [[package]] name = "hmac" version = "0.12.1" @@ -996,9 +964,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" dependencies = [ "bytes", "fnv", @@ -1017,6 +985,29 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows 0.48.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.4.0" @@ -1092,7 +1083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", - "rustix 0.38.21", + "rustix 0.38.32", "windows-sys 0.48.0", ] @@ -1160,9 +1151,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.148" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" @@ -1246,9 +1237,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi", @@ -1509,20 +1500,6 @@ dependencies = [ "spki", ] -[[package]] -name = "pnet" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "130c5b738eeda2dc5796fe2671e49027e6935e817ab51b930a36ec9e6a206a64" -dependencies = [ - "ipnetwork", - "pnet_base", - "pnet_datalink", - "pnet_packet", - "pnet_sys", - "pnet_transport", -] - [[package]] name = "pnet_base" version = "0.34.0" @@ -1545,39 +1522,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "pnet_macros" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688b17499eee04a0408aca0aa5cba5fc86401d7216de8a63fdf7a4c227871804" -dependencies = [ - "proc-macro2", - "quote", - "regex", - "syn 2.0.33", -] - -[[package]] -name = "pnet_macros_support" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea925b72f4bd37f8eab0f221bbe4c78b63498350c983ffa9dd4bcde7e030f56" -dependencies = [ - "pnet_base", -] - -[[package]] -name = "pnet_packet" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a005825396b7fe7a38a8e288dbc342d5034dac80c15212436424fef8ea90ba" -dependencies = [ - "glob", - "pnet_base", - "pnet_macros", - "pnet_macros_support", -] - [[package]] name = "pnet_sys" version = "0.34.0" @@ -1588,18 +1532,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "pnet_transport" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2637e14d7de974ee2f74393afccbc8704f3e54e6eb31488715e72481d1662cc3" -dependencies = [ - "libc", - "pnet_base", - "pnet_packet", - "pnet_sys", -] - [[package]] name = "polling" version = "2.8.0" @@ -1648,7 +1580,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls", + "rustls 0.21.7", "thiserror", "tokio", "tracing", @@ -1664,7 +1596,7 @@ dependencies = [ "rand", "ring 0.16.20", "rustc-hash", - "rustls", + "rustls 0.21.7", "rustls-native-certs 0.6.3", "slab", "thiserror", @@ -1680,7 +1612,7 @@ checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ "bytes", "libc", - "socket2 0.5.4", + "socket2 0.5.6", "tracing", "windows-sys 0.48.0", ] @@ -1733,15 +1665,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_users" version = "0.4.3" @@ -1749,7 +1672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "redox_syscall", "thiserror", ] @@ -1880,15 +1803,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys 0.4.13", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1903,6 +1826,20 @@ dependencies = [ "sct", ] +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring 0.17.6", + "rustls-pki-types", + "rustls-webpki 0.102.2", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -1949,9 +1886,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.0.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb0a1f9b9efec70d32e6d6aa3e58ebd88c3754ec98dfe9145c63cf54cc829b83" +checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" [[package]] name = "rustls-webpki" @@ -1965,9 +1902,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.0" +version = "0.102.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de2635c8bc2b88d367767c5de8ea1d8db9af3f6219eba28442242d9ab81d1b89" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" dependencies = [ "ring 0.17.6", "rustls-pki-types", @@ -2233,12 +2170,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2320,22 +2257,21 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.1", - "redox_syscall 0.4.1", - "rustix 0.38.21", - "windows-sys 0.48.0", + "fastrand 2.0.2", + "rustix 0.38.32", + "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -2392,9 +2328,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.32.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -2402,27 +2338,48 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "socket2 0.5.4", + "socket2 0.5.6", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", "syn 2.0.33", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.7", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.2", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-tungstenite" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", @@ -2430,6 +2387,21 @@ dependencies = [ "tungstenite", ] +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "futures-util", + "hashbrown 0.14.0", + "pin-project-lite", + "tokio", +] + [[package]] name = "toml" version = "0.5.11" @@ -2474,9 +2446,9 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes", @@ -2515,9 +2487,9 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "uhlc" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1eadef1fa26cbbae1276c46781e8f4d888bdda434779c18ae6c2a0e69991885" +checksum = "99b6df3f3e948b40e20c38a6d1fd6d8f91b3573922fc164e068ad3331560487e" dependencies = [ "humantime", "lazy_static", @@ -2760,7 +2732,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b7b128a98c1cfa201b09eb49ba285887deb3cbe7466a98850eb1adabb452be5" dependencies = [ - "windows", + "windows 0.34.0", ] [[package]] @@ -2807,6 +2779,15 @@ dependencies = [ "windows_x86_64_msvc 0.34.0", ] +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -2972,20 +2953,17 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-global-executor", - "async-std", "async-trait", "base64", "const_format", - "env_logger", + "env_logger 0.11.2", "event-listener 4.0.0", "flume", "form_urlencoded", "futures", "git-version", - "hex", "lazy_static", "log", "ordered-float", @@ -2996,8 +2974,10 @@ dependencies = [ "rustc_version", "serde", "serde_json", - "socket2 0.5.4", + "socket2 0.5.6", "stop-token", + "tokio", + "tokio-util", "uhlc", "uuid", "vec_map", @@ -3013,6 +2993,7 @@ dependencies = [ "zenoh-plugin-trait", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-shm", "zenoh-sync", "zenoh-transport", @@ -3022,7 +3003,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "zenoh-collections", ] @@ -3034,10 +3015,12 @@ dependencies = [ "async-std", "async-trait", "cbindgen", - "env_logger", + "chrono", + "env_logger 0.10.2", "fs2", "futures", "json5", + "lazy_static", "libc", "log", "rand", @@ -3052,7 +3035,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "log", "serde", @@ -3065,15 +3048,16 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "flume", "json5", + "log", "num_cpus", "secrecy", "serde", @@ -3089,17 +3073,19 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", + "async-global-executor", "lazy_static", + "tokio", "zenoh-result", + "zenoh-runtime", ] [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "aes", "hmac", @@ -3112,19 +3098,20 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "bincode", - "env_logger", + "env_logger 0.11.2", "flume", "futures", "log", "serde", + "tokio", "zenoh", "zenoh-core", "zenoh-macros", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3132,7 +3119,7 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3146,9 +3133,8 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "zenoh-config", "zenoh-link-commons", @@ -3165,46 +3151,50 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "flume", + "futures", "log", - "lz4_flex", + "rustls 0.22.2", + "rustls-webpki 0.102.2", "serde", - "typenum", + "tokio", + "tokio-util", "zenoh-buffers", "zenoh-codec", "zenoh-core", "zenoh-protocol", "zenoh-result", - "zenoh-sync", + "zenoh-runtime", "zenoh-util", ] [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-rustls", - "async-std", "async-trait", "base64", "futures", "log", "quinn", - "rustls", + "rustls 0.21.7", "rustls-native-certs 0.7.0", "rustls-pemfile 2.0.0", - "rustls-webpki 0.102.0", + "rustls-webpki 0.102.2", "secrecy", + "tokio", + "tokio-rustls 0.24.1", + "tokio-util", "zenoh-config", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3212,15 +3202,17 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "log", + "tokio", + "tokio-util", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3228,24 +3220,27 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-rustls", - "async-std", "async-trait", "base64", "futures", "log", - "rustls", + "rustls 0.22.2", "rustls-pemfile 2.0.0", - "rustls-webpki 0.102.0", + "rustls-pki-types", + "rustls-webpki 0.102.2", "secrecy", + "tokio", + "tokio-rustls 0.25.0", + "tokio-util", "webpki-roots", "zenoh-config", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3253,18 +3248,20 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "log", - "socket2 0.5.4", + "socket2 0.5.6", + "tokio", + "tokio-util", "zenoh-buffers", "zenoh-collections", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3272,37 +3269,40 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "futures", "log", "nix 0.27.1", + "tokio", + "tokio-util", "uuid", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", ] [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "futures-util", "log", "tokio", "tokio-tungstenite", + "tokio-util", "url", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3310,20 +3310,18 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "proc-macro2", "quote", - "rustc_version", "syn 2.0.33", - "unzip-n", "zenoh-keyexpr", ] [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "const_format", "libloading", @@ -3339,14 +3337,12 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "const_format", - "hex", "rand", "serde", "uhlc", - "uuid", "zenoh-buffers", "zenoh-keyexpr", "zenoh-result", @@ -3355,17 +3351,27 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "anyhow", ] +[[package]] +name = "zenoh-runtime" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "lazy_static", + "tokio", + "zenoh-collections", + "zenoh-result", +] + [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "bincode", "log", "serde", "shared_memory", @@ -3376,26 +3382,22 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "event-listener 4.0.0", - "flume", "futures", "tokio", "zenoh-buffers", "zenoh-collections", "zenoh-core", + "zenoh-runtime", ] [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-executor", - "async-global-executor", - "async-std", "async-trait", "flume", "log", @@ -3406,6 +3408,8 @@ dependencies = [ "rsa", "serde", "sha3", + "tokio", + "tokio-util", "zenoh-buffers", "zenoh-codec", "zenoh-collections", @@ -3415,6 +3419,7 @@ dependencies = [ "zenoh-link", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-shm", "zenoh-sync", "zenoh-util", @@ -3423,27 +3428,22 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-std", "async-trait", - "clap 4.4.11", - "const_format", "flume", - "futures", - "hex", "home", "humantime", "lazy_static", "libc", "libloading", "log", - "pnet", "pnet_datalink", "shellexpand", + "tokio", "winapi", "zenoh-core", - "zenoh-protocol", "zenoh-result", ] diff --git a/Cargo.toml b/Cargo.toml index 52deaa71c..95867f95f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,9 +41,11 @@ maintenance = { status = "actively-developed" } [dependencies] async-std = "=1.12.0" async-trait = "0.1.66" +chrono = "0.4.34" env_logger = "0.10.0" futures = "0.3.26" json5 = "0.4.1" +lazy_static = "1.4.0" libc = "0.2.139" log = "0.4.17" rand = "0.8.5" diff --git a/Cargo.toml.in b/Cargo.toml.in index d1eec11bd..f434df3a1 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -41,9 +41,11 @@ maintenance = { status = "actively-developed" } [dependencies] async-std = "=1.12.0" async-trait = "0.1.66" +chrono = "0.4.34" env_logger = "0.10.0" futures = "0.3.26" json5 = "0.4.1" +lazy_static = "1.4.0" libc = "0.2.139" log = "0.4.17" rand = "0.8.5" diff --git a/docs/api.rst b/docs/api.rst index 6694af4a5..758c405b5 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -38,6 +38,8 @@ Bytes map .. autocfunction:: zenoh_commons.h::z_bytes_map_null .. autocfunction:: zenoh_commons.h::z_bytes_map_drop .. autocfunction:: zenoh_commons.h::z_bytes_map_get +.. autocfunction:: zenoh_commons.h::z_bytes_map_len +.. autocfunction:: zenoh_commons.h::z_bytes_map_is_empty .. autocfunction:: zenoh_commons.h::z_bytes_map_insert_by_alias .. autocfunction:: zenoh_commons.h::z_bytes_map_insert_by_copy .. autocfunction:: zenoh_commons.h::z_bytes_map_iter @@ -106,6 +108,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 @@ -120,6 +123,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 @@ -157,6 +161,8 @@ Attachment .. autocfunction:: zenoh_commons.h::z_attachment_null .. autocfunction:: zenoh_commons.h::z_attachment_get +.. autocfunction:: zenoh_commons.h::z_attachment_len +.. autocfunction:: zenoh_commons.h::z_attachment_is_empty .. autocfunction:: zenoh_commons.h::z_attachment_check .. autocfunction:: zenoh_commons.h::z_attachment_iterate @@ -299,7 +305,7 @@ Types .. autocstruct:: zenoh_commons.h::zc_owned_liveliness_token_t .. autocstruct:: zenoh_commons.h::zc_owned_liveliness_declaration_options_t -.. autocstruct:: zenoh_commons.h::zc_owned_liveliness_get_options_t +.. autocstruct:: zenoh_commons.h::zc_liveliness_get_options_t .. autocstruct:: zenoh_commons.h::zc_owned_liveliness_declare_subscriber_options_t Functions diff --git a/docs/requirements.txt b/docs/requirements.txt index 670562c3e..a5a4b5f60 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ -sphinx==4.5.0 -sphinx_c_autodoc -sphinx_rtd_theme -clang==14 +sphinx==7.2.6 +sphinx_c_autodoc==1.3.0 +sphinx_rtd_theme==2.0.0 +clang==14.0 diff --git a/examples/z_liveliness.c b/examples/z_liveliness.c index b21cc40bc..4191b0496 100644 --- a/examples/z_liveliness.c +++ b/examples/z_liveliness.c @@ -13,12 +13,6 @@ #include #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" int main(int argc, char **argv) { @@ -63,7 +57,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } else if (c == 'd') { printf("Undeclaring liveliness token...\n"); z_drop(z_move(token)); diff --git a/examples/z_ping.c b/examples/z_ping.c index bb061baee..fdc08f71d 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "zenoh.h" @@ -58,35 +57,27 @@ int main(int argc, char** argv) { z_mutex_lock(&mutex); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); - struct timespec wmup_start, wmup_stop, wmup_timeout; - clock_gettime(CLOCK_MONOTONIC, &wmup_start); + z_clock_t warmup_start = z_clock_now(); + unsigned long elapsed_us = 0; while (elapsed_us < args.warmup_ms * 1000) { - clock_gettime(CLOCK_REALTIME, &wmup_timeout); - wmup_timeout.tv_sec += PING_TIMEOUT_SEC; z_publisher_put(z_loan(pub), data, args.size, NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); } - clock_gettime(CLOCK_MONOTONIC, &wmup_stop); - elapsed_us = - (1000000 * (wmup_stop.tv_sec - wmup_start.tv_sec) + (wmup_stop.tv_nsec - wmup_start.tv_nsec) / 1000); + elapsed_us = z_clock_elapsed_us(&warmup_start); } } - struct timespec t_start, t_stop, t_timeout; unsigned long* results = z_malloc(sizeof(unsigned long) * args.number_of_pings); for (int i = 0; i < args.number_of_pings; i++) { - clock_gettime(CLOCK_REALTIME, &t_timeout); - t_timeout.tv_sec += PING_TIMEOUT_SEC; - clock_gettime(CLOCK_MONOTONIC, &t_start); + z_clock_t measure_start = z_clock_now(); z_publisher_put(z_loan(pub), data, args.size, NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); } - clock_gettime(CLOCK_MONOTONIC, &t_stop); - results[i] = (1000000 * (t_stop.tv_sec - t_start.tv_sec) + (t_stop.tv_nsec - t_start.tv_nsec) / 1000); + results[i] = z_clock_elapsed_us(&measure_start); } for (int i = 0; i < args.number_of_pings; i++) { printf("%d bytes: seq=%d rtt=%luµs, lat=%luµs\n", args.size, i, results[i], results[i] / 2); diff --git a/examples/z_pub.c b/examples/z_pub.c index 73fd02287..ecc95e42d 100644 --- a/examples/z_pub.c +++ b/examples/z_pub.c @@ -15,12 +15,6 @@ #include #include "zenoh.h" -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif void matching_status_handler(const zcu_matching_status_t *matching_status, void *arg) { if (matching_status->matching) { @@ -41,11 +35,11 @@ int main(int argc, char **argv) { z_owned_config_t config = z_config_default(); if (argc > 4) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { + if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[4]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", - argv[3], Z_CONFIG_CONNECT_KEY, Z_CONFIG_CONNECT_KEY); + argv[4], Z_CONFIG_CONNECT_KEY, Z_CONFIG_CONNECT_KEY); exit(-1); } } @@ -72,7 +66,7 @@ int main(int argc, char **argv) { char buf[256]; for (int idx = 0; 1; ++idx) { - sleep(1); + z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index b75f245c3..a24133e91 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -15,12 +15,6 @@ #include #include "zenoh.h" -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif int main(int argc, char **argv) { char *keyexpr = "demo/example/zenoh-c-pub"; @@ -69,7 +63,7 @@ int main(int argc, char **argv) { char buf[256]; char buf_ind[16]; for (int idx = 0; 1; ++idx) { - sleep(1); + z_sleep_s(1); // add some other attachment value sprintf(buf_ind, "%d", idx); diff --git a/examples/z_pub_cache.c b/examples/z_pub_cache.c index 8c1d36221..770bf9d93 100644 --- a/examples/z_pub_cache.c +++ b/examples/z_pub_cache.c @@ -15,12 +15,6 @@ #include #include "zenoh.h" -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif int main(int argc, char **argv) { char *keyexpr = "demo/example/zenoh-c-pub"; @@ -66,7 +60,7 @@ int main(int argc, char **argv) { char buf[256]; for (int idx = 0; 1; ++idx) { - sleep(1); + z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)buf, strlen(buf), NULL); diff --git a/examples/z_pub_shm.c b/examples/z_pub_shm.c index f26c65c08..10970bf62 100644 --- a/examples/z_pub_shm.c +++ b/examples/z_pub_shm.c @@ -17,12 +17,6 @@ #include #include "zenoh.h" -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #define N 10 @@ -85,7 +79,7 @@ int main(int argc, char **argv) { snprintf(buf, 255, "[%4d] %s", idx, value); size_t len = strlen(buf); zc_shmbuf_set_length(&shmbuf, len); - sleep(1); + z_sleep_s(1); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); diff --git a/examples/z_pull.c b/examples/z_pull.c index badbd6f44..4f2de7945 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -12,12 +12,6 @@ // ZettaScale Zenoh Team, // #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *kind_to_str(z_sample_kind_t kind); @@ -67,7 +61,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } else { z_subscriber_pull(z_loan(sub)); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index 7653a6c77..d60bc2bf1 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -12,12 +12,6 @@ // ZettaScale Zenoh Team, // #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *kind_to_str(z_sample_kind_t kind); @@ -69,7 +63,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_queryable.c b/examples/z_queryable.c index f74f5d355..9d6ec7702 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -13,12 +13,6 @@ #include #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *expr = "demo/example/zenoh-c-queryable"; @@ -81,7 +75,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 80c98d689..672ddd607 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -14,12 +14,6 @@ #include #include #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *expr = "demo/example/zenoh-c-queryable"; diff --git a/examples/z_scout.c b/examples/z_scout.c index 3b882f547..1b7b3c21d 100644 --- a/examples/z_scout.c +++ b/examples/z_scout.c @@ -12,14 +12,6 @@ // ZettaScale Zenoh Team, #include - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif - #include "zenoh.h" void fprintpid(FILE *stream, z_id_t pid) { @@ -41,13 +33,9 @@ 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_whatami_to_str(whatami, buf, sizeof(buf)); + fprintf(stream, "%s", buf); } void fprintlocators(FILE *stream, const z_str_array_t *locs) { @@ -96,6 +84,6 @@ int main(int argc, char **argv) { z_owned_closure_hello_t closure = z_closure(callback, drop, context); printf("Scouting...\n"); z_scout(z_move(config), z_move(closure)); - sleep(1); + z_sleep_s(1); return 0; } \ No newline at end of file diff --git a/examples/z_sub.c b/examples/z_sub.c index b52db8850..378a717e6 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -12,12 +12,6 @@ // ZettaScale Zenoh Team, // #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *kind_to_str(z_sample_kind_t kind); @@ -74,7 +68,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index c3d22e39f..2031d1155 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -13,12 +13,6 @@ // #include #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *kind_to_str(z_sample_kind_t kind); @@ -86,7 +80,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_sub_liveliness.c b/examples/z_sub_liveliness.c index 67c87001a..5916200b2 100644 --- a/examples/z_sub_liveliness.c +++ b/examples/z_sub_liveliness.c @@ -12,12 +12,6 @@ // ZettaScale Zenoh Team, // #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" void data_handler(const z_sample_t *sample, void *arg) { @@ -76,7 +70,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_sub_thr.c b/examples/z_sub_thr.c index d32480174..05ee709d3 100644 --- a/examples/z_sub_thr.c +++ b/examples/z_sub_thr.c @@ -12,7 +12,6 @@ // ZettaScale Zenoh Team, // #include -#include #include "zenoh.h" @@ -21,46 +20,40 @@ typedef struct { volatile unsigned long count; volatile unsigned long finished_rounds; - struct timespec start; - struct timespec first_start; + z_clock_t start; + z_clock_t first_start; + bool started; } z_stats_t; z_stats_t *z_stats_make() { z_stats_t *stats = z_malloc(sizeof(z_stats_t)); stats->count = 0; stats->finished_rounds = 0; - stats->first_start.tv_nsec = 0; + stats->started = false; return stats; } -static inline double get_elapsed_s(const struct timespec *start, const struct timespec *end) { - return (double)(end->tv_sec - start->tv_sec) + (double)(end->tv_nsec - start->tv_nsec) / 1.0E9; -} - void on_sample(const z_sample_t *sample, void *context) { z_stats_t *stats = (z_stats_t *)context; if (stats->count == 0) { - clock_gettime(CLOCK_MONOTONIC, &stats->start); - if (stats->first_start.tv_nsec == 0) { + stats->start = z_clock_now(); + if (!stats->started) { stats->first_start = stats->start; + stats->started = true; } stats->count++; } else if (stats->count < N) { stats->count++; } else { - struct timespec end; - clock_gettime(CLOCK_MONOTONIC, &end); stats->finished_rounds++; - printf("%f msg/s\n", (double)N / get_elapsed_s(&stats->start, &end)); + printf("%f msg/s\n", 1000.0 * N / z_clock_elapsed_ms(&stats->start)); stats->count = 0; } } void drop_stats(void *context) { const z_stats_t *stats = (z_stats_t *)context; const unsigned long sent_messages = N * stats->finished_rounds + stats->count; - struct timespec end; - clock_gettime(CLOCK_MONOTONIC, &end); - double elapsed_s = get_elapsed_s(&stats->first_start, &end); + double elapsed_s = z_clock_elapsed_s(&stats->first_start); printf("Stats being dropped after unsubscribing: sent %ld messages over %f seconds (%f msg/s)\n", sent_messages, elapsed_s, (double)sent_messages / elapsed_s); z_free(context); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index e0b405014..55a52f82d 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -93,6 +93,20 @@ typedef enum z_encoding_prefix_t { Z_ENCODING_PREFIX_IMAGE_PNG = 19, Z_ENCODING_PREFIX_IMAGE_GIF = 20, } z_encoding_prefix_t; +/** + * A :c:type:`z_keyexpr_intersection_level_t`. + * + * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** + */ +typedef enum z_keyexpr_intersection_level_t { + Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT = 0, + Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS = 1, + Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, + Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, +} z_keyexpr_intersection_level_t; /** * The priority of zenoh messages. * @@ -218,6 +232,14 @@ typedef struct z_owned_bytes_map_t { uint64_t _0[2]; size_t _1[4]; } z_owned_bytes_map_t; +/** + * Clock + * Uses monotonic clock + */ +typedef struct z_clock_t { + uint64_t t; + const void *t_base; +} z_clock_t; /** * Represents a Zenoh ID. * @@ -343,13 +365,8 @@ typedef struct z_owned_closure_query_t { * * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ -#if defined(TARGET_ARCH_X86_64) +#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_reply_t { - uint64_t _0[28]; -} z_owned_reply_t; -#endif -#if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_owned_reply_t { uint64_t _0[30]; } z_owned_reply_t; #endif @@ -825,6 +842,13 @@ typedef struct z_task_t { typedef struct z_task_attr_t { size_t _0; } z_task_attr_t; +/** + * Time + * Uses system clock + */ +typedef struct z_time_t { + uint64_t t; +} z_time_t; /** * The options for `zc_liveliness_declare_token` */ @@ -850,9 +874,9 @@ typedef struct zc_owned_liveliness_token_t { /** * The options for :c:func:`zc_liveliness_declare_subscriber` */ -typedef struct zc_owned_liveliness_get_options_t { +typedef struct zc_liveliness_get_options_t { uint32_t timeout_ms; -} zc_owned_liveliness_get_options_t; +} zc_liveliness_get_options_t; /** * An owned payload, backed by a reference counted owner. * @@ -1025,6 +1049,10 @@ ZENOHC_API bool z_attachment_check(const struct z_attachment_t *this_); * Returns the value associated with the key. */ ZENOHC_API struct z_bytes_t z_attachment_get(struct z_attachment_t this_, struct z_bytes_t key); +/** + * Returns true if `z_attachment_t` contains no key-value pairs, false otherwise. + */ +ZENOHC_API bool z_attachment_is_empty(struct z_attachment_t this_); /** * Iterate over `this`'s key-value pairs, breaking if `body` returns a non-zero * value for a key-value pair, and returning the latest return value. @@ -1037,6 +1065,12 @@ ZENOHC_API int8_t z_attachment_iterate(struct z_attachment_t this_, z_attachment_iter_body_t body, void *context); +/** + * Returns number of key-value pairs for `z_attachment_t`. + * + * Does so by iterating over all existing key-value pairs. + */ +ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); /** * Returns the gravestone value for `z_attachment_t`. */ @@ -1154,6 +1188,10 @@ ZENOHC_API void z_bytes_map_insert_by_copy(const struct z_owned_bytes_map_t *this_, struct z_bytes_t key, struct z_bytes_t value); +/** + * Returns true if the map is empty, false otherwise. + */ +ZENOHC_API bool z_bytes_map_is_empty(struct z_owned_bytes_map_t *this_); /** * Iterates over the key-value pairs in the map. * @@ -1170,6 +1208,10 @@ ZENOHC_API int8_t z_bytes_map_iter(const struct z_owned_bytes_map_t *this_, z_attachment_iter_body_t body, void *ctx); +/** + * Returns number of key-value pairs in the map. + */ +ZENOHC_API size_t z_bytes_map_len(struct z_owned_bytes_map_t *this_); /** * Constructs a new map. */ @@ -1193,6 +1235,10 @@ ZENOHC_API struct z_bytes_t z_bytes_null(void); * Constructs a `len` bytes long view starting at `start`. */ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); +ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); +ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); +ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); +ZENOHC_API struct z_clock_t z_clock_now(void); /** * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. * @@ -1594,6 +1640,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`. * @@ -1682,10 +1736,23 @@ 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 */ ZENOHC_API struct z_owned_keyexpr_t z_keyexpr_null(void); +/** + * Returns the relation between `left` and `right` from `left`'s point of view. + * + * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. + */ +ZENOHC_API +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, + struct z_keyexpr_t right); /** * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. * The user is responsible of droping the returned string using `z_drop` @@ -1971,6 +2038,11 @@ ZENOHC_API struct z_owned_queryable_t z_queryable_null(void); * Constructs the default value for :c:type:`z_query_reply_options_t`. */ ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); +ZENOHC_API void z_random_fill(void *buf, size_t len); +ZENOHC_API uint16_t z_random_u16(void); +ZENOHC_API uint32_t z_random_u32(void); +ZENOHC_API uint64_t z_random_u64(void); +ZENOHC_API uint8_t z_random_u8(void); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -2108,6 +2180,9 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); * Constructs a null safe-to-drop value of 'z_owned_session_t' type */ ZENOHC_API struct z_owned_session_t z_session_null(void); +ZENOHC_API int8_t z_sleep_ms(size_t time); +ZENOHC_API int8_t z_sleep_s(size_t time); +ZENOHC_API int8_t z_sleep_us(size_t time); /** * Returns ``true`` if `strs` is valid. */ @@ -2170,6 +2245,11 @@ int8_t z_task_init(struct z_task_t *task, void (*fun)(void *arg), void *arg); ZENOHC_API int8_t z_task_join(struct z_task_t *task); +ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); +ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); +ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); +ZENOHC_API struct z_time_t z_time_now(void); +ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); /** * Returns ``true`` if `ts` is a valid timestamp */ @@ -2200,6 +2280,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. */ @@ -2245,6 +2337,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. @@ -2317,24 +2418,23 @@ ZENOHC_API int8_t zc_liveliness_get(struct z_session_t session, struct z_keyexpr_t key, struct z_owned_closure_reply_t *callback, - const struct zc_owned_liveliness_get_options_t *options); + const struct zc_liveliness_get_options_t *options); /** * Returns `true` if the options are valid. */ -ZENOHC_API -bool zc_liveliness_get_options_check(const struct zc_owned_liveliness_get_options_t *_opts); +ZENOHC_API bool zc_liveliness_get_options_check(const struct zc_liveliness_get_options_t *_opts); /** - * The gravestone value for `zc_owned_liveliness_get_options_t` + * The gravestone value for `zc_liveliness_get_options_t` */ -ZENOHC_API struct zc_owned_liveliness_get_options_t zc_liveliness_get_options_default(void); +ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); /** * Destroys the options. */ -ZENOHC_API void zc_liveliness_get_options_drop(struct zc_owned_liveliness_get_options_t *opts); +ZENOHC_API void zc_liveliness_get_options_drop(struct zc_liveliness_get_options_t *opts); /** - * The gravestone value for `zc_owned_liveliness_get_options_t` + * The gravestone value for `zc_liveliness_get_options_t` */ -ZENOHC_API struct zc_owned_liveliness_get_options_t zc_liveliness_get_options_null(void); +ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_null(void); /** * Returns `true` if the options are valid. */ diff --git a/src/attachment.rs b/src/attachment.rs index 051edafdc..7b456a9c1 100644 --- a/src/attachment.rs +++ b/src/attachment.rs @@ -117,6 +117,58 @@ pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_by } } +fn _z_attachment_len(this: z_attachment_t, check_if_non_empty: bool) -> usize { + match this.iteration_driver.as_ref() { + None => 0, + Some(iteration_driver) => { + struct count_context_t { + count: usize, + stop_if_not_empty: bool, + } + + extern "C" fn attachment_count_iterator( + _key: z_bytes_t, + _value: z_bytes_t, + context: *mut c_void, + ) -> i8 { + unsafe { + let context = &mut *(context as *mut count_context_t); + context.count += 1; + if context.stop_if_not_empty { + 1 + } else { + 0 + } + } + } + let mut count_context = count_context_t { + count: 0, + stop_if_not_empty: check_if_non_empty, + }; + (iteration_driver)( + this.data, + attachment_count_iterator, + &mut count_context as *mut _ as *mut c_void, + ); + count_context.count + } + } +} + +/// Returns number of key-value pairs for `z_attachment_t`. +/// +/// Does so by iterating over all existing key-value pairs. +#[no_mangle] +pub extern "C" fn z_attachment_len(this: z_attachment_t) -> usize { + _z_attachment_len(this, false) +} + +/// Returns true if `z_attachment_t` contains no key-value pairs, false otherwise. +#[no_mangle] +pub extern "C" fn z_attachment_is_empty(this: z_attachment_t) -> bool { + _z_attachment_len(this, true) == 0 +} + /// A map of maybe-owned vector of bytes to owned vector of bytes. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher @@ -164,6 +216,20 @@ pub extern "C" fn z_bytes_map_drop(this: &mut z_owned_bytes_map_t) { this.take(); } +/// Returns number of key-value pairs in the map. +#[no_mangle] +pub extern "C" fn z_bytes_map_len(this: &mut z_owned_bytes_map_t) -> usize { + let this = unsafe { &*this.get() }; + this.as_ref().map(|m| m.len()).unwrap_or(0) +} + +/// Returns true if the map is empty, false otherwise. +#[no_mangle] +pub extern "C" fn z_bytes_map_is_empty(this: &mut z_owned_bytes_map_t) -> bool { + let this = unsafe { &*this.get() }; + this.as_ref().map(|m| m.is_empty()).unwrap_or(true) +} + /// Returns the value associated with `key`, returning a gravestone value if: /// - `this` or `key` is in gravestone state. /// - `this` has no value associated to `key` diff --git a/src/get.rs b/src/get.rs index 423810a4f..bc37d7039 100644 --- a/src/get.rs +++ b/src/get.rs @@ -48,12 +48,8 @@ type ReplyInner = Option; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[cfg(target_arch = "x86_64")] +#[cfg(not(target_arch = "arm"))] #[repr(C, align(8))] -pub struct z_owned_reply_t([u64; 28]); - -#[cfg(target_arch = "aarch64")] -#[repr(C, align(16))] pub struct z_owned_reply_t([u64; 30]); #[cfg(target_arch = "arm")] diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 06784a8dc..7742b3948 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -24,6 +24,7 @@ use crate::z_str_null; use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use libc::c_char; +use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; @@ -103,6 +104,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 { @@ -293,6 +320,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)] @@ -305,6 +348,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: @@ -552,3 +609,43 @@ pub extern "C" fn z_keyexpr_join(left: z_keyexpr_t, right: z_keyexpr_t) -> z_own } } } + +/// A :c:type:`z_keyexpr_intersection_level_t`. +/// +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(C)] +pub enum z_keyexpr_intersection_level_t { + DISJOINT = 0, + INTERSECTS = 1, + INCLUDES = 2, + EQUALS = 3, +} + +impl From for z_keyexpr_intersection_level_t { + fn from(val: SetIntersectionLevel) -> Self { + match val { + SetIntersectionLevel::Disjoint => z_keyexpr_intersection_level_t::DISJOINT, + SetIntersectionLevel::Intersects => z_keyexpr_intersection_level_t::INTERSECTS, + SetIntersectionLevel::Includes => z_keyexpr_intersection_level_t::INCLUDES, + SetIntersectionLevel::Equals => z_keyexpr_intersection_level_t::EQUALS, + } + } +} + +#[no_mangle] +/// Returns the relation between `left` and `right` from `left`'s point of view. +/// +/// Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. +pub extern "C" fn z_keyexpr_relation_to( + left: z_keyexpr_t, + right: z_keyexpr_t, +) -> z_keyexpr_intersection_level_t { + match (&*left, &*right) { + (Some(l), Some(r)) => l.relation_to(r).into(), + _ => z_keyexpr_intersection_level_t::DISJOINT, + } +} diff --git a/src/lib.rs b/src/lib.rs index 2ff9259c6..5019a0713 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::*; @@ -174,3 +178,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/liveliness.rs b/src/liveliness.rs index 69ee2d2e2..d66508cd5 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -195,29 +195,27 @@ pub extern "C" fn zc_liveliness_declare_subscriber( /// The options for :c:func:`zc_liveliness_declare_subscriber` #[repr(C)] -pub struct zc_owned_liveliness_get_options_t { +pub struct zc_liveliness_get_options_t { timeout_ms: u32, } -/// The gravestone value for `zc_owned_liveliness_get_options_t` +/// The gravestone value for `zc_liveliness_get_options_t` #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_null() -> zc_owned_liveliness_get_options_t { - zc_owned_liveliness_get_options_t { timeout_ms: 0 } +pub extern "C" fn zc_liveliness_get_options_null() -> zc_liveliness_get_options_t { + zc_liveliness_get_options_t { timeout_ms: 0 } } -/// The gravestone value for `zc_owned_liveliness_get_options_t` +/// The gravestone value for `zc_liveliness_get_options_t` #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_default() -> zc_owned_liveliness_get_options_t { - zc_owned_liveliness_get_options_t { timeout_ms: 10000 } +pub extern "C" fn zc_liveliness_get_options_default() -> zc_liveliness_get_options_t { + zc_liveliness_get_options_t { timeout_ms: 10000 } } /// Returns `true` if the options are valid. #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_check( - _opts: &zc_owned_liveliness_get_options_t, -) -> bool { +pub extern "C" fn zc_liveliness_get_options_check(_opts: &zc_liveliness_get_options_t) -> bool { true } /// Destroys the options. #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_drop(opts: &mut zc_owned_liveliness_get_options_t) { +pub extern "C" fn zc_liveliness_get_options_drop(opts: &mut zc_liveliness_get_options_t) { *opts = zc_liveliness_get_options_null() } @@ -231,7 +229,7 @@ pub extern "C" fn zc_liveliness_get( session: z_session_t, key: z_keyexpr_t, callback: &mut z_owned_closure_reply_t, - options: Option<&zc_owned_liveliness_get_options_t>, + options: Option<&zc_liveliness_get_options_t>, ) -> i8 { let Some(session) = session.upgrade() else { log::error!("Failed to declare liveliness token: provided session was invalid"); diff --git a/src/platform/clock.rs b/src/platform/clock.rs new file mode 100644 index 000000000..196d697cb --- /dev/null +++ b/src/platform/clock.rs @@ -0,0 +1,127 @@ +use chrono::{DateTime, Local}; +use libc::c_char; +use std::{ + os::raw::c_void, + 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, +// to be able to return number of ns passed since. +// This is to avoid wrapping Instant into a c type and not +// have to account for its platform-dependent size and alignment. +lazy_static! { + static ref CLOCK_BASE: Instant = Instant::now(); +} + +/// Clock +/// Uses monotonic clock +#[repr(C)] +#[derive(Clone, Copy)] +pub struct z_clock_t { + t: u64, + t_base: *const c_void, +} + +#[no_mangle] +pub extern "C" fn z_clock_now() -> z_clock_t { + z_clock_t { + t: CLOCK_BASE.elapsed().as_nanos() as u64, + t_base: &CLOCK_BASE as *const CLOCK_BASE as *const c_void, + } +} +#[allow(clippy::missing_safety_doc)] +unsafe fn get_elapsed_nanos(time: *const z_clock_t) -> u64 { + if time.is_null() { + return 0; + } + let now_t = (*((*time).t_base as *const CLOCK_BASE)) + .elapsed() + .as_nanos() as u64; + if now_t > (*time).t { + now_t - (*time).t + } else { + 0 + } +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_clock_elapsed_s(time: *const z_clock_t) -> u64 { + get_elapsed_nanos(time) / 1_000_000_000 +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_clock_elapsed_ms(time: *const z_clock_t) -> u64 { + get_elapsed_nanos(time) / 1_000_000 +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_clock_elapsed_us(time: *const z_clock_t) -> u64 { + get_elapsed_nanos(time) / 1_000 +} + +/// Time +/// Uses system clock +#[repr(C)] +#[derive(Clone, Copy)] +pub struct z_time_t { + t: u64, +} + +#[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 || buf.is_null() { + return buf; + } + let datetime: DateTime = SystemTime::now().into(); + let s = datetime.format("%Y-%m-%dT%H:%M:%SZ").to_string(); + 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 +} + +#[no_mangle] +pub extern "C" fn z_time_now() -> z_time_t { + z_time_t { + t: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or(Duration::new(0, 0)) + .as_nanos() as u64, + } +} +#[allow(clippy::missing_safety_doc)] +unsafe fn get_elapsed_nanos_system_clock(time: *const z_time_t) -> u64 { + if time.is_null() { + return 0; + } + let now_t = z_time_now().t; + if now_t > (*time).t { + now_t - (*time).t + } else { + 0 + } +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_time_elapsed_s(time: *const z_time_t) -> u64 { + get_elapsed_nanos_system_clock(time) / 1_000_000_000 +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_time_elapsed_ms(time: *const z_time_t) -> u64 { + get_elapsed_nanos_system_clock(time) / 1_000_000 +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_time_elapsed_us(time: *const z_time_t) -> u64 { + get_elapsed_nanos_system_clock(time) / 1_000 +} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index c9f87a9c7..438763afe 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -1,5 +1,5 @@ // -// Copyright (c) 2017, 2023 ZettaScale Technology. +// Copyright (c) 2017, 2024 ZettaScale Technology. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License 2.0 which is available at @@ -12,5 +12,12 @@ // ZettaScale Zenoh team, // +pub use clock::*; +mod clock; +pub use sleep::*; +mod sleep; pub use synchronization::*; mod synchronization; + +pub use random::*; +mod random; diff --git a/src/platform/random.rs b/src/platform/random.rs new file mode 100644 index 000000000..d466e7b77 --- /dev/null +++ b/src/platform/random.rs @@ -0,0 +1,34 @@ +use std::slice::from_raw_parts_mut; + +use libc::c_void; +use rand::{random, thread_rng, RngCore}; + +#[no_mangle] +pub extern "C" fn z_random_u8() -> u8 { + random::() +} + +#[no_mangle] +pub extern "C" fn z_random_u16() -> u16 { + random::() +} + +#[no_mangle] +pub extern "C" fn z_random_u32() -> u32 { + random::() +} + +#[no_mangle] +pub extern "C" fn z_random_u64() -> u64 { + random::() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_random_fill(buf: *mut c_void, len: usize) { + if buf.is_null() || len == 0 { + return; + } + let b: &mut [u8] = from_raw_parts_mut(buf as *mut u8, len); + thread_rng().fill_bytes(b); +} diff --git a/src/platform/sleep.rs b/src/platform/sleep.rs new file mode 100644 index 000000000..b2f3e4dd7 --- /dev/null +++ b/src/platform/sleep.rs @@ -0,0 +1,19 @@ +use std::{thread, time}; + +#[no_mangle] +pub extern "C" fn z_sleep_s(time: usize) -> i8 { + thread::sleep(time::Duration::from_secs(time as u64)); + 0 +} + +#[no_mangle] +pub extern "C" fn z_sleep_ms(time: usize) -> i8 { + thread::sleep(time::Duration::from_millis(time as u64)); + 0 +} + +#[no_mangle] +pub extern "C" fn z_sleep_us(time: usize) -> i8 { + thread::sleep(time::Duration::from_micros(time as u64)); + 0 +} 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 + } + } +} diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 8dcff3317..9ade440f3 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -17,14 +17,6 @@ #undef NDEBUG #include - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif - #include "zenoh.h" #define SLEEP 1 @@ -135,7 +127,7 @@ int main(int argc, char **argv) { assert(_ret_int == -1); #endif - sleep(SLEEP); + z_sleep_s(SLEEP); size_t keyexpr_len = strlen(URI); char *keyexpr_str = (char *)z_malloc(keyexpr_len + 1); @@ -157,7 +149,7 @@ int main(int argc, char **argv) { assert(strlen(URI) == keyexpr_len); #endif - sleep(SLEEP); + z_sleep_s(SLEEP); z_owned_config_t _ret_config = z_config_new(); assert(z_check(_ret_config)); @@ -184,7 +176,7 @@ int main(int argc, char **argv) { #endif z_drop(z_move(_ret_sconfig)); - sleep(SLEEP); + z_sleep_s(SLEEP); _ret_sconfig = z_scouting_config_from(z_loan(_ret_config)); z_owned_closure_hello_t _ret_closure_hello = z_closure(hello_handler, NULL, NULL); @@ -192,8 +184,8 @@ int main(int argc, char **argv) { assert(_ret_int8 == 0); assert(hellos == 1); - sleep(atoi(SCOUTING_TIMEOUT) / 1000); - sleep(SLEEP); + z_sleep_s(atoi(SCOUTING_TIMEOUT) / 1000); + z_sleep_s(SLEEP); z_owned_session_t s1 = z_open(z_move(_ret_config)); assert(z_check(s1)); @@ -207,13 +199,13 @@ int main(int argc, char **argv) { z_owned_closure_zid_t _ret_closure_zid = z_closure(zid_handler, NULL, NULL); _ret_int8 = z_info_peers_zid(z_loan(s1), z_move(_ret_closure_zid)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(zids == 0); _ret_int8 = z_info_routers_zid(z_loan(s1), z_move(_ret_closure_zid)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(zids == 1); #ifdef ZENOH_PICO @@ -223,7 +215,7 @@ int main(int argc, char **argv) { zp_start_lease_task(z_loan(s1), &_ret_lease_opt); #endif - sleep(SLEEP); + z_sleep_s(SLEEP); _ret_config = z_config_default(); #ifdef ZENOH_PICO @@ -248,7 +240,7 @@ int main(int argc, char **argv) { zp_start_lease_task(z_loan(s2), NULL); #endif - sleep(SLEEP); + z_sleep_s(SLEEP); z_session_t ls1 = z_loan(s1); z_owned_closure_sample_t _ret_closure_sample = z_closure(data_handler, NULL, &ls1); @@ -257,7 +249,7 @@ int main(int argc, char **argv) { z_declare_subscriber(z_loan(s2), z_keyexpr(keyexpr_str), z_move(_ret_closure_sample), &_ret_sub_opt); assert(z_check(_ret_sub)); - sleep(SLEEP); + z_sleep_s(SLEEP); char s1_res[64]; sprintf(s1_res, "%s/chunk/%d", keyexpr_str, 1); @@ -271,14 +263,14 @@ int main(int argc, char **argv) { _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), (const uint8_t *)value, strlen(value), &_ret_put_opt); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(datas == 1); z_delete_options_t _ret_delete_opt = z_delete_options_default(); _ret_int8 = z_delete(z_loan(s1), z_loan(_ret_expr), &_ret_delete_opt); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(datas == 2); _ret_int8 = z_undeclare_keyexpr(z_loan(s1), z_move(_ret_expr)); @@ -303,23 +295,23 @@ int main(int argc, char **argv) { _ret_int8 = z_publisher_put(z_loan(_ret_pub), (const uint8_t *)value, strlen(value), &_ret_pput_opt); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); _ret_int8 = z_subscriber_pull(z_loan(_ret_psub)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(datas == 3); z_publisher_delete_options_t _ret_pdelete_opt = z_publisher_delete_options_default(); _ret_int8 = z_publisher_delete(z_loan(_ret_pub), &_ret_pdelete_opt); - sleep(SLEEP); + z_sleep_s(SLEEP); _ret_int8 = z_subscriber_pull(z_loan(_ret_psub)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(datas == 4); _ret_int8 = z_undeclare_publisher(z_move(_ret_pub)); @@ -328,7 +320,7 @@ int main(int argc, char **argv) { _ret_int8 = z_undeclare_pull_subscriber(z_move(_ret_psub)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); z_owned_closure_query_t _ret_closure_query = z_closure(query_handler, NULL, &ls1); z_queryable_options_t _ret_qle_opt = z_queryable_options_default(); @@ -336,7 +328,7 @@ int main(int argc, char **argv) { z_declare_queryable(z_loan(s1), z_keyexpr(s1_res), z_move(_ret_closure_query), &_ret_qle_opt); assert(z_check(qle)); - sleep(SLEEP); + z_sleep_s(SLEEP); z_session_t ls2 = z_loan(s2); z_owned_closure_reply_t _ret_closure_reply = z_closure(reply_handler, NULL, &ls2); @@ -350,7 +342,7 @@ int main(int argc, char **argv) { _ret_int8 = z_get(z_loan(s2), z_keyexpr(s1_res), "", z_move(_ret_closure_reply), &_ret_get_opt); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(queries == 1); assert(replies == 1); @@ -372,7 +364,7 @@ int main(int argc, char **argv) { _ret_int8 = z_close(z_move(s2)); assert(_ret_int8 == 0); - sleep(SLEEP * 5); + z_sleep_s(SLEEP * 5); z_free(keyexpr_str); diff --git a/tests/z_api_attachment_test.c b/tests/z_api_attachment_test.c index c11abcbfe..737048e9b 100644 --- a/tests/z_api_attachment_test.c +++ b/tests/z_api_attachment_test.c @@ -29,6 +29,11 @@ void writting_through_map_by_alias_read_by_get() { z_attachment_t attachment = z_bytes_map_as_attachment(&map); // Elements check + + assert(z_bytes_map_len(&map) == 2); + assert(z_attachment_len(attachment) == 2); + assert(!z_attachment_is_empty(attachment)); + z_bytes_t a1 = z_attachment_get(attachment, z_bytes_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); @@ -61,6 +66,10 @@ void writting_through_map_by_copy_read_by_iter() { z_attachment_t attachment = z_bytes_map_as_attachment(&map); // Elements check + assert(z_bytes_map_len(&map) == 2); + assert(z_attachment_len(attachment) == 2); + assert(!z_attachment_is_empty(attachment)); + int res = z_attachment_iterate(attachment, _attachment_reader, (void*)42); assert(res == 24); @@ -81,6 +90,9 @@ void writting_no_map_read_by_get() { z_attachment_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; // Elements check + assert(z_attachment_len(attachment) == 2); + assert(!z_attachment_is_empty(attachment)); + z_bytes_t a1 = z_attachment_get(attachment, z_bytes_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); @@ -94,6 +106,8 @@ void writting_no_map_read_by_get() { void invalid_attachment_safety() { z_attachment_t attachment = z_attachment_null(); + assert(z_attachment_is_empty(attachment)); + assert(z_attachment_len(attachment) == 0); z_bytes_t a_non = z_attachment_get(attachment, z_bytes_from_str("k_non")); assert(a_non.start == NULL); diff --git a/tests/z_api_keyexpr_test.c b/tests/z_api_keyexpr_test.c index b5cdeaad1..cb3c234b3 100644 --- a/tests/z_api_keyexpr_test.c +++ b/tests/z_api_keyexpr_test.c @@ -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() { @@ -73,9 +89,23 @@ void undeclare() { assert(!z_keyexpr_check(&ke)); } +void relation_to() { + z_keyexpr_t nul = z_keyexpr(NULL); + z_keyexpr_t foobar = z_keyexpr("foo/bar"); + z_keyexpr_t foostar = z_keyexpr("foo/*"); + z_keyexpr_t barstar = z_keyexpr("bar/*"); + assert(z_keyexpr_relation_to(foostar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES); + assert(z_keyexpr_relation_to(foobar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS); + assert(z_keyexpr_relation_to(foostar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS); + assert(z_keyexpr_relation_to(barstar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); + assert(z_keyexpr_relation_to(nul, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); + assert(z_keyexpr_relation_to(foobar, nul) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); +} + int main(int argc, char **argv) { canonize(); includes(); intersects(); undeclare(); + relation_to(); } diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 7495939f2..868b3878e 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -122,7 +122,7 @@ int run_subscriber() { } SEM_POST(sem_sub); - sleep(10); + z_sleep_s(10); z_drop(z_move(sub)); z_close(z_move(s)); diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index 554d1fd57..bafdd87ca 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -107,7 +107,7 @@ int run_subscriber() { } SEM_POST(sem); - sleep(10); + z_sleep_s(10); z_undeclare_subscriber(z_move(sub)); z_close(z_move(s)); diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 836f8d988..1de9de788 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -76,7 +76,7 @@ int run_queryable() { } SEM_POST(sem); - sleep(10); + z_sleep_s(10); z_drop(z_move(qable)); z_close(z_move(s)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 67c690f8e..9bcc16cc1 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -59,7 +59,7 @@ int run_queryable() { } SEM_POST(sem); - sleep(10); + z_sleep_s(10); z_drop(z_move(qable)); z_close(z_move(s)); From a2cfa7ff963b62792cd4d50577ffbc5010c76f46 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 28 Mar 2024 12:32:31 +0100 Subject: [PATCH 010/377] merge --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c62eb1df..d29080bad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,9 +417,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", From 206983ecb23142bda6dc43e00aaec1e89c2d80c9 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 3 Apr 2024 22:34:30 +0200 Subject: [PATCH 011/377] put and get with owned payload --- .gitignore | 5 +- CMakeLists.txt | 5 + Cargo.lock | 1 + Cargo.toml | 1 + Cargo.toml.in | 1 + build-resources/opaque-types/Cargo.lock | 2624 +++++++++++++++++++++++ build-resources/opaque-types/Cargo.toml | 10 + build-resources/opaque-types/src/lib.rs | 38 + build.rs | 57 +- examples/z_get.c | 9 +- examples/z_non_blocking_get.c | 7 +- examples/z_ping.c | 5 +- examples/z_pong.c | 6 +- examples/z_pub.c | 3 +- examples/z_pub_attachment.c | 3 +- examples/z_pub_cache.c | 3 +- examples/z_pub_shm.c | 2 +- examples/z_pub_thr.c | 3 +- examples/z_pull.c | 7 +- examples/z_put.c | 3 +- examples/z_query_sub.c | 7 +- examples/z_queryable.c | 10 +- examples/z_queryable_with_channels.c | 10 +- examples/z_sub.c | 7 +- examples/z_sub_attachment.c | 6 +- include/zenoh_commons.h | 185 +- src/collections.rs | 79 +- src/commons.rs | 152 +- src/get.rs | 136 +- src/lib.rs | 2 + src/liveliness.rs | 7 +- src/opaque_types/mod.rs | 15 + src/publisher.rs | 59 +- src/pull_subscriber.rs | 6 +- src/put.rs | 68 +- src/queryable.rs | 19 +- src/querying_subscriber.rs | 6 +- src/subscriber.rs | 6 +- tests/z_api_alignment_test.c | 6 +- tests/z_int_pub_cache_query_sub_test.c | 15 +- tests/z_int_pub_sub_attachment_test.c | 9 +- tests/z_int_pub_sub_test.c | 9 +- tests/z_int_queryable_attachment_test.c | 9 +- tests/z_int_queryable_test.c | 9 +- 44 files changed, 3200 insertions(+), 430 deletions(-) create mode 100644 build-resources/opaque-types/Cargo.lock create mode 100644 build-resources/opaque-types/Cargo.toml create mode 100644 build-resources/opaque-types/src/lib.rs create mode 100644 src/opaque_types/mod.rs diff --git a/.gitignore b/.gitignore index d7a6cf967..8aaf37e32 100644 --- a/.gitignore +++ b/.gitignore @@ -70,4 +70,7 @@ dkms.conf .cache # Platform dependent generated files -include/zenoh_configure.h \ No newline at end of file +include/zenoh_configure.h + +# Build resources +.build_resources* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 00aa5cac2..aac66278b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,6 +179,10 @@ set_genexpr_condition(cargo_flags DEBUG $ "--manifest-path=${cargo_toml_dir_debug}/Cargo.toml" "--release;--manifest-path=${cargo_toml_dir_release}/Cargo.toml") set(cargo_flags ${cargo_flags} ${ZENOHC_CARGO_FLAGS}) +set_genexpr_condition(cargo_dep_flags DEBUG $ + "--manifest-path=${CMAKE_CURRENT_SOURCE_DIR}/build-resources/opaque-types/Cargo.toml" + "--release;--manifest-path=${CMAKE_CURRENT_SOURCE_DIR}/build-resources/opaque-types/Cargo.toml") +set(cargo_dep_flags ${cargo_dep_flags} ${ZENOHC_CARGO_FLAGS}) if(ZENOHC_BUILD_WITH_LOGGER_AUTOINIT) set(cargo_flags ${cargo_flags} --features=logger-autoinit) @@ -199,6 +203,7 @@ add_custom_command( OUTPUT ${libs} COMMAND ${CMAKE_COMMAND} -E echo \"RUSTFLAGS = $$RUSTFLAGS\" COMMAND ${CMAKE_COMMAND} -E echo \"cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags}\" + COMMAND cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_dep_flags} &> ${CMAKE_CURRENT_SOURCE_DIR}/.build_resources_opaque_types.txt || echo "" COMMAND cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags} VERBATIM COMMAND_EXPAND_LISTS diff --git a/Cargo.lock b/Cargo.lock index d29080bad..7bf87ae6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3024,6 +3024,7 @@ dependencies = [ "libc", "log", "rand", + "regex", "serde_yaml", "spin 0.9.8", "zenoh", diff --git a/Cargo.toml b/Cargo.toml index 95867f95f..8e0541888 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,6 +59,7 @@ zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/ze [build-dependencies] cbindgen = "0.24.3" fs2 = "0.4.3" +regex = "1.7.1" serde_yaml = "0.9.19" [lib] diff --git a/Cargo.toml.in b/Cargo.toml.in index f434df3a1..a8123bcd5 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -59,6 +59,7 @@ zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/ze [build-dependencies] cbindgen = "0.24.3" fs2 = "0.4.3" +regex = "1.7.1" serde_yaml = "0.9.19" [lib] diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock new file mode 100644 index 000000000..a6f37dab3 --- /dev/null +++ b/build-resources/opaque-types/Cargo.lock @@ -0,0 +1,2624 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] +name = "array-init" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +dependencies = [ + "concurrent-queue", + "event-listener 5.2.0", + "event-listener-strategy 0.5.0", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +dependencies = [ + "async-lock 3.3.0", + "async-task", + "concurrent-queue", + "fastrand 2.0.2", + "futures-lite 2.3.0", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.2.0", + "async-executor", + "async-io 2.3.2", + "async-lock 3.3.0", + "blocking", + "futures-lite 2.3.0", + "once_cell", + "tokio", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +dependencies = [ + "async-lock 3.3.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.3.0", + "parking", + "polling 3.6.0", + "rustix 0.38.32", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.32", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +dependencies = [ + "async-io 2.3.2", + "async-lock 2.8.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.32", + "signal-hook-registry", + "slab", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite 1.13.0", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" + +[[package]] +name = "async-trait" +version = "0.1.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +dependencies = [ + "async-channel 2.2.0", + "async-lock 3.3.0", + "async-task", + "fastrand 2.0.2", + "futures-io", + "futures-lite 2.3.0", + "piper", + "tracing", +] + +[[package]] +name = "bumpalo" +version = "3.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cache-padded" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener 5.2.0", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand 2.0.2", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "git-version" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" +dependencies = [ + "git-version-macro", +] + +[[package]] +name = "git-version-macro" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipnetwork" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" +dependencies = [ + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keyed-set" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79e110283e09081809ca488cf3a9709270c6d4d4c4a32674c39cc438366615a" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.4", +] + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.5.0", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +dependencies = [ + "value-bag", +] + +[[package]] +name = "lz4_flex" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-types" +version = "0.1.0" +dependencies = [ + "zenoh", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-float" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "pest_meta" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.2", + "futures-io", +] + +[[package]] +name = "pnet_base" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cf6fb3ab38b68d01ab2aea03ed3d1132b4868fa4e06285f29f16da01c5f4c" +dependencies = [ + "no-std-net", +] + +[[package]] +name = "pnet_datalink" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad5854abf0067ebbd3967f7d45ebc8976ff577ff0c7bd101c4973ae3c70f98fe" +dependencies = [ + "ipnetwork", + "libc", + "pnet_base", + "pnet_sys", + "winapi", +] + +[[package]] +name = "pnet_sys" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "417c0becd1b573f6d544f73671070b039051e5ad819cc64aa96377b536128d00" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 0.38.32", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ringbuffer-spsc" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1938faa63a2362ee1747afb2d10567d0fb1413b9cbd6198a8541485c4f773" +dependencies = [ + "array-init", + "cache-padded", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" + +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "serde", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shared_memory" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba8593196da75d9dc4f69349682bd4c2099f8cde114257d1ef7ef1b33d1aba54" +dependencies = [ + "cfg-if", + "libc", + "nix", + "rand", + "win-sys", +] + +[[package]] +name = "shellexpand" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +dependencies = [ + "dirs", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stop-token" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" +dependencies = [ + "async-channel 1.9.0", + "cfg-if", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "token-cell" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a2b964fdb303b08a4eab04d7c1bad2bca33f8eee334ccd28802f1041c6eb87" +dependencies = [ + "paste", +] + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.6", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "futures-util", + "hashbrown 0.14.3", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uhlc" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b6df3f3e948b40e20c38a6d1fd6d8f91b3573922fc164e068ad3331560487e" +dependencies = [ + "humantime", + "lazy_static", + "log", + "rand", + "serde", + "spin", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "unzip-n" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e7e85a0596447f0f2ac090e16bc4c516c6fe91771fb0c0ccf7fa3dae896b9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "getrandom", +] + +[[package]] +name = "validated_struct" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feef04c049b4beae3037a2a31b8da40d8cebec0b97456f24c7de0ede4ed9efed" +dependencies = [ + "json5", + "serde", + "serde_json", + "validated_struct_macros", +] + +[[package]] +name = "validated_struct_macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d4444a980afa9ef0d29c2a3f4d952ec0495a7a996a9c78b52698b71bc21edb4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unzip-n", +] + +[[package]] +name = "value-bag" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.55", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "win-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b7b128a98c1cfa201b09eb49ba285887deb3cbe7466a98850eb1adabb452be5" +dependencies = [ + "windows", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45296b64204227616fdbf2614cefa4c236b98ee64dfaaaa435207ed99fe7829f" +dependencies = [ + "windows_aarch64_msvc 0.34.0", + "windows_i686_gnu 0.34.0", + "windows_i686_msvc 0.34.0", + "windows_x86_64_gnu 0.34.0", + "windows_x86_64_msvc 0.34.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "zenoh" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "base64", + "const_format", + "env_logger", + "event-listener 4.0.3", + "flume", + "form_urlencoded", + "futures", + "git-version", + "lazy_static", + "log", + "ordered-float", + "paste", + "petgraph", + "rand", + "regex", + "rustc_version", + "serde", + "serde_json", + "socket2 0.5.6", + "stop-token", + "tokio", + "tokio-util", + "uhlc", + "uuid", + "vec_map", + "zenoh-buffers", + "zenoh-codec", + "zenoh-collections", + "zenoh-config", + "zenoh-core", + "zenoh-crypto", + "zenoh-keyexpr", + "zenoh-link", + "zenoh-macros", + "zenoh-plugin-trait", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-shm", + "zenoh-sync", + "zenoh-transport", + "zenoh-util", +] + +[[package]] +name = "zenoh-buffers" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "zenoh-collections", +] + +[[package]] +name = "zenoh-codec" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "log", + "serde", + "uhlc", + "zenoh-buffers", + "zenoh-protocol", + "zenoh-shm", +] + +[[package]] +name = "zenoh-collections" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" + +[[package]] +name = "zenoh-config" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "flume", + "json5", + "log", + "num_cpus", + "secrecy", + "serde", + "serde_json", + "serde_yaml", + "validated_struct", + "zenoh-core", + "zenoh-protocol", + "zenoh-result", + "zenoh-util", +] + +[[package]] +name = "zenoh-core" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-global-executor", + "lazy_static", + "tokio", + "zenoh-result", + "zenoh-runtime", +] + +[[package]] +name = "zenoh-crypto" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "aes", + "hmac", + "rand", + "rand_chacha", + "sha3", + "zenoh-result", +] + +[[package]] +name = "zenoh-keyexpr" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "hashbrown 0.14.3", + "keyed-set", + "rand", + "schemars", + "serde", + "token-cell", + "zenoh-result", +] + +[[package]] +name = "zenoh-link" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "zenoh-config", + "zenoh-link-commons", + "zenoh-protocol", + "zenoh-result", +] + +[[package]] +name = "zenoh-link-commons" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "flume", + "futures", + "log", + "rustls", + "rustls-webpki", + "serde", + "tokio", + "tokio-util", + "zenoh-buffers", + "zenoh-codec", + "zenoh-core", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-util", +] + +[[package]] +name = "zenoh-macros" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", + "zenoh-keyexpr", +] + +[[package]] +name = "zenoh-plugin-trait" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "const_format", + "libloading", + "log", + "serde", + "serde_json", + "zenoh-keyexpr", + "zenoh-macros", + "zenoh-result", + "zenoh-util", +] + +[[package]] +name = "zenoh-protocol" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "const_format", + "rand", + "serde", + "uhlc", + "zenoh-buffers", + "zenoh-keyexpr", + "zenoh-result", +] + +[[package]] +name = "zenoh-result" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "anyhow", +] + +[[package]] +name = "zenoh-runtime" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "lazy_static", + "tokio", + "zenoh-collections", + "zenoh-result", +] + +[[package]] +name = "zenoh-shm" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "log", + "serde", + "shared_memory", + "zenoh-buffers", + "zenoh-result", +] + +[[package]] +name = "zenoh-sync" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "event-listener 4.0.3", + "futures", + "tokio", + "zenoh-buffers", + "zenoh-collections", + "zenoh-core", + "zenoh-runtime", +] + +[[package]] +name = "zenoh-transport" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "flume", + "log", + "lz4_flex", + "paste", + "rand", + "ringbuffer-spsc", + "serde", + "sha3", + "tokio", + "tokio-util", + "zenoh-buffers", + "zenoh-codec", + "zenoh-collections", + "zenoh-config", + "zenoh-core", + "zenoh-crypto", + "zenoh-link", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-shm", + "zenoh-sync", + "zenoh-util", +] + +[[package]] +name = "zenoh-util" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-std", + "async-trait", + "flume", + "home", + "humantime", + "lazy_static", + "libc", + "libloading", + "log", + "pnet_datalink", + "shellexpand", + "tokio", + "winapi", + "zenoh-core", + "zenoh-result", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml new file mode 100644 index 000000000..6e8319bb0 --- /dev/null +++ b/build-resources/opaque-types/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "opaque-types" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } \ No newline at end of file diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs new file mode 100644 index 000000000..8ef08035c --- /dev/null +++ b/build-resources/opaque-types/src/lib.rs @@ -0,0 +1,38 @@ +use zenoh::sample::Sample; +use zenoh::buffers::ZBuf; + +#[macro_export] +macro_rules! get_opaque_type_data { +($src_type:ty, $expr:expr) => { + const _: () = { + let align = std::mem::align_of::<$src_type>(); + let size = std::mem::size_of::<$src_type>(); + let mut msg: [u8; 61] = *b"type: , align: , size: "; + let mut i = 0; + while i < 4 { + msg[i as usize + 46] = b'0' + ((align / 10u32.pow(3 - i) as usize) % 10) as u8; + msg[i as usize + 57] = b'0' + ((size / 10u32.pow(3 - i) as usize) % 10) as u8; + i += 1; + } + let mut i: usize = 0; + while i < $expr.len() { + msg[i as usize + 5] = $expr.as_bytes()[i]; + i += 1; + } + panic!("{}", unsafe { + std::str::from_utf8_unchecked(msg.as_slice()) + }); + }; + } +} + +/// A split buffer that owns all of its data. +/// +/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. +get_opaque_type_data!(Option, "z_owned_buffer_t"); + +/// An owned sample. +/// +/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. +get_opaque_type_data!(Option, "zc_owned_sample_t"); \ No newline at end of file diff --git a/build.rs b/build.rs index 17dde1894..03a271817 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,5 @@ use fs2::FileExt; +use regex::Regex; use std::io::{Read, Write}; use std::{borrow::Cow, collections::HashMap, io::BufWriter, path::Path}; @@ -24,6 +25,7 @@ const HEADER: &str = r"// "; fn main() { + generate_opaque_types(); cbindgen::generate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) .expect("Unable to generate bindings") .write_to_file(GENERATION_PATH); @@ -36,7 +38,60 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=src"); println!("cargo:rerun-if-changed=splitguide.yaml"); - println!("cargo:rerun-if-changed=cbindgen.toml") + println!("cargo:rerun-if-changed=cbindgen.toml"); + println!("cargo:rerun-if-changed=build-resources") +} + +fn generate_opaque_types() { + let current_folder = std::env::current_dir().unwrap(); + let path_in = current_folder.join("./.build_resources_opaque_types.txt"); + let path_out = current_folder.join("./src/opaque_types/mod.rs"); + + let data_in = std::fs::read_to_string(path_in).unwrap(); + let mut data_out = String::new(); + let docs = get_opaque_type_docs(); + + let re = Regex::new(r"type:(\w+) *, align:0*(\d+), size:0*(\d+)").unwrap(); + for (_, [type_name, align, size]) in re.captures_iter(&data_in).map(|c| c.extract()) { + let s = format!( + "#[repr(C, align({align}))] +pub struct {type_name} {{ + _0: [u8; {size}] +}} +" + ); + if let Some(doc) = docs.get(type_name) { + for d in doc { + data_out += d; + data_out += "\r\n"; + } + } + data_out += &s; + } + std::fs::write(path_out, data_out).unwrap(); +} + +fn get_opaque_type_docs() -> HashMap> { + let current_folder = std::env::current_dir().unwrap(); + let path_in = current_folder.join("./build-resources/opaque-types/src/lib.rs"); + let re = Regex::new(r#"get_opaque_type_data!\(.*, "(\w+)"\)"#).unwrap(); + let mut comments = std::vec::Vec::::new(); + let mut res = HashMap::>::new(); + + for line in std::fs::read_to_string(path_in).unwrap().lines() { + if line.starts_with("///") { + comments.push(line.to_string()); + continue; + } + if comments.is_empty() { + continue; + } + if let Some(c) = re.captures(line) { + res.insert(c[1].to_string(), comments.clone()); + } + comments.clear(); + } + res } fn configure() { diff --git a/examples/z_get.c b/examples/z_get.c index 853366210..e5a1de104 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -57,17 +57,18 @@ int main(int argc, char **argv) { z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get_options_t opts = z_get_options_default(); if (value != NULL) { - opts.value.payload = z_bytes_from_str(value); + opts.value.payload = zc_payload_encode_from_string(value); } z_get(z_loan(s), keyexpr, "", z_move(channel.send), - &opts); // here, the send is moved and will be dropped by zenoh when adequate + z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_bytes_t payload = z_sample_payload(&sample); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index a741d6071..21437199c 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -49,7 +49,7 @@ int main(int argc, char **argv) { opts.target = Z_QUERY_TARGET_ALL; z_owned_reply_channel_t channel = zc_reply_non_blocking_fifo_new(16); z_get(z_loan(s), keyexpr, "", z_move(channel.send), - &opts); // here, the send is moved and will be dropped by zenoh when adequate + z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); for (bool call_success = z_call(channel.recv, &reply); !call_success || z_check(reply); call_success = z_call(channel.recv, &reply)) { @@ -59,8 +59,9 @@ int main(int argc, char **argv) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_bytes_t payload = z_sample_payload(&sample); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_ping.c b/examples/z_ping.c index fdc08f71d..a5c0954d0 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -54,6 +54,7 @@ int main(int argc, char** argv) { for (int i = 0; i < args.size; i++) { data[i] = i % 10; } + zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = data, .len = args.size}); z_mutex_lock(&mutex); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); @@ -61,7 +62,7 @@ int main(int argc, char** argv) { unsigned long elapsed_us = 0; while (elapsed_us < args.warmup_ms * 1000) { - z_publisher_put(z_loan(pub), data, args.size, NULL); + z_publisher_put(z_loan(pub), z_move(payload), NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); @@ -72,7 +73,7 @@ int main(int argc, char** argv) { unsigned long* results = z_malloc(sizeof(unsigned long) * args.number_of_pings); for (int i = 0; i < args.number_of_pings; i++) { z_clock_t measure_start = z_clock_now(); - z_publisher_put(z_loan(pub), data, args.size, NULL); + z_publisher_put(z_loan(pub), z_move(payload), NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); diff --git a/examples/z_pong.c b/examples/z_pong.c index 4047ff3d2..772280696 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -6,10 +6,8 @@ void callback(const z_sample_t* sample, void* context) { z_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); #ifdef ZENOH_C // The zc_owned_payload_t API is exclusive to zenoh-c, but allows avoiding some copies. - z_owned_buffer_t payload = z_sample_owned_payload(sample); - zc_publisher_put_owned(pub, z_move(payload), NULL); -#else - z_publisher_put(pub, sample->payload.start, sample->payload.len, NULL); + zc_owned_payload_t payload = z_sample_owned_payload(sample); + z_publisher_put(pub, z_move(payload), NULL); #endif } void drop(void* context) { diff --git a/examples/z_pub.c b/examples/z_pub.c index ecc95e42d..9dd496153 100644 --- a/examples/z_pub.c +++ b/examples/z_pub.c @@ -71,7 +71,8 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_publisher_put(z_loan(pub), (const uint8_t *)buf, strlen(buf), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index a24133e91..530d9dc29 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -71,7 +71,8 @@ int main(int argc, char **argv) { sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_publisher_put(z_loan(pub), (const uint8_t *)buf, strlen(buf), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pub_cache.c b/examples/z_pub_cache.c index 770bf9d93..622896948 100644 --- a/examples/z_pub_cache.c +++ b/examples/z_pub_cache.c @@ -63,7 +63,8 @@ int main(int argc, char **argv) { z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)buf, strlen(buf), NULL); + zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } z_drop(z_move(pub_cache)); diff --git a/examples/z_pub_shm.c b/examples/z_pub_shm.c index 10970bf62..3c032e02f 100644 --- a/examples/z_pub_shm.c +++ b/examples/z_pub_shm.c @@ -84,7 +84,7 @@ int main(int argc, char **argv) { z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); zc_owned_payload_t payload = zc_shmbuf_into_payload(z_move(shmbuf)); - zc_publisher_put_owned(z_loan(pub), z_move(payload), &options); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pub_thr.c b/examples/z_pub_thr.c index 8686c33eb..e0568973c 100644 --- a/examples/z_pub_thr.c +++ b/examples/z_pub_thr.c @@ -54,7 +54,8 @@ int main(int argc, char **argv) { } while (1) { - z_publisher_put(z_loan(pub), (const uint8_t *)value, len, NULL); + zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = value, .len = len}); + z_publisher_put(z_loan(pub), z_move(payload), NULL); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pull.c b/examples/z_pull.c index 4f2de7945..c7daf1172 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -18,9 +18,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_bytes_t payload = z_sample_payload(sample); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } diff --git a/examples/z_put.c b/examples/z_put.c index 498d1e958..503fb5c36 100644 --- a/examples/z_put.c +++ b/examples/z_put.c @@ -48,7 +48,8 @@ int main(int argc, char **argv) { z_put_options_t options = z_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); options.attachment = z_bytes_map_as_attachment(&attachment); - int res = z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)value, strlen(value), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(value); + int res = z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), &options); if (res < 0) { printf("Put failed...\n"); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index d60bc2bf1..a5b2ec1f9 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -18,9 +18,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_bytes_t payload = z_sample_payload(sample); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 9d6ec7702..25d8a959d 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -22,10 +22,12 @@ z_keyexpr_t keyexpr; void query_handler(const z_query_t *query, void *context) { z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); z_bytes_t pred = z_query_parameters(query); - z_value_t payload_value = z_query_value(query); - if (payload_value.payload.len > 0) { - printf(">> [Queryable ] Received Query '%s?%.*s' with value '%.*s'\n", z_loan(keystr), (int)pred.len, - pred.start, (int)payload_value.payload.len, payload_value.payload.start); + zc_payload_t payload = z_query_value(query).payload; + if (zc_payload_len(payload) > 0) { + z_owned_str_t payload_string = zc_payload_decode_into_string(payload); + printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, + pred.start, z_loan(payload_string)); + z_drop(z_move(payload_string)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 672ddd607..dfef42532 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -68,10 +68,12 @@ int main(int argc, char **argv) { z_query_t query = z_loan(oquery); z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(&query)); z_bytes_t pred = z_query_parameters(&query); - z_value_t payload_value = z_query_value(&query); - if (payload_value.payload.len > 0) { - printf(">> [Queryable ] Received Query '%s?%.*s' with value '%.*s'\n", z_loan(keystr), (int)pred.len, - pred.start, (int)payload_value.payload.len, payload_value.payload.start); + zc_payload_t payload = z_query_value(&query).payload; + if (zc_payload_len(payload) > 0) { + z_owned_str_t payload_string = zc_payload_decode_into_string(payload); + printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, + pred.start, z_loan(payload_string)); + z_drop(z_move(payload_string)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } diff --git a/examples/z_sub.c b/examples/z_sub.c index 378a717e6..c7ea05c9a 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -18,9 +18,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_bytes_t payload = z_sample_payload(sample); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 2031d1155..b3be1f672 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -24,9 +24,8 @@ int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_bytes_t payload = z_sample_payload(sample); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload)); z_attachment_t attachment = z_sample_attachment(sample); // checks if attachment exists @@ -40,6 +39,7 @@ void data_handler(const z_sample_t *sample, void *arg) { printf(" message number: %.*s\n", (int)index.len, index.start); } } + z_drop(z_move(payload)); z_drop(z_move(keystr)); } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 55a52f82d..26c428c29 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -207,13 +207,9 @@ typedef struct z_attachment_t { * A split buffer that owns all of its data. * * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - * - * You can use `z_buffer_contiguous` to obtain a contiguous version of a buffer. - * If the buffer was already contiguous, the reference count will simply be increased. - * Otherwise, the split buffer's entire content will be copied in a newly allocated buffer. */ -typedef struct z_owned_buffer_t { - size_t _inner[5]; +typedef struct ALIGN(8) z_owned_buffer_t { + uint8_t _0[40]; } z_owned_buffer_t; /** * A loan of a `z_owned_buffer_t`. @@ -221,7 +217,7 @@ typedef struct z_owned_buffer_t { * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. */ typedef struct z_buffer_t { - const void *_inner; + struct z_owned_buffer_t *_inner; } z_buffer_t; /** * A map of maybe-owned vector of bytes to owned vector of bytes. @@ -617,7 +613,7 @@ typedef struct z_delete_options_t { * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. */ typedef struct z_encoding_t { - uint64_t prefix; + enum z_encoding_prefix_t prefix; struct z_bytes_t suffix; } z_encoding_t; /** @@ -634,7 +630,7 @@ typedef struct z_encoding_t { * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ typedef struct z_owned_encoding_t { - uint64_t prefix; + enum z_encoding_prefix_t prefix; struct z_bytes_t suffix; bool _dropped; } z_owned_encoding_t; @@ -645,16 +641,22 @@ typedef struct z_query_consolidation_t { enum z_consolidation_mode_t mode; } z_query_consolidation_t; /** - * A zenoh value. + * An owned payload, backed by a reference counted owner. + * + * The `payload` field may be modified, and Zenoh will take the new values into account. + */ +typedef struct z_owned_buffer_t zc_owned_payload_t; +/** + * An owned zenoh value. * * Members: - * z_bytes_t payload: The payload of this zenoh value. - * z_encoding_t encoding: The encoding of this zenoh value `payload`. + * zc_owned_payload_t payload: The payload of this zenoh value. + * z_owned_encoding_t encoding: The encoding of this zenoh value `payload`. */ -typedef struct z_value_t { - struct z_bytes_t payload; - struct z_encoding_t encoding; -} z_value_t; +typedef struct z_owned_value_t { + zc_owned_payload_t payload; + struct z_owned_encoding_t encoding; +} z_owned_value_t; /** * Options passed to the :c:func:`z_get` function. * @@ -668,7 +670,7 @@ typedef struct z_value_t { typedef struct z_get_options_t { enum z_query_target_t target; struct z_query_consolidation_t consolidation; - struct z_value_t value; + struct z_owned_value_t value; struct z_attachment_t attachment; uint64_t timeout_ms; } z_get_options_t; @@ -792,6 +794,18 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; +typedef struct z_buffer_t zc_payload_t; +/** + * A zenoh value. + * + * Members: + * zc_payload_t payload: The payload of this zenoh value. + * z_encoding_t encoding: The encoding of this zenoh value `payload`. + */ +typedef struct z_value_t { + zc_payload_t payload; + struct z_encoding_t encoding; +} z_value_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -877,30 +891,14 @@ typedef struct zc_owned_liveliness_token_t { typedef struct zc_liveliness_get_options_t { uint32_t timeout_ms; } zc_liveliness_get_options_t; -/** - * An owned payload, backed by a reference counted owner. - * - * The `payload` field may be modified, and Zenoh will take the new values into account, - * however, assuming `ostart` and `olen` are the respective values of `payload.start` and - * `payload.len` when constructing the `zc_owned_payload_t payload` value was created, - * then `payload.start` MUST remain within the `[ostart, ostart + olen[` interval, and - * `payload.len` must remain within `[0, olen -(payload.start - ostart)]`. - * - * Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` - * functions, then the operation will fail (but the passed value will still be consumed). - */ -typedef struct z_owned_buffer_t zc_owned_payload_t; /** * An owned sample. * * This is a read only type that can only be constructed by cloning a `z_sample_t`. * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. */ -typedef struct zc_owned_sample_t { - struct z_owned_keyexpr_t _0; - struct z_owned_buffer_t _1; - struct z_owned_buffer_t _2; - size_t _3[12]; +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[224]; } zc_owned_sample_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; @@ -1083,19 +1081,16 @@ ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); * Increments the buffer's reference count, returning an owned version of the buffer. */ ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); -/** - * Returns an owned version of this buffer whose data is guaranteed to be contiguous in memory. - * - * This is achieved by increasing the reference count if the buffer is already contiguous, and by copying its data in a new contiguous buffer if it wasn't. - */ -ZENOHC_API -struct z_owned_buffer_t z_buffer_contiguous(struct z_buffer_t buffer); /** * Decrements the buffer's reference counter, destroying it if applicable. * * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. */ ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +/** + * Returns total number bytes in the buffer. + */ +ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); /** * Loans the buffer, allowing you to call functions that only need a loan of it. */ @@ -1104,12 +1099,6 @@ ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer * The gravestone value for `z_owned_buffer_t`. */ ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); -/** - * Returns the payload of the buffer if it is contiguous, aliasling it. - * - * If the payload was not contiguous in memory, `z_bytes_null` will be returned instead. - */ -ZENOHC_API struct z_bytes_t z_buffer_payload(struct z_buffer_t buffer); /** * Returns the `index`th slice of the buffer, aliasing it. * @@ -1119,10 +1108,9 @@ ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t i /** * Returns the number of slices in the buffer. * - * If the return value is 0 or 1, then the buffer's data is contiguous in memory and `z_buffer_contiguous` will succeed. + * If the return value is 0 or 1, then the buffer's data is contiguous in memory. */ -ZENOHC_API -size_t z_buffer_slice_count(struct z_buffer_t buffer); +ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ @@ -1581,7 +1569,7 @@ int8_t z_get(struct z_session_t session, struct z_keyexpr_t keyexpr, const char *parameters, struct z_owned_closure_reply_t *callback, - const struct z_get_options_t *options); + struct z_get_options_t *options); ZENOHC_API struct z_get_options_t z_get_options_default(void); /** * Returns ``true`` if `hello` is valid. @@ -1819,22 +1807,24 @@ ZENOHC_API struct z_owned_publisher_t z_publisher_null(void); */ ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); /** - * Sends a `PUT` message onto the publisher's key expression. + * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` * * The payload's encoding can be sepcified through the options. * * Parameters: * session: The zenoh session. * payload: The value to put. - * len: The length of the value to put. * options: The publisher put options. * Returns: * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API int8_t z_publisher_put(struct z_publisher_t publisher, - const uint8_t *payload, - size_t len, + zc_owned_payload_t *payload, const struct z_publisher_put_options_t *options); /** * Constructs the default value for :c:type:`z_publisher_put_options_t`. @@ -1858,7 +1848,11 @@ ZENOHC_API struct z_owned_pull_subscriber_t z_pull_subscriber_null(void); */ ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default(void); /** - * Put data. + * Put data, transfering the buffer ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` * * The payload's encoding can be sepcified through the options. * @@ -1866,7 +1860,6 @@ ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default( * session: The zenoh session. * keyexpr: The key expression to put. * payload: The value to put. - * len: The length of the value to put. * options: The put options. * Returns: * ``0`` in case of success, negative values in case of failure. @@ -1874,8 +1867,7 @@ ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default( ZENOHC_API int8_t z_put(struct z_session_t session, struct z_keyexpr_t keyexpr, - const uint8_t *payload, - size_t len, + zc_owned_payload_t *payload, const struct z_put_options_t *opts); /** * Constructs the default value for :c:type:`z_put_options_t`. @@ -2133,7 +2125,7 @@ ZENOHC_API struct z_owned_buffer_t z_sample_owned_payload(const struct z_sample_ * * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ -ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API struct z_buffer_t z_sample_payload(const struct z_sample_t *sample); /** * The qos with which the sample was received. */ @@ -2280,6 +2272,10 @@ 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); +ZENOHC_API bool z_value_check(const struct z_owned_value_t *value); +ZENOHC_API void z_value_drop(struct z_owned_value_t *value); +ZENOHC_API struct z_value_t z_value_loan(const struct z_owned_value_t *value); +ZENOHC_API struct z_owned_value_t z_value_null(void); /** * Converts the kind of zenoh entity into a string. * @@ -2466,61 +2462,42 @@ ZENOHC_API void zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t * Returns `false` if `payload` is the gravestone value. */ ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); +/** + * Increments internal payload reference count, returning owned payload. + */ +ZENOHC_API zc_owned_payload_t zc_payload_clone(zc_payload_t payload); +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API struct z_owned_str_t zc_payload_decode_into_string(zc_payload_t payload); /** * Decrements `payload`'s backing refcount, releasing the memory if appropriate. */ ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); /** - * Constructs `zc_owned_payload_t`'s gravestone value. + * Encodes byte sequence by aliasing. */ -ZENOHC_API zc_owned_payload_t zc_payload_null(void); +ZENOHC_API zc_owned_payload_t zc_payload_encode_from_bytes(struct z_bytes_t bytes); /** - * Clones the `payload` by incrementing its reference counter. + * Encodes a null-terminated string by aliasing. */ -ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); +ZENOHC_API zc_owned_payload_t zc_payload_encode_from_string(const char *cstr); /** - * Sends a `PUT` message onto the publisher's key expression, transfering the buffer ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload's encoding can be sepcified through the options. - * - * Parameters: - * session: The zenoh session. - * payload: The value to put. - * len: The length of the value to put. - * options: The publisher put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. + * Returns total number bytes in the payload. */ -ZENOHC_API -int8_t zc_publisher_put_owned(struct z_publisher_t publisher, - zc_owned_payload_t *payload, - const struct z_publisher_put_options_t *options); +ZENOHC_API size_t zc_payload_len(zc_payload_t payload); /** - * Put data, transfering the buffer ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload's encoding can be sepcified through the options. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to put. - * payload: The value to put. - * options: The put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. + * Returns a :c:type:`zc_payload_t` loaned from `payload`. */ -ZENOHC_API -int8_t zc_put_owned(struct z_session_t session, - struct z_keyexpr_t keyexpr, - zc_owned_payload_t *payload, - const struct z_put_options_t *opts); +ZENOHC_API zc_payload_t zc_payload_loan(const zc_owned_payload_t *payload); +/** + * Constructs `zc_owned_payload_t`'s gravestone value. + */ +ZENOHC_API zc_owned_payload_t zc_payload_null(void); +/** + * Clones the `payload` by incrementing its reference counter. + */ +ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); /** * Creates a new blocking fifo channel, returned as a pair of closures. * diff --git a/src/collections.rs b/src/collections.rs index 89c0e0438..e0f2e7afe 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -13,12 +13,14 @@ // use libc::{c_char, size_t}; +use std::ops::Deref; +use std::ptr::NonNull; use zenoh::{ buffers::{buffer::SplitBuffer, ZBuf}, prelude::ZenohId, }; -use crate::impl_guarded_transmute; +use crate::{impl_guarded_transmute, GuardedTransmute}; /// A contiguous view of bytes owned by some other entity. /// @@ -162,17 +164,7 @@ impl From<&[u8]> for z_bytes_t { } } -/// A split buffer that owns all of its data. -/// -/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. -/// -/// You can use `z_buffer_contiguous` to obtain a contiguous version of a buffer. -/// If the buffer was already contiguous, the reference count will simply be increased. -/// Otherwise, the split buffer's entire content will be copied in a newly allocated buffer. -#[repr(C)] -pub struct z_owned_buffer_t { - _inner: [usize; 5], -} +pub use crate::z_owned_buffer_t; impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); impl Default for z_owned_buffer_t { fn default() -> Self { @@ -181,13 +173,10 @@ impl Default for z_owned_buffer_t { } impl From for z_owned_buffer_t { fn from(value: ZBuf) -> Self { - let value = match value.contiguous() { - std::borrow::Cow::Borrowed(_) => value, - std::borrow::Cow::Owned(value) => value.into(), - }; - unsafe { core::mem::transmute(Some(value)) } + Some(value).transmute() } } + impl From> for z_owned_buffer_t { fn from(value: Option) -> Self { match value { @@ -239,12 +228,18 @@ pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { /// /// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. #[repr(C)] -#[derive(Clone, Copy)] -pub struct z_buffer_t<'a> { - _inner: &'a (), +#[derive(Clone, Copy, Default)] +pub struct z_buffer_t { + _inner: Option>, } -impl_guarded_transmute!(Option<&'a ZBuf>, z_buffer_t<'a>, 'a); -impl<'a> From> for Option<&'a ZBuf> { + +impl From> for z_buffer_t { + fn from(value: Option<&ZBuf>) -> Self { + unsafe { core::mem::transmute(value) } + } +} + +impl From for Option<&'static ZBuf> { fn from(value: z_buffer_t) -> Self { unsafe { core::mem::transmute(value) } } @@ -253,45 +248,29 @@ impl<'a> From> for Option<&'a ZBuf> { /// Increments the buffer's reference count, returning an owned version of the buffer. #[no_mangle] pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { - unsafe { Some(core::mem::transmute::<_, &ZBuf>(buffer).clone()).into() } -} - -/// Returns the payload of the buffer if it is contiguous, aliasling it. -/// -/// If the payload was not contiguous in memory, `z_bytes_null` will be returned instead. -#[no_mangle] -pub extern "C" fn z_buffer_payload(buffer: z_buffer_t) -> z_bytes_t { - let Some(buffer): Option<&ZBuf> = buffer.into() else { - return z_bytes_null(); - }; - match buffer.contiguous() { - std::borrow::Cow::Borrowed(buffer) => buffer.into(), - std::borrow::Cow::Owned(_) => z_bytes_null(), + match buffer._inner { + Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, + None => ZBuf::empty().into(), } } -/// Returns an owned version of this buffer whose data is guaranteed to be contiguous in memory. +/// Returns the number of slices in the buffer. /// -/// This is achieved by increasing the reference count if the buffer is already contiguous, and by copying its data in a new contiguous buffer if it wasn't. +/// If the return value is 0 or 1, then the buffer's data is contiguous in memory. #[no_mangle] -pub extern "C" fn z_buffer_contiguous(buffer: z_buffer_t) -> z_owned_buffer_t { - let Some(buf): Option<&ZBuf> = buffer.into() else { - return z_buffer_null(); - }; - match buf.contiguous() { - std::borrow::Cow::Borrowed(_) => buf.clone().into(), - std::borrow::Cow::Owned(buf) => ZBuf::from(buf).into(), +pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).len(), } } -/// Returns the number of slices in the buffer. -/// -/// If the return value is 0 or 1, then the buffer's data is contiguous in memory and `z_buffer_contiguous` will succeed. +/// Returns total number bytes in the buffer. #[no_mangle] -pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { +pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { match buffer.into() { None => 0, - Some(buf) => ZBuf::slices(buf).len(), + Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), } } diff --git a/src/commons.rs b/src/commons.rs index d23618846..249333d66 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -12,7 +12,9 @@ // ZettaScale Zenoh team, // +use std::any::Any; use std::ops::Deref; +use std::slice; use crate::collections::*; use crate::keyexpr::*; @@ -22,8 +24,10 @@ use crate::z_priority_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; +use zenoh::buffers::buffer::SplitBuffer; +use zenoh::buffers::ZBuf; +use zenoh::buffers::ZSliceBuffer; use zenoh::prelude::SampleKind; -use zenoh::prelude::SplitBuffer; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::QoS; @@ -93,14 +97,7 @@ impl From> for z_timestamp_t { /// An owned payload, backed by a reference counted owner. /// -/// The `payload` field may be modified, and Zenoh will take the new values into account, -/// however, assuming `ostart` and `olen` are the respective values of `payload.start` and -/// `payload.len` when constructing the `zc_owned_payload_t payload` value was created, -/// then `payload.start` MUST remain within the `[ostart, ostart + olen[` interval, and -/// `payload.len` must remain within `[0, olen -(payload.start - ostart)]`. -/// -/// Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` -/// functions, then the operation will fail (but the passed value will still be consumed). +/// The `payload` field may be modified, and Zenoh will take the new values into account. #[allow(non_camel_case_types)] pub type zc_owned_payload_t = z_owned_buffer_t; @@ -125,6 +122,81 @@ pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { z_buffer_null() } +/// Returns a :c:type:`zc_payload_t` loaned from `payload`. +#[no_mangle] +pub extern "C" fn zc_payload_loan(payload: &zc_owned_payload_t) -> zc_payload_t { + z_buffer_loan(payload) +} + +#[allow(non_camel_case_types)] +pub type zc_payload_t = z_buffer_t; + +/// Increments internal payload reference count, returning owned payload. +#[no_mangle] +pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t { + z_buffer_clone(payload) +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t) -> z_owned_str_t { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + return z_str_null(); + } + let mut cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + cstr.insert_unchecked(pos, s); + pos += s.len(); + } + cstr +} + +unsafe impl Send for z_bytes_t {} +unsafe impl Sync for z_bytes_t {} + +impl ZSliceBuffer for z_bytes_t { + fn as_slice(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.start, self.len) } + } + fn as_mut_slice(&mut self) -> &mut [u8] { + unsafe { slice::from_raw_parts_mut(self.start as *mut u8, self.len) } + } + fn as_any(&self) -> &dyn Any { + self + } +} + +/// Encodes byte sequence by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_bytes(bytes: z_bytes_t) -> zc_owned_payload_t { + ZBuf::from(bytes).into() +} + +/// Encodes a null-terminated string by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_string( + cstr: *const libc::c_char, +) -> zc_owned_payload_t { + let bytes = z_bytes_t { + start: cstr as *const u8, + len: libc::strlen(cstr), + }; + zc_payload_encode_from_bytes(bytes) +} + +/// Returns total number bytes in the payload. +#[no_mangle] +pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { + z_buffer_len(payload) +} + /// QoS settings of zenoh message. /// #[repr(C)] @@ -191,8 +263,8 @@ pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { /// /// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { - sample.payload.slices().next().unwrap_or(b"").into() +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_buffer_t { + Some(&sample.payload).into() } /// Returns the sample's payload after incrementing its internal reference count. /// @@ -231,18 +303,7 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } } -/// An owned sample. -/// -/// This is a read only type that can only be constructed by cloning a `z_sample_t`. -/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -#[repr(C)] -pub struct zc_owned_sample_t { - _0: z_owned_keyexpr_t, - _1: z_owned_buffer_t, - _2: z_owned_buffer_t, - _3: [usize; 12], -} - +pub use crate::zc_owned_sample_t; impl_guarded_transmute!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. @@ -422,24 +483,21 @@ impl From for z_encoding_prefix_t { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct z_encoding_t { - pub prefix: u64, + pub prefix: z_encoding_prefix_t, pub suffix: z_bytes_t, } impl From for zenoh_protocol::core::Encoding { fn from(enc: z_encoding_t) -> Self { if enc.suffix.len == 0 { - zenoh_protocol::core::Encoding::Exact((enc.prefix as u8).try_into().unwrap()) + zenoh_protocol::core::Encoding::Exact(enc.prefix.into()) } else { let suffix = unsafe { let slice: &'static [u8] = std::slice::from_raw_parts(enc.suffix.start, enc.suffix.len); std::str::from_utf8_unchecked(slice) }; - zenoh_protocol::core::Encoding::WithSuffix( - (enc.prefix as u8).try_into().unwrap(), - suffix.into(), - ) + zenoh_protocol::core::Encoding::WithSuffix(enc.prefix.into(), suffix.into()) } } } @@ -448,7 +506,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { fn from(val: &zenoh_protocol::core::Encoding) -> Self { let suffix = val.suffix(); z_encoding_t { - prefix: u8::from(*val.prefix()) as u64, + prefix: (*val.prefix()).into(), suffix: z_bytes_t { start: suffix.as_ptr(), len: suffix.len(), @@ -470,7 +528,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. #[repr(C)] pub struct z_owned_encoding_t { - pub prefix: u64, + pub prefix: z_encoding_prefix_t, pub suffix: z_bytes_t, pub _dropped: bool, } @@ -478,7 +536,7 @@ pub struct z_owned_encoding_t { impl z_owned_encoding_t { pub fn null() -> Self { z_owned_encoding_t { - prefix: 0, + prefix: z_encoding_prefix_t::Empty, suffix: z_bytes_t::default(), _dropped: true, } @@ -506,10 +564,7 @@ pub unsafe extern "C" fn z_encoding( len: libc::strlen(suffix), } }; - z_encoding_t { - prefix: prefix as u64, - suffix, - } + z_encoding_t { prefix, suffix } } /// Constructs a default :c:type:`z_encoding_t`. @@ -562,13 +617,30 @@ pub struct z_owned_str_t { pub _cstr: *mut libc::c_char, } +impl z_owned_str_t { + #[allow(clippy::missing_safety_doc)] + pub unsafe fn preallocate(len: usize) -> z_owned_str_t { + let cstr = libc::malloc(len + 1) as *mut libc::c_char; + *cstr.add(len) = 0; + z_owned_str_t { _cstr: cstr } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { + std::ptr::copy_nonoverlapping( + value.as_ptr(), + (self._cstr as *mut u8).add(start), + value.len(), + ); + } +} + impl From<&[u8]> for z_owned_str_t { fn from(value: &[u8]) -> Self { unsafe { - let cstr = libc::malloc(value.len() + 1) as *mut libc::c_char; - std::ptr::copy_nonoverlapping(value.as_ptr(), cstr as _, value.len()); - *cstr.add(value.len()) = 0; - z_owned_str_t { _cstr: cstr } + let mut cstr = Self::preallocate(value.len()); + cstr.insert_unchecked(0, value); + cstr } } } diff --git a/src/get.rs b/src/get.rs index bc37d7039..17ed9ccbe 100644 --- a/src/get.rs +++ b/src/get.rs @@ -15,14 +15,14 @@ use libc::c_char; use libc::c_void; use std::{ - borrow::Cow, convert::TryFrom, ffi::CStr, ops::{Deref, DerefMut}, }; +use zenoh::buffers::ZBuf; use zenoh::{ - prelude::{ConsolidationMode, KeyExpr, QueryTarget, SplitBuffer}, + prelude::{ConsolidationMode, KeyExpr, QueryTarget}, query::{Mode, QueryConsolidation, Reply}, sample::AttachmentBuilder, value::Value, @@ -33,10 +33,20 @@ use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, z_attachment_t, }; +use crate::z_encoding_check; +use crate::z_encoding_drop; +use crate::z_encoding_loan; +use crate::z_encoding_null; +use crate::z_owned_encoding_t; +use crate::zc_owned_payload_t; +use crate::zc_payload_check; +use crate::zc_payload_drop; +use crate::zc_payload_loan; +use crate::zc_payload_null; +use crate::zc_payload_t; use crate::{ - impl_guarded_transmute, z_bytes_t, z_closure_reply_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_reply_t, z_sample_t, z_session_t, GuardedTransmute, - LOG_INVALID_SESSION, + impl_guarded_transmute, z_closure_reply_call, z_encoding_t, z_keyexpr_t, + z_owned_closure_reply_t, z_sample_t, z_session_t, GuardedTransmute, LOG_INVALID_SESSION, }; type ReplyInner = Option; @@ -59,13 +69,7 @@ pub struct z_owned_reply_t([u64; 19]); impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); impl From for z_owned_reply_t { - fn from(mut val: ReplyInner) -> Self { - if let Some(val) = &mut val { - match &mut val.sample { - Ok(inner) => inner.payload = inner.payload.contiguous().into_owned().into(), - Err(inner) => inner.payload = inner.payload.contiguous().into_owned().into(), - }; - } + fn from(val: ReplyInner) -> Self { val.transmute() } } @@ -101,9 +105,6 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { if let Some(sample) = reply.as_ref().and_then(|s| s.sample.as_ref().ok()) { - if let Cow::Owned(_) = sample.payload.contiguous() { - unreachable!("z_reply_ok found a payload that wasn't contiguous by the time it was reached, which breaks some crate assertions. This is definitely a bug with zenoh, please contact us.") - } z_sample_t::new(sample) } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Ok despite that not being the case") @@ -113,14 +114,53 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { /// A zenoh value. /// /// Members: -/// z_bytes_t payload: The payload of this zenoh value. +/// zc_payload_t payload: The payload of this zenoh value. /// z_encoding_t encoding: The encoding of this zenoh value `payload`. #[repr(C)] pub struct z_value_t { - pub payload: z_bytes_t, + pub payload: zc_payload_t, pub encoding: z_encoding_t, } +/// An owned zenoh value. +/// +/// Members: +/// zc_owned_payload_t payload: The payload of this zenoh value. +/// z_owned_encoding_t encoding: The encoding of this zenoh value `payload`. +#[repr(C)] +pub struct z_owned_value_t { + pub payload: zc_owned_payload_t, + pub encoding: z_owned_encoding_t, +} + +#[no_mangle] +pub extern "C" fn z_value_null() -> z_owned_value_t { + z_owned_value_t { + payload: zc_payload_null(), + encoding: z_encoding_null(), + } +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_value_drop(value: &mut z_owned_value_t) { + z_encoding_drop(&mut value.encoding); + zc_payload_drop(&mut value.payload); +} + +#[no_mangle] +pub extern "C" fn z_value_loan(value: &z_owned_value_t) -> z_value_t { + z_value_t { + payload: zc_payload_loan(&value.payload), + encoding: z_encoding_loan(&value.encoding), + } +} + +#[no_mangle] +pub extern "C" fn z_value_check(value: &z_owned_value_t) -> bool { + zc_payload_check(&value.payload) && z_encoding_check(&value.encoding) +} + /// Yields the contents of the reply by asserting it indicates a failure. /// /// You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. @@ -129,10 +169,7 @@ pub struct z_value_t { pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { if let Some(inner) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { z_value_t { - payload: match &inner.payload.contiguous() { - Cow::Borrowed(payload) => crate::z_bytes_t { start: payload.as_ptr(), len: payload.len() }, - Cow::Owned(_) => unreachable!("z_reply_err found a payload that wasn't contiguous by the time it was reached, which breaks some crate assertions."), - }, + payload: Some(&inner.payload).into(), encoding: (&inner.encoding).into(), } } else { @@ -165,7 +202,7 @@ pub extern "C" fn z_reply_null() -> z_owned_reply_t { pub struct z_get_options_t { pub target: z_query_target_t, pub consolidation: z_query_consolidation_t, - pub value: z_value_t, + pub value: z_owned_value_t, pub attachment: z_attachment_t, pub timeout_ms: u64, } @@ -175,12 +212,7 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { target: QueryTarget::default().into(), consolidation: QueryConsolidation::default().into(), timeout_ms: 0, - value: { - z_value_t { - payload: z_bytes_t::empty(), - encoding: z_encoding_default(), - } - }, + value: z_value_null(), attachment: z_attachment_null(), } } @@ -206,7 +238,7 @@ pub unsafe extern "C" fn z_get( keyexpr: z_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, - options: Option<&z_get_options_t>, + options: Option<&mut z_get_options_t>, ) -> i8 { let mut closure = z_owned_closure_reply_t::empty(); std::mem::swap(callback, &mut closure); @@ -223,8 +255,25 @@ pub unsafe extern "C" fn z_get( if let Some(options) = options { q = q .consolidation(options.consolidation) - .target(options.target.into()) - .with_value(&options.value); + .target(options.target.into()); + + if let Some(payload) = options.value.payload.take() { + let mut value = Value::new(payload); + if z_encoding_check(&options.value.encoding) { + value = value.encoding(z_encoding_loan(&options.value.encoding).into()); + } + q = q.with_value(value); + } + z_encoding_drop(&mut options.value.encoding); + if zc_payload_check(&options.value.payload) { + let buf: ZBuf = options.value.payload.as_ref().unwrap().clone(); + let mut value = Value::new(buf); + if z_encoding_check(&options.value.encoding) { + value = value.encoding(z_encoding_loan(&options.value.encoding).into()); + } + q = q.with_value(value); + z_value_drop(&mut options.value); + } if options.timeout_ms != 0 { q = q.timeout(std::time::Duration::from_millis(options.timeout_ms)); } @@ -302,30 +351,29 @@ impl From for QueryTarget { impl From<&z_value_t> for Value { #[inline] fn from(val: &z_value_t) -> Value { - unsafe { - let value: Value = - std::slice::from_raw_parts(val.payload.start, val.payload.len).into(); - let encoding = std::str::from_utf8(std::slice::from_raw_parts( + let payload: Option<&ZBuf> = val.payload.into(); + let payload = match payload { + Some(b) => b.clone(), + None => ZBuf::empty(), + }; + let encoding = unsafe { + std::str::from_utf8(std::slice::from_raw_parts( val.encoding.suffix.start, val.encoding.suffix.len, )) - .expect("encodings must be UTF8"); - value.encoding( - zenoh::prelude::Encoding::new(val.encoding.prefix as u8, encoding).unwrap(), - ) - } + .expect("encodings must be UTF8") + }; + let v = Value::new(payload); + v.encoding(zenoh::prelude::Encoding::new(val.encoding.prefix as u8, encoding).unwrap()) } } impl From<&Value> for z_value_t { #[inline] fn from(val: &Value) -> z_value_t { - let std::borrow::Cow::Borrowed(payload) = val.payload.contiguous() else { - panic!("Would have returned a reference to a temporary, make sure you the Value's payload is contiguous BEFORE calling this constructor.") - }; z_value_t { encoding: (&val.encoding).into(), - payload: payload.into(), + payload: Some(&val.payload).into(), } } } diff --git a/src/lib.rs b/src/lib.rs index 5019a0713..96cc4bd76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,6 +55,8 @@ pub use querying_subscriber::*; pub mod attachment; pub use platform::*; pub mod platform; +pub use opaque_types::*; +pub mod opaque_types; #[cfg(feature = "shared-memory")] mod shm; diff --git a/src/liveliness.rs b/src/liveliness.rs index d66508cd5..b3c61a7de 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -14,7 +14,7 @@ use zenoh::{ liveliness::{Liveliness, LivelinessToken}, - prelude::{SessionDeclarations, SplitBuffer}, + prelude::SessionDeclarations, }; use zenoh_util::core::{zresult::ErrNo, SyncResolve}; @@ -176,10 +176,7 @@ pub extern "C" fn zc_liveliness_declare_subscriber( match session .liveliness() .declare_subscriber(key) - .callback(move |mut sample| { - if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { - sample.payload = v.into(); - } + .callback(move |sample| { let sample = z_sample_t::new(&sample); z_closure_sample_call(&callback, &sample) }) diff --git a/src/opaque_types/mod.rs b/src/opaque_types/mod.rs new file mode 100644 index 000000000..0327b0943 --- /dev/null +++ b/src/opaque_types/mod.rs @@ -0,0 +1,15 @@ +/// A split buffer that owns all of its data. +/// +/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. +#[repr(C, align(8))] +pub struct z_owned_buffer_t { + _0: [u8; 40] +} +/// An owned sample. +/// +/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. +#[repr(C, align(8))] +pub struct zc_owned_sample_t { + _0: [u8; 224] +} diff --git a/src/publisher.rs b/src/publisher.rs index f49d8cd31..6647655bd 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -234,14 +234,17 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t } } -/// Sends a `PUT` message onto the publisher's key expression. +/// Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. +/// +/// This is avoids copies when transfering data that was either: +/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher +/// - constructed from a `zc_owned_shmbuf_t` /// /// The payload's encoding can be sepcified through the options. /// /// Parameters: /// session: The zenoh session. /// payload: The value to put. -/// len: The length of the value to put. /// options: The publisher put options. /// Returns: /// ``0`` in case of success, negative values in case of failure. @@ -249,12 +252,15 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_publisher_put( publisher: z_publisher_t, - payload: *const u8, - len: usize, + payload: Option<&mut zc_owned_payload_t>, options: Option<&z_publisher_put_options_t>, ) -> i8 { if let Some(p) = publisher.as_ref() { - let value: Value = std::slice::from_raw_parts(payload, len).into(); + let Some(payload) = payload.and_then(|p| p.take()) else { + log::debug!("Attempted to put without a payload"); + return i8::MIN; + }; + let value: Value = payload.into(); let put = match options { Some(options) => { let mut put = p.put(value.encoding(options.encoding.into())); @@ -282,49 +288,6 @@ pub unsafe extern "C" fn z_publisher_put( } } -/// Sends a `PUT` message onto the publisher's key expression, transfering the buffer ownership. -/// -/// This is avoids copies when transfering data that was either: -/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher -/// - constructed from a `zc_owned_shmbuf_t` -/// -/// The payload's encoding can be sepcified through the options. -/// -/// Parameters: -/// session: The zenoh session. -/// payload: The value to put. -/// len: The length of the value to put. -/// options: The publisher put options. -/// Returns: -/// ``0`` in case of success, negative values in case of failure. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_publisher_put_owned( - publisher: z_publisher_t, - payload: Option<&mut zc_owned_payload_t>, - options: Option<&z_publisher_put_options_t>, -) -> i8 { - if let Some(p) = publisher.as_ref() { - let Some(payload) = payload.and_then(|p| p.take()) else { - log::debug!("Attempted to put without a payload"); - return i8::MIN; - }; - let value: Value = payload.into(); - let put = match options { - Some(options) => p.put(value.encoding(options.encoding.into())), - None => p.put(value), - }; - if let Err(e) = put.res_sync() { - log::error!("{}", e); - e.errno().get() - } else { - 0 - } - } else { - i8::MIN - } -} - /// Represents the set of options that can be applied to the delete operation by a previously declared publisher, /// whenever issued via :c:func:`z_publisher_delete`. #[repr(C)] diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index 247484cb1..ebef7064b 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -22,7 +22,6 @@ use crate::z_reliability_t; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::SplitBuffer; use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; @@ -149,10 +148,7 @@ pub extern "C" fn z_declare_pull_subscriber( Some(s) => { let mut res = s .declare_subscriber(keyexpr) - .callback(move |mut sample| { - if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { - sample.payload = v.into(); - } + .callback(move |sample| { let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) diff --git a/src/put.rs b/src/put.rs index b5d9f2f94..5c8b8d807 100644 --- a/src/put.rs +++ b/src/put.rs @@ -16,7 +16,6 @@ use crate::keyexpr::*; use crate::session::*; use crate::LOG_INVALID_SESSION; use libc::c_void; -use libc::size_t; use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; use zenoh::publication::CongestionControl; use zenoh::sample::AttachmentBuilder; @@ -135,62 +134,6 @@ pub extern "C" fn z_put_options_default() -> z_put_options_t { } } -/// Put data. -/// -/// The payload's encoding can be sepcified through the options. -/// -/// Parameters: -/// session: The zenoh session. -/// keyexpr: The key expression to put. -/// payload: The value to put. -/// len: The length of the value to put. -/// options: The put options. -/// Returns: -/// ``0`` in case of success, negative values in case of failure. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_put( - session: z_session_t, - keyexpr: z_keyexpr_t, - payload: *const u8, - len: size_t, - opts: Option<&z_put_options_t>, -) -> i8 { - match session.upgrade() { - Some(s) => { - let mut res = s - .put(keyexpr, std::slice::from_raw_parts(payload, len)) - .kind(SampleKind::Put); - if let Some(opts) = opts { - res = res - .encoding(opts.encoding) - .congestion_control(opts.congestion_control.into()) - .priority(opts.priority.into()); - if z_attachment_check(&opts.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - opts.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - res = res.with_attachment(attachment_builder.build()); - }; - } - match res.res_sync() { - Err(e) => { - log::error!("{}", e); - e.errno().get() - } - Ok(()) => 0, - } - } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - i8::MIN - } - } -} - /// Put data, transfering the buffer ownership. /// /// This is avoids copies when transfering data that was either: @@ -208,7 +151,7 @@ pub unsafe extern "C" fn z_put( /// ``0`` in case of success, negative values in case of failure. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn zc_put_owned( +pub extern "C" fn z_put( session: z_session_t, keyexpr: z_keyexpr_t, payload: Option<&mut zc_owned_payload_t>, @@ -223,6 +166,15 @@ pub extern "C" fn zc_put_owned( .encoding(opts.encoding) .congestion_control(opts.congestion_control.into()) .priority(opts.priority.into()); + if z_attachment_check(&opts.attachment) { + let mut attachment_builder = AttachmentBuilder::new(); + z_attachment_iterate( + opts.attachment, + insert_in_attachment_builder, + &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, + ); + res = res.with_attachment(attachment_builder.build()); + }; } match res.res_sync() { Err(e) => { diff --git a/src/queryable.rs b/src/queryable.rs index 1906dc735..f5b647473 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -16,17 +16,17 @@ use crate::attachment::{ z_attachment_iterate, z_attachment_null, z_attachment_t, }; use crate::{ - impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, LOG_INVALID_SESSION, + impl_guarded_transmute, z_buffer_t, z_bytes_t, z_closure_query_call, z_encoding_default, + z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, + LOG_INVALID_SESSION, }; use libc::c_void; use std::ops::{Deref, DerefMut}; use zenoh::prelude::SessionDeclarations; use zenoh::{ - prelude::{Sample, SplitBuffer}, + prelude::Sample, queryable::{Query, Queryable as CallbackQueryable}, sample::AttachmentBuilder, - value::Value, }; use zenoh_util::core::{zresult::ErrNo, SyncResolve}; @@ -346,14 +346,15 @@ pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_bytes_t { #[no_mangle] pub unsafe extern "C" fn z_query_value(query: &z_query_t) -> z_value_t { match query.as_ref().and_then(|q| q.value()) { - Some(value) => { + Some(value) => + { #[allow(mutable_transmutes)] - if let std::borrow::Cow::Owned(payload) = value.payload.contiguous() { - unsafe { std::mem::transmute::<_, &mut Value>(value).payload = payload.into() } - } value.into() } - None => (&Value::empty()).into(), + None => z_value_t { + payload: z_buffer_t::default(), + encoding: z_encoding_default(), + }, } } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index a4681b4e9..910f1b89b 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -15,7 +15,6 @@ use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::SplitBuffer; use zenoh_ext::*; use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; @@ -185,10 +184,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( } } match sub - .callback(move |mut sample| { - if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { - sample.payload = v.into(); - } + .callback(move |sample| { let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) diff --git a/src/subscriber.rs b/src/subscriber.rs index 7d15e740a..d82086f7f 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -21,7 +21,6 @@ use crate::z_owned_closure_sample_t; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::SplitBuffer; use zenoh::subscriber::Reliability; use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; @@ -179,10 +178,7 @@ pub extern "C" fn z_declare_subscriber( match session.upgrade() { Some(s) => { - let mut res = s.declare_subscriber(keyexpr).callback(move |mut sample| { - if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { - sample.payload = v.into(); - } + let mut res = s.declare_subscriber(keyexpr).callback(move |sample| { let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }); diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 9ade440f3..49827e148 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -260,7 +260,8 @@ int main(int argc, char **argv) { z_encoding_t _ret_encoding = z_encoding_default(); _ret_encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); _ret_put_opt.encoding = _ret_encoding; - _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), (const uint8_t *)value, strlen(value), &_ret_put_opt); + zc_owned_payload_t payload = zc_payload_encode_from_string(value); + _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), z_move(payload), &_ret_put_opt); assert(_ret_int8 == 0); z_sleep_s(SLEEP); @@ -292,7 +293,8 @@ int main(int argc, char **argv) { assert(z_check(_ret_pub)); z_publisher_put_options_t _ret_pput_opt = z_publisher_put_options_default(); - _ret_int8 = z_publisher_put(z_loan(_ret_pub), (const uint8_t *)value, strlen(value), &_ret_pput_opt); + payload = zc_payload_encode_from_string(value); + _ret_int8 = z_publisher_put(z_loan(_ret_pub), z_move(payload), &_ret_pput_opt); assert(_ret_int8 == 0); z_sleep_s(SLEEP); diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 868b3878e..789a00ffc 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -61,7 +61,8 @@ int run_publisher() { // values for cache for (int i = 0; i < values_count / 2; ++i) { - z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)values[i], strlen(values[i]), NULL); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } SEM_POST(sem_pub); @@ -70,7 +71,8 @@ int run_publisher() { // values for subscribe for (int i = values_count / 2; i < values_count; ++i) { - z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)values[i], strlen(values[i]), NULL); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } printf("wait: sem_sub\n"); @@ -91,8 +93,13 @@ void data_handler(const z_sample_t *sample, void *arg) { exit(-1); } z_drop(z_move(keystr)); - - ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(sample)); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + if (strcmp(values[val_num], z_loan(payload))) { + perror("Unexpected value received"); + z_drop(z_move(payload)); + exit(-1); + } + z_drop(z_move(payload)); printf("data_handler: %i\n", val_num); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index bafdd87ca..a665ad19b 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -55,7 +55,8 @@ int run_publisher() { options.attachment = z_bytes_map_as_attachment(&map); for (int i = 0; i < values_count; ++i) { z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_VAR), z_bytes_from_str(values[i])); - z_publisher_put(z_loan(pub), (const uint8_t *)values[i], strlen(values[i]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); @@ -73,11 +74,13 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); - z_bytes_t payload = z_sample_payload(sample); - if (strncmp(values[val_num], (const char *)payload.start, (int)payload.len)) { + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + if (strcmp(values[val_num], z_loan(payload))) { perror("Unexpected value received"); + z_drop(z_move(payload)); exit(-1); } + z_drop(z_move(payload)); z_bytes_t v_const = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index 6e48fef5a..06d5c87ba 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -49,7 +49,8 @@ int run_publisher() { for (int i = 0; i < values_count; ++i) { z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_publisher_put(z_loan(pub), (const uint8_t *)values[i], strlen(values[i]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); @@ -66,11 +67,13 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); - z_bytes_t payload = z_sample_payload(sample); - if (strncmp(values[val_num], (const char *)payload.start, (int)payload.len)) { + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + if (strcmp(values[val_num], z_loan(payload))) { perror("Unexpected value received"); + z_drop(z_move(payload)); exit(-1); } + z_drop(z_move(payload)); if (z_qos_get_congestion_control(z_sample_qos(sample)) != Z_CONGESTION_CONTROL_BLOCK || z_qos_get_priority(z_sample_qos(sample)) != Z_PRIORITY_DATA) { diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 1de9de788..deb28658e 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -110,13 +110,18 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - - ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(&sample)); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); + if (strcmp(values[val_num], z_loan(payload))) { + perror("Unexpected value received"); + z_drop(z_move(payload)); + exit(-1); + } z_bytes_t v_const = z_attachment_get(z_sample_attachment(&sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); + z_drop(z_move(payload)); } z_drop(z_move(reply)); z_drop(z_move(channel)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 9bcc16cc1..dc587e292 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -86,10 +86,15 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - - ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(&sample)); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); + if (strcmp(values[val_num], z_loan(payload))) { + perror("Unexpected value received"); + z_drop(z_move(payload)); + exit(-1); + } z_drop(z_move(keystr)); + z_drop(z_move(payload)); } z_drop(z_move(reply)); z_drop(z_move(channel)); From ed3a164b56b0e55fc17d0826c3aa12bdaf89450e Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 3 Apr 2024 22:49:47 +0200 Subject: [PATCH 012/377] reply with owned payload --- examples/z_queryable.c | 3 +- examples/z_queryable_with_channels.c | 3 +- include/zenoh_commons.h | 4 +-- src/queryable.rs | 48 ++++++++++++------------- tests/z_api_alignment_test.c | 3 +- tests/z_int_queryable_attachment_test.c | 4 +-- tests/z_int_queryable_test.c | 4 +-- 7 files changed, 33 insertions(+), 36 deletions(-) diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 25d8a959d..5c4ef6dfb 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -33,7 +33,8 @@ void query_handler(const z_query_t *query, void *context) { } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_query_reply(query, z_keyexpr((const char *)context), (const unsigned char *)value, strlen(value), &options); + zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_query_reply(query, z_keyexpr((const char *)context), z_move(reply_payload), &options); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index dfef42532..e68577d2e 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -79,7 +79,8 @@ int main(int argc, char **argv) { } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_query_reply(&query, keyexpr, (const unsigned char *)value, strlen(value), &options); + zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_query_reply(&query, keyexpr, z_move(reply_payload), &options); z_drop(z_move(keystr)); z_drop(z_move(oquery)); } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 26c428c29..a24a9c0b4 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1994,14 +1994,12 @@ struct z_bytes_t z_query_parameters(const struct z_query_t *query); * query: The query to reply to. * key: The key of this reply. * payload: The value of this reply. - * len: The length of the value of this reply. * options: The options of this reply. */ ZENOHC_API int8_t z_query_reply(const struct z_query_t *query, struct z_keyexpr_t key, - const uint8_t *payload, - size_t len, + zc_owned_payload_t *payload, const struct z_query_reply_options_t *options); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. diff --git a/src/queryable.rs b/src/queryable.rs index f5b647473..c55820227 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -17,7 +17,7 @@ use crate::attachment::{ }; use crate::{ impl_guarded_transmute, z_buffer_t, z_bytes_t, z_closure_query_call, z_encoding_default, - z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, + z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, LOG_INVALID_SESSION, }; use libc::c_void; @@ -273,15 +273,13 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { /// query: The query to reply to. /// key: The key of this reply. /// payload: The value of this reply. -/// len: The length of the value of this reply. /// options: The options of this reply. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_reply( query: &z_query_t, key: z_keyexpr_t, - payload: *const u8, - len: usize, + payload: Option<&mut zc_owned_payload_t>, options: Option<&z_query_reply_options_t>, ) -> i8 { let Some(query) = query.as_ref() else { @@ -289,30 +287,28 @@ pub unsafe extern "C" fn z_query_reply( return i8::MIN; }; if let Some(key) = &*key { - let mut s = Sample::new( - key.clone().into_owned(), - std::slice::from_raw_parts(payload, len), - ); - if let Some(o) = options { - s.encoding = o.encoding.into(); - if z_attachment_check(&o.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - o.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - s = s.with_attachment(attachment_builder.build()); - }; + if let Some(payload) = payload.and_then(|p| p.take()) { + let mut s = Sample::new(key.clone().into_owned(), payload); + if let Some(o) = options { + s.encoding = o.encoding.into(); + if z_attachment_check(&o.attachment) { + let mut attachment_builder = AttachmentBuilder::new(); + z_attachment_iterate( + o.attachment, + insert_in_attachment_builder, + &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, + ); + s = s.with_attachment(attachment_builder.build()); + }; + } + if let Err(e) = query.reply(Ok(s)).res_sync() { + log::error!("{}", e); + return e.errno().get(); + } + return 0; } - if let Err(e) = query.reply(Ok(s)).res_sync() { - log::error!("{}", e); - return e.errno().get(); - } - 0 - } else { - i8::MIN } + i8::MIN } /// Get a query's key by aliasing it. diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 49827e148..e7b72ef96 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -56,7 +56,8 @@ void query_handler(const z_query_t *query, void *arg) { z_value_t payload_value = z_query_value(query); (void)(payload_value); z_query_reply_options_t _ret_qreply_opt = z_query_reply_options_default(); - z_query_reply(query, z_keyexpr(z_loan(k_str)), (const uint8_t *)value, strlen(value), &_ret_qreply_opt); + zc_owned_payload_t payload = zc_payload_encode_from_string(value); + z_query_reply(query, z_keyexpr(z_loan(k_str)), z_move(payload), &_ret_qreply_opt); z_drop(z_move(k_str)); } diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index deb28658e..26645ad29 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -50,8 +50,8 @@ void query_handler(const z_query_t *query, void *context) { z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); options.attachment = z_bytes_map_as_attachment(&map); - z_query_reply(query, z_keyexpr((const char *)context), (const uint8_t *)values[value_num], - strlen(values[value_num]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); z_drop(z_move(map)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index dc587e292..7cc7f3bfc 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -34,8 +34,8 @@ void query_handler(const z_query_t *query, void *context) { z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_query_reply(query, z_keyexpr((const char *)context), (const uint8_t *)values[value_num], - strlen(values[value_num]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); if (++value_num == values_count) { From 6d005bb1e86eebc48a2f5eab187c448345d103eb Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 4 Apr 2024 23:38:42 +0200 Subject: [PATCH 013/377] modified payload decoding functions to return error and take value by pointer --- examples/z_get.c | 9 ++- examples/z_non_blocking_get.c | 7 +- examples/z_pull.c | 7 +- examples/z_query_sub.c | 7 +- examples/z_queryable.c | 8 +- examples/z_queryable_with_channels.c | 7 +- examples/z_sub.c | 7 +- examples/z_sub_attachment.c | 10 ++- include/zenoh_commons.h | 52 +++++++------ include/zenoh_macros.h | 4 +- src/attachment.rs | 10 +-- src/collections.rs | 99 ++++++++++++++++++++++--- src/commons.rs | 40 ++++++++-- src/get.rs | 70 ++--------------- tests/z_int_pub_cache_query_sub_test.c | 9 ++- tests/z_int_pub_sub_attachment_test.c | 9 ++- tests/z_int_pub_sub_test.c | 9 ++- tests/z_int_queryable_attachment_test.c | 9 ++- tests/z_int_queryable_test.c | 9 ++- 19 files changed, 223 insertions(+), 159 deletions(-) diff --git a/examples/z_get.c b/examples/z_get.c index e5a1de104..9866212f7 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -57,18 +57,19 @@ int main(int argc, char **argv) { z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get_options_t opts = z_get_options_default(); if (value != NULL) { - opts.value.payload = zc_payload_encode_from_string(value); + opts.payload = zc_payload_encode_from_string(value); } z_get(z_loan(s), keyexpr, "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); + z_owned_str_t payload_value = z_str_null(); for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); - printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload)); - z_drop(z_move(payload)); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index 21437199c..471f7e227 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) { z_get(z_loan(s), keyexpr, "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); + z_owned_str_t payload_value = z_str_null(); for (bool call_success = z_call(channel.recv, &reply); !call_success || z_check(reply); call_success = z_call(channel.recv, &reply)) { if (!call_success) { @@ -59,9 +60,9 @@ int main(int argc, char **argv) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); - printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload)); - z_drop(z_move(payload)); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_pull.c b/examples/z_pull.c index c7daf1172..094dc0a6b 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -18,10 +18,11 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload)); - z_drop(z_move(payload)); + z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index a5b2ec1f9..620dd9594 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -18,10 +18,11 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload)); - z_drop(z_move(payload)); + z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 5c4ef6dfb..577ef146e 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -24,15 +24,17 @@ void query_handler(const z_query_t *query, void *context) { z_bytes_t pred = z_query_parameters(query); zc_payload_t payload = z_query_value(query).payload; if (zc_payload_len(payload) > 0) { - z_owned_str_t payload_string = zc_payload_decode_into_string(payload); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(payload, &payload_value); printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, - pred.start, z_loan(payload_string)); - z_drop(z_move(payload_string)); + pred.start, z_loan(payload_value)); + z_drop(z_move(payload_value)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); + zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); z_query_reply(query, z_keyexpr((const char *)context), z_move(reply_payload), &options); z_drop(z_move(keystr)); diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index e68577d2e..6c3ca0df1 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -70,10 +70,11 @@ int main(int argc, char **argv) { z_bytes_t pred = z_query_parameters(&query); zc_payload_t payload = z_query_value(&query).payload; if (zc_payload_len(payload) > 0) { - z_owned_str_t payload_string = zc_payload_decode_into_string(payload); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(payload, &payload_value); printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, - pred.start, z_loan(payload_string)); - z_drop(z_move(payload_string)); + pred.start, z_loan(payload_value)); + z_drop(z_move(payload_value)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } diff --git a/examples/z_sub.c b/examples/z_sub.c index c7ea05c9a..ffa63703b 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -18,10 +18,11 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload)); - z_drop(z_move(payload)); + z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index b3be1f672..b703e6ad6 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -24,8 +24,10 @@ int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); - printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload_value)); z_attachment_t attachment = z_sample_attachment(sample); // checks if attachment exists @@ -35,11 +37,11 @@ void data_handler(const z_sample_t *sample, void *arg) { // reads particular attachment item z_bytes_t index = z_attachment_get(attachment, z_bytes_from_str("index")); - if (z_check(index)) { + if (z_bytes_is_initialized(&index)) { printf(" message number: %.*s\n", (int)index.len, index.start); } } - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index a24a9c0b4..fe2b58959 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -219,6 +219,10 @@ typedef struct ALIGN(8) z_owned_buffer_t { typedef struct z_buffer_t { struct z_owned_buffer_t *_inner; } z_buffer_t; +typedef struct z_owned_bytes_t { + uint8_t *start; + size_t len; +} z_owned_bytes_t; /** * A map of maybe-owned vector of bytes to owned vector of bytes. * @@ -631,7 +635,7 @@ typedef struct z_encoding_t { */ typedef struct z_owned_encoding_t { enum z_encoding_prefix_t prefix; - struct z_bytes_t suffix; + struct z_owned_bytes_t suffix; bool _dropped; } z_owned_encoding_t; /** @@ -646,17 +650,6 @@ typedef struct z_query_consolidation_t { * The `payload` field may be modified, and Zenoh will take the new values into account. */ typedef struct z_owned_buffer_t zc_owned_payload_t; -/** - * An owned zenoh value. - * - * Members: - * zc_owned_payload_t payload: The payload of this zenoh value. - * z_owned_encoding_t encoding: The encoding of this zenoh value `payload`. - */ -typedef struct z_owned_value_t { - zc_owned_payload_t payload; - struct z_owned_encoding_t encoding; -} z_owned_value_t; /** * Options passed to the :c:func:`z_get` function. * @@ -670,7 +663,8 @@ typedef struct z_owned_value_t { typedef struct z_get_options_t { enum z_query_target_t target; struct z_query_consolidation_t consolidation; - struct z_owned_value_t value; + zc_owned_payload_t payload; + struct z_encoding_t encoding; struct z_attachment_t attachment; uint64_t timeout_ms; } z_get_options_t; @@ -1102,7 +1096,7 @@ ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); /** * Returns the `index`th slice of the buffer, aliasing it. * - * Out of bounds accesses will return `z_bytes_null`. + * Out of bounds accesses will return `z_bytes_empty`. */ ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); /** @@ -1114,13 +1108,23 @@ ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ -ZENOHC_API bool z_bytes_check(const struct z_bytes_t *b); +ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *b); +ZENOHC_API struct z_owned_bytes_t z_bytes_clone(const struct z_bytes_t *b); +/** + * Returns the gravestone value for `z_bytes_t` + */ +ZENOHC_API struct z_bytes_t z_bytes_empty(void); /** * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). * - * `str == NULL` will cause this to return `z_bytes_null()` + * `str == NULL` will cause this to return `z_bytes_empty()` */ ZENOHC_API struct z_bytes_t z_bytes_from_str(const char *str); +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_bytes_is_initialized(const struct z_bytes_t *b); +ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *b); /** * Aliases `this` into a generic `z_attachment_t`, allowing it to be passed to corresponding APIs. */ @@ -1211,14 +1215,14 @@ ZENOHC_API struct z_owned_bytes_map_t z_bytes_map_null(void); /** * Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). * - * `str == NULL` will cause this to return `z_bytes_null()` + * `str == NULL` will cause this to return `z_bytes_empty()` */ ZENOHC_API struct z_bytes_t z_bytes_new(const char *str); /** - * Returns the gravestone value for `z_bytes_t` + * Returns the gravestone value for `z_owned_bytes_t` */ -ZENOHC_API struct z_bytes_t z_bytes_null(void); +ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); /** * Constructs a `len` bytes long view starting at `start`. */ @@ -2270,10 +2274,6 @@ 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); -ZENOHC_API bool z_value_check(const struct z_owned_value_t *value); -ZENOHC_API void z_value_drop(struct z_owned_value_t *value); -ZENOHC_API struct z_value_t z_value_loan(const struct z_owned_value_t *value); -ZENOHC_API struct z_owned_value_t z_value_null(void); /** * Converts the kind of zenoh entity into a string. * @@ -2467,7 +2467,11 @@ ZENOHC_API zc_owned_payload_t zc_payload_clone(zc_payload_t payload); /** * Decodes payload into null-terminated string */ -ZENOHC_API struct z_owned_str_t zc_payload_decode_into_string(zc_payload_t payload); +ZENOHC_API int8_t zc_payload_decode_into_bytes(zc_payload_t payload, struct z_owned_bytes_t *b); +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API int8_t zc_payload_decode_into_string(zc_payload_t payload, struct z_owned_str_t *cstr); /** * Decrements `payload`'s backing refcount, releasing the memory if appropriate. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index dba68f29a..bb50476a5 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -89,7 +89,7 @@ z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ - z_bytes_t : z_bytes_check, \ + z_owned_bytes_t : z_bytes_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -257,7 +257,7 @@ inline bool z_check(const z_owned_keyexpr_t& v) { return z_keyexpr_check(&v); } inline bool z_check(const z_keyexpr_t& v) { return z_keyexpr_is_initialized(&v); } inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } -inline bool z_check(const z_bytes_t& v) { return z_bytes_check(&v); } +inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } inline bool z_check(const zc_owned_payload_t& v) { return zc_payload_check(&v); } inline bool z_check(const zc_owned_shmbuf_t& v) { return zc_shmbuf_check(&v); } inline bool z_check(const zc_owned_shm_manager_t& v) { return zc_shm_manager_check(&v); } diff --git a/src/attachment.rs b/src/attachment.rs index 7b456a9c1..045596c47 100644 --- a/src/attachment.rs +++ b/src/attachment.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, cell::UnsafeCell, collections::HashMap}; use libc::c_void; -use crate::{impl_guarded_transmute, z_bytes_null, z_bytes_t}; +use crate::{impl_guarded_transmute, z_bytes_empty, z_bytes_t}; use zenoh::sample::{Attachment, AttachmentBuilder}; @@ -101,7 +101,7 @@ pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_by let mut context = attachment_get_iterator_context { key, - value: z_bytes_null(), + value: z_bytes_empty(), }; if this.iteration_driver.map_or(false, |iteration_driver| { @@ -113,7 +113,7 @@ pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_by }) { context.value } else { - z_bytes_null() + z_bytes_empty() } } @@ -237,12 +237,12 @@ pub extern "C" fn z_bytes_map_is_empty(this: &mut z_owned_bytes_map_t) -> bool { pub extern "C" fn z_bytes_map_get(this: &z_owned_bytes_map_t, key: z_bytes_t) -> z_bytes_t { let this = unsafe { &*this.get() }; let (Some(this), Some(key)) = (this.as_ref(), key.as_slice()) else { - return z_bytes_null(); + return z_bytes_empty(); }; if let Some(value) = this.get(key) { value.as_ref().into() } else { - z_bytes_null() + z_bytes_empty() } } diff --git a/src/collections.rs b/src/collections.rs index e0f2e7afe..2990f1a3a 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -54,15 +54,58 @@ impl Default for z_bytes_t { } } +#[repr(C)] +#[derive(Clone, Debug)] +pub struct z_owned_bytes_t { + pub start: *mut u8, + pub len: size_t, +} + +impl Drop for z_owned_bytes_t { + fn drop(&mut self) { + unsafe { z_bytes_drop(self) } + } +} + +impl z_owned_bytes_t { + pub fn new(data: &[u8]) ->z_owned_bytes_t { + if data.len() == 0 { + return z_bytes_null(); + } + let data = data.to_vec().into_boxed_slice(); + z_owned_bytes_t { + len: data.len(), + start: Box::leak(data).as_mut_ptr(), + } + } + + pub fn preallocate(len: usize) -> z_owned_bytes_t { + let data = vec![0u8; len].into_boxed_slice(); + z_owned_bytes_t { + len, + start: Box::leak(data).as_mut_ptr(), + } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { + std::ptr::copy_nonoverlapping( + value.as_ptr(), + (self.start as *mut u8).add(start), + value.len(), + ); + } +} + /// Returns ``true`` if `b` is initialized. #[no_mangle] -pub extern "C" fn z_bytes_check(b: &z_bytes_t) -> bool { +pub extern "C" fn z_bytes_is_initialized(b: &z_bytes_t) -> bool { !b.start.is_null() } /// Returns the gravestone value for `z_bytes_t` #[no_mangle] -pub const extern "C" fn z_bytes_null() -> z_bytes_t { +pub const extern "C" fn z_bytes_empty() -> z_bytes_t { z_bytes_t { len: 0, start: core::ptr::null(), @@ -71,12 +114,12 @@ pub const extern "C" fn z_bytes_null() -> z_bytes_t { /// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_null()` +/// `str == NULL` will cause this to return `z_bytes_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_from_str(str: *const c_char) -> z_bytes_t { if str.is_null() { - z_bytes_null() + z_bytes_empty() } else { let len = unsafe { libc::strlen(str) }; z_bytes_t { @@ -89,7 +132,7 @@ pub unsafe extern "C" fn z_bytes_from_str(str: *const c_char) -> z_bytes_t { #[deprecated = "Renamed to z_bytes_from_str"] /// Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_null()` +/// `str == NULL` will cause this to return `z_bytes_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_new(str: *const c_char) -> z_bytes_t { @@ -101,7 +144,7 @@ pub unsafe extern "C" fn z_bytes_new(str: *const c_char) -> z_bytes_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_wrap(start: *const u8, len: usize) -> z_bytes_t { if start.is_null() { - z_bytes_null() + z_bytes_empty() } else { z_bytes_t { len, start } } @@ -109,15 +152,49 @@ pub unsafe extern "C" fn z_bytes_wrap(start: *const u8, len: usize) -> z_bytes_t /// Frees `b` and invalidates it for double-drop safety. #[allow(clippy::missing_safety_doc)] -pub(crate) unsafe fn z_bytes_drop(b: &mut z_bytes_t) { +pub unsafe extern "C" fn z_bytes_drop(b: &mut z_owned_bytes_t) { if !b.start.is_null() { std::mem::drop(Box::from_raw( core::ptr::slice_from_raw_parts(b.start, b.len).cast_mut(), )); - b.start = std::ptr::null(); + b.start = std::ptr::null_mut(); + b.len = 0; } } +/// Returns the gravestone value for `z_owned_bytes_t` +#[no_mangle] +pub const extern "C" fn z_bytes_null() -> z_owned_bytes_t { + z_owned_bytes_t { + len: 0, + start: core::ptr::null_mut(), + } +} + +#[no_mangle] +pub const extern "C" fn z_bytes_loan(b: &z_owned_bytes_t) -> z_bytes_t { + z_bytes_t { + len: b.len, + start: b.start, + } +} + +#[no_mangle] +pub extern "C" fn z_bytes_clone(b: &z_bytes_t) -> z_owned_bytes_t { + if !z_bytes_is_initialized(b) { + return z_bytes_null(); + } else { + return z_owned_bytes_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) } ) + } +} + +/// Returns ``true`` if `b` is initialized. +#[no_mangle] +pub extern "C" fn z_bytes_check(b: &z_owned_bytes_t) -> bool { + !b.start.is_null() +} + + impl From for z_bytes_t { #[inline] fn from(pid: ZenohId) -> Self { @@ -276,13 +353,13 @@ pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { /// Returns the `index`th slice of the buffer, aliasing it. /// -/// Out of bounds accesses will return `z_bytes_null`. +/// Out of bounds accesses will return `z_bytes_empty`. #[no_mangle] pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { match buffer.into() { - None => z_bytes_null(), + None => z_bytes_empty(), Some(buf) => ZBuf::slices(buf) .nth(index) - .map_or(z_bytes_null(), |slice| slice.into()), + .map_or(z_bytes_empty(), |slice| slice.into()), } } diff --git a/src/commons.rs b/src/commons.rs index 249333d66..e8a6bc5d6 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -140,12 +140,13 @@ pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t /// Decodes payload into null-terminated string #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t) -> z_owned_str_t { +pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t, cstr: &mut z_owned_str_t) -> i8 { let payload: Option<&ZBuf> = payload.into(); if payload.is_none() { - return z_str_null(); + *cstr = z_str_null(); + return 0; } - let mut cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); + *cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); let payload = payload.unwrap(); let mut pos = 0; @@ -153,7 +154,27 @@ pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t) -> cstr.insert_unchecked(pos, s); pos += s.len(); } - cstr + return 0; +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_bytes(payload: zc_payload_t, b: &mut z_owned_bytes_t) -> i8 { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + *b = z_bytes_null(); + return 0; + } + *b = z_owned_bytes_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + b.insert_unchecked(pos, s); + pos += s.len(); + } + return 0; } unsafe impl Send for z_bytes_t {} @@ -529,7 +550,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { #[repr(C)] pub struct z_owned_encoding_t { pub prefix: z_encoding_prefix_t, - pub suffix: z_bytes_t, + pub suffix: z_owned_bytes_t, pub _dropped: bool, } @@ -537,7 +558,7 @@ impl z_owned_encoding_t { pub fn null() -> Self { z_owned_encoding_t { prefix: z_encoding_prefix_t::Empty, - suffix: z_bytes_t::default(), + suffix: z_bytes_null(), _dropped: true, } } @@ -595,7 +616,7 @@ pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { z_encoding_t { prefix: encoding.prefix, - suffix: encoding.suffix, + suffix: z_bytes_loan(&encoding.suffix), } } @@ -603,7 +624,7 @@ impl From for z_owned_encoding_t { fn from(val: z_encoding_t) -> Self { z_owned_encoding_t { prefix: val.prefix, - suffix: val.suffix, + suffix: z_bytes_clone(&val.suffix), _dropped: false, } } @@ -655,6 +676,9 @@ impl Drop for z_owned_str_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_drop(s: &mut z_owned_str_t) { + if s._cstr.is_null() { + return; + } libc::free(std::mem::transmute(s._cstr)); s._cstr = std::ptr::null_mut(); } diff --git a/src/get.rs b/src/get.rs index 17ed9ccbe..3e9e4ded4 100644 --- a/src/get.rs +++ b/src/get.rs @@ -33,15 +33,8 @@ use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, z_attachment_t, }; -use crate::z_encoding_check; -use crate::z_encoding_drop; -use crate::z_encoding_loan; -use crate::z_encoding_null; -use crate::z_owned_encoding_t; +use crate::z_encoding_default; use crate::zc_owned_payload_t; -use crate::zc_payload_check; -use crate::zc_payload_drop; -use crate::zc_payload_loan; use crate::zc_payload_null; use crate::zc_payload_t; use crate::{ @@ -122,45 +115,6 @@ pub struct z_value_t { pub encoding: z_encoding_t, } -/// An owned zenoh value. -/// -/// Members: -/// zc_owned_payload_t payload: The payload of this zenoh value. -/// z_owned_encoding_t encoding: The encoding of this zenoh value `payload`. -#[repr(C)] -pub struct z_owned_value_t { - pub payload: zc_owned_payload_t, - pub encoding: z_owned_encoding_t, -} - -#[no_mangle] -pub extern "C" fn z_value_null() -> z_owned_value_t { - z_owned_value_t { - payload: zc_payload_null(), - encoding: z_encoding_null(), - } -} - -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_value_drop(value: &mut z_owned_value_t) { - z_encoding_drop(&mut value.encoding); - zc_payload_drop(&mut value.payload); -} - -#[no_mangle] -pub extern "C" fn z_value_loan(value: &z_owned_value_t) -> z_value_t { - z_value_t { - payload: zc_payload_loan(&value.payload), - encoding: z_encoding_loan(&value.encoding), - } -} - -#[no_mangle] -pub extern "C" fn z_value_check(value: &z_owned_value_t) -> bool { - zc_payload_check(&value.payload) && z_encoding_check(&value.encoding) -} - /// Yields the contents of the reply by asserting it indicates a failure. /// /// You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. @@ -202,7 +156,8 @@ pub extern "C" fn z_reply_null() -> z_owned_reply_t { pub struct z_get_options_t { pub target: z_query_target_t, pub consolidation: z_query_consolidation_t, - pub value: z_owned_value_t, + pub payload: zc_owned_payload_t, + pub encoding: z_encoding_t, pub attachment: z_attachment_t, pub timeout_ms: u64, } @@ -212,7 +167,8 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { target: QueryTarget::default().into(), consolidation: QueryConsolidation::default().into(), timeout_ms: 0, - value: z_value_null(), + payload: zc_payload_null(), + encoding: z_encoding_default(), attachment: z_attachment_null(), } } @@ -257,22 +213,10 @@ pub unsafe extern "C" fn z_get( .consolidation(options.consolidation) .target(options.target.into()); - if let Some(payload) = options.value.payload.take() { + if let Some(payload) = options.payload.take() { let mut value = Value::new(payload); - if z_encoding_check(&options.value.encoding) { - value = value.encoding(z_encoding_loan(&options.value.encoding).into()); - } - q = q.with_value(value); - } - z_encoding_drop(&mut options.value.encoding); - if zc_payload_check(&options.value.payload) { - let buf: ZBuf = options.value.payload.as_ref().unwrap().clone(); - let mut value = Value::new(buf); - if z_encoding_check(&options.value.encoding) { - value = value.encoding(z_encoding_loan(&options.value.encoding).into()); - } + value = value.encoding(options.encoding.into()); q = q.with_value(value); - z_value_drop(&mut options.value); } if options.timeout_ms != 0 { q = q.timeout(std::time::Duration::from_millis(options.timeout_ms)); diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 789a00ffc..03a6d893c 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -93,13 +93,14 @@ void data_handler(const z_sample_t *sample, void *arg) { exit(-1); } z_drop(z_move(keystr)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); printf("data_handler: %i\n", val_num); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index a665ad19b..ccb2c1e82 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -74,13 +74,14 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); z_bytes_t v_const = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index 06d5c87ba..ad5969fa2 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -67,13 +67,14 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); if (z_qos_get_congestion_control(z_sample_qos(sample)) != Z_CONGESTION_CONTROL_BLOCK || z_qos_get_priority(z_sample_qos(sample)) != Z_PRIORITY_DATA) { diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 26645ad29..909da8c24 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -110,10 +110,11 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } @@ -121,7 +122,7 @@ int run_get() { ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); } z_drop(z_move(reply)); z_drop(z_move(channel)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 7cc7f3bfc..3b3abad94 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -86,15 +86,16 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } z_drop(z_move(keystr)); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); } z_drop(z_move(reply)); z_drop(z_move(channel)); From b957f98a304bb870c5715c5bfe8a5d71525706c3 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 12:31:48 +0200 Subject: [PATCH 014/377] generate opaque types data inside build.rs instead of cmake --- CMakeLists.txt | 5 ----- build.rs | 28 ++++++++++++++++++++++++++-- src/collections.rs | 17 ++++++----------- src/commons.rs | 14 ++++++++++---- src/opaque_types/mod.rs | 15 --------------- 5 files changed, 42 insertions(+), 37 deletions(-) delete mode 100644 src/opaque_types/mod.rs diff --git a/CMakeLists.txt b/CMakeLists.txt index aac66278b..00aa5cac2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,10 +179,6 @@ set_genexpr_condition(cargo_flags DEBUG $ "--manifest-path=${cargo_toml_dir_debug}/Cargo.toml" "--release;--manifest-path=${cargo_toml_dir_release}/Cargo.toml") set(cargo_flags ${cargo_flags} ${ZENOHC_CARGO_FLAGS}) -set_genexpr_condition(cargo_dep_flags DEBUG $ - "--manifest-path=${CMAKE_CURRENT_SOURCE_DIR}/build-resources/opaque-types/Cargo.toml" - "--release;--manifest-path=${CMAKE_CURRENT_SOURCE_DIR}/build-resources/opaque-types/Cargo.toml") -set(cargo_dep_flags ${cargo_dep_flags} ${ZENOHC_CARGO_FLAGS}) if(ZENOHC_BUILD_WITH_LOGGER_AUTOINIT) set(cargo_flags ${cargo_flags} --features=logger-autoinit) @@ -203,7 +199,6 @@ add_custom_command( OUTPUT ${libs} COMMAND ${CMAKE_COMMAND} -E echo \"RUSTFLAGS = $$RUSTFLAGS\" COMMAND ${CMAKE_COMMAND} -E echo \"cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags}\" - COMMAND cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_dep_flags} &> ${CMAKE_CURRENT_SOURCE_DIR}/.build_resources_opaque_types.txt || echo "" COMMAND cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags} VERBATIM COMMAND_EXPAND_LISTS diff --git a/build.rs b/build.rs index 03a271817..b14bdc4cd 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,8 @@ use fs2::FileExt; use regex::Regex; use std::io::{Read, Write}; +use std::path::PathBuf; +use std::process::{Command, Stdio}; use std::{borrow::Cow, collections::HashMap, io::BufWriter, path::Path}; const GENERATION_PATH: &str = "include/zenoh-gen.h"; @@ -24,6 +26,8 @@ const HEADER: &str = r"// #endif "; +use std::env; + fn main() { generate_opaque_types(); cbindgen::generate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) @@ -42,9 +46,29 @@ fn main() { println!("cargo:rerun-if-changed=build-resources") } +fn produce_opaque_types_data() -> PathBuf { + let target = env::var("TARGET").unwrap(); + let current_folder = std::env::current_dir().unwrap(); + let manifest_path = current_folder.join("./build-resources/opaque-types/Cargo.toml"); + let output_file_path = current_folder.join("./.build_resources_opaque_types.txt"); + let out_file = std::fs::File::create(output_file_path.clone()).unwrap(); + let stdio = Stdio::from(out_file); + let _ = Command::new("cargo") + .arg("build") + .arg("--target") + .arg(target) + .arg("--manifest-path") + .arg(manifest_path) + .stderr(stdio) + .output() + .unwrap(); + + output_file_path +} + fn generate_opaque_types() { let current_folder = std::env::current_dir().unwrap(); - let path_in = current_folder.join("./.build_resources_opaque_types.txt"); + let path_in = produce_opaque_types_data(); let path_out = current_folder.join("./src/opaque_types/mod.rs"); let data_in = std::fs::read_to_string(path_in).unwrap(); @@ -56,7 +80,7 @@ fn generate_opaque_types() { let s = format!( "#[repr(C, align({align}))] pub struct {type_name} {{ - _0: [u8; {size}] + _0: [u8; {size}], }} " ); diff --git a/src/collections.rs b/src/collections.rs index 2990f1a3a..363c30a89 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -68,8 +68,8 @@ impl Drop for z_owned_bytes_t { } impl z_owned_bytes_t { - pub fn new(data: &[u8]) ->z_owned_bytes_t { - if data.len() == 0 { + pub fn new(data: &[u8]) -> z_owned_bytes_t { + if data.is_empty() { return z_bytes_null(); } let data = data.to_vec().into_boxed_slice(); @@ -83,17 +83,13 @@ impl z_owned_bytes_t { let data = vec![0u8; len].into_boxed_slice(); z_owned_bytes_t { len, - start: Box::leak(data).as_mut_ptr(), + start: Box::leak(data).as_mut_ptr(), } } #[allow(clippy::missing_safety_doc)] pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping( - value.as_ptr(), - (self.start as *mut u8).add(start), - value.len(), - ); + std::ptr::copy_nonoverlapping(value.as_ptr(), self.start.add(start), value.len()); } } @@ -182,9 +178,9 @@ pub const extern "C" fn z_bytes_loan(b: &z_owned_bytes_t) -> z_bytes_t { #[no_mangle] pub extern "C" fn z_bytes_clone(b: &z_bytes_t) -> z_owned_bytes_t { if !z_bytes_is_initialized(b) { - return z_bytes_null(); + z_bytes_null() } else { - return z_owned_bytes_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) } ) + z_owned_bytes_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) }) } } @@ -194,7 +190,6 @@ pub extern "C" fn z_bytes_check(b: &z_owned_bytes_t) -> bool { !b.start.is_null() } - impl From for z_bytes_t { #[inline] fn from(pid: ZenohId) -> Self { diff --git a/src/commons.rs b/src/commons.rs index e8a6bc5d6..5f8ede970 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -140,7 +140,10 @@ pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t /// Decodes payload into null-terminated string #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t, cstr: &mut z_owned_str_t) -> i8 { +pub unsafe extern "C" fn zc_payload_decode_into_string( + payload: zc_payload_t, + cstr: &mut z_owned_str_t, +) -> i8 { let payload: Option<&ZBuf> = payload.into(); if payload.is_none() { *cstr = z_str_null(); @@ -154,13 +157,16 @@ pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t, cs cstr.insert_unchecked(pos, s); pos += s.len(); } - return 0; + 0 } /// Decodes payload into null-terminated string #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_bytes(payload: zc_payload_t, b: &mut z_owned_bytes_t) -> i8 { +pub unsafe extern "C" fn zc_payload_decode_into_bytes( + payload: zc_payload_t, + b: &mut z_owned_bytes_t, +) -> i8 { let payload: Option<&ZBuf> = payload.into(); if payload.is_none() { *b = z_bytes_null(); @@ -174,7 +180,7 @@ pub unsafe extern "C" fn zc_payload_decode_into_bytes(payload: zc_payload_t, b: b.insert_unchecked(pos, s); pos += s.len(); } - return 0; + 0 } unsafe impl Send for z_bytes_t {} diff --git a/src/opaque_types/mod.rs b/src/opaque_types/mod.rs deleted file mode 100644 index 0327b0943..000000000 --- a/src/opaque_types/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -/// A split buffer that owns all of its data. -/// -/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. -#[repr(C, align(8))] -pub struct z_owned_buffer_t { - _0: [u8; 40] -} -/// An owned sample. -/// -/// This is a read only type that can only be constructed by cloning a `z_sample_t`. -/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -#[repr(C, align(8))] -pub struct zc_owned_sample_t { - _0: [u8; 224] -} From f73599feb336f94dc029eb6958abcfbcba47abd6 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 12:36:30 +0200 Subject: [PATCH 015/377] .gitignore update --- .gitignore | 3 ++- src/opaque_types/.gitkeep | 0 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/opaque_types/.gitkeep diff --git a/.gitignore b/.gitignore index 8aaf37e32..49b20fcc2 100644 --- a/.gitignore +++ b/.gitignore @@ -73,4 +73,5 @@ dkms.conf include/zenoh_configure.h # Build resources -.build_resources* \ No newline at end of file +.build_resources* +src/opaque_types/mod.rs \ No newline at end of file diff --git a/src/opaque_types/.gitkeep b/src/opaque_types/.gitkeep new file mode 100644 index 000000000..e69de29bb From a3cc34a1c1f54eb9fcfc1d9ff5d9fc3c9d454024 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 16:04:59 +0200 Subject: [PATCH 016/377] extract build.rs instad of current folder to allow build outside of crate root --- build.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/build.rs b/build.rs index b14bdc4cd..51d44a615 100644 --- a/build.rs +++ b/build.rs @@ -46,10 +46,18 @@ fn main() { println!("cargo:rerun-if-changed=build-resources") } +fn get_build_rs_path() -> PathBuf { + let file_path = file!(); + let mut path_buf = PathBuf::new(); + path_buf.push(file_path); + path_buf.parent().unwrap().to_path_buf() +} + fn produce_opaque_types_data() -> PathBuf { let target = env::var("TARGET").unwrap(); - let current_folder = std::env::current_dir().unwrap(); + let current_folder = get_build_rs_path(); let manifest_path = current_folder.join("./build-resources/opaque-types/Cargo.toml"); + println!("cargo:warning={}", current_folder.to_str().unwrap()); let output_file_path = current_folder.join("./.build_resources_opaque_types.txt"); let out_file = std::fs::File::create(output_file_path.clone()).unwrap(); let stdio = Stdio::from(out_file); @@ -67,7 +75,7 @@ fn produce_opaque_types_data() -> PathBuf { } fn generate_opaque_types() { - let current_folder = std::env::current_dir().unwrap(); + let current_folder = get_build_rs_path(); let path_in = produce_opaque_types_data(); let path_out = current_folder.join("./src/opaque_types/mod.rs"); @@ -96,7 +104,7 @@ pub struct {type_name} {{ } fn get_opaque_type_docs() -> HashMap> { - let current_folder = std::env::current_dir().unwrap(); + let current_folder = get_build_rs_path(); let path_in = current_folder.join("./build-resources/opaque-types/src/lib.rs"); let re = Regex::new(r#"get_opaque_type_data!\(.*, "(\w+)"\)"#).unwrap(); let mut comments = std::vec::Vec::::new(); From 142b75299e7e4610328650cd18cf608749c9e0fa Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 16:28:54 +0200 Subject: [PATCH 017/377] remove println! --- build.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/build.rs b/build.rs index 51d44a615..703bde4c1 100644 --- a/build.rs +++ b/build.rs @@ -57,7 +57,6 @@ fn produce_opaque_types_data() -> PathBuf { let target = env::var("TARGET").unwrap(); let current_folder = get_build_rs_path(); let manifest_path = current_folder.join("./build-resources/opaque-types/Cargo.toml"); - println!("cargo:warning={}", current_folder.to_str().unwrap()); let output_file_path = current_folder.join("./.build_resources_opaque_types.txt"); let out_file = std::fs::File::create(output_file_path.clone()).unwrap(); let stdio = Stdio::from(out_file); From 4932ddff7c708380ca8177d7a844981182397ed8 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 17:36:13 +0200 Subject: [PATCH 018/377] move Payload/zBuf-related functionality into separate file --- include/zenoh_commons.h | 4 +- src/collections.rs | 132 +------------------- src/commons.rs | 140 +-------------------- src/lib.rs | 2 + src/payload.rs | 261 ++++++++++++++++++++++++++++++++++++++++ src/put.rs | 1 + 6 files changed, 271 insertions(+), 269 deletions(-) create mode 100644 src/payload.rs diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index fe2b58959..7e6060df7 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -2121,13 +2121,13 @@ ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); * Note that other samples may have received the same buffer, meaning that mutating this buffer may * affect the samples received by other subscribers. */ -ZENOHC_API struct z_owned_buffer_t z_sample_owned_payload(const struct z_sample_t *sample); +ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sample); /** * The sample's data, the return value aliases the sample. * * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ -ZENOHC_API struct z_buffer_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); /** * The qos with which the sample was received. */ diff --git a/src/collections.rs b/src/collections.rs index 363c30a89..d55a9fa1b 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -13,14 +13,7 @@ // use libc::{c_char, size_t}; -use std::ops::Deref; -use std::ptr::NonNull; -use zenoh::{ - buffers::{buffer::SplitBuffer, ZBuf}, - prelude::ZenohId, -}; - -use crate::{impl_guarded_transmute, GuardedTransmute}; +use zenoh::prelude::ZenohId; /// A contiguous view of bytes owned by some other entity. /// @@ -235,126 +228,3 @@ impl From<&[u8]> for z_bytes_t { } } } - -pub use crate::z_owned_buffer_t; -impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); -impl Default for z_owned_buffer_t { - fn default() -> Self { - z_buffer_null() - } -} -impl From for z_owned_buffer_t { - fn from(value: ZBuf) -> Self { - Some(value).transmute() - } -} - -impl From> for z_owned_buffer_t { - fn from(value: Option) -> Self { - match value { - Some(value) => value.into(), - None => z_buffer_null(), - } - } -} -impl core::ops::Deref for z_owned_buffer_t { - type Target = Option; - - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} -impl core::ops::DerefMut for z_owned_buffer_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { core::mem::transmute(self) } - } -} - -/// The gravestone value for `z_owned_buffer_t`. -#[no_mangle] -pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { - unsafe { core::mem::transmute(None::) } -} - -/// Decrements the buffer's reference counter, destroying it if applicable. -/// -/// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. -#[no_mangle] -pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { - core::mem::drop(buffer.take()) -} - -/// Returns `true` if the buffer is in a valid state. -#[no_mangle] -pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { - buffer.is_some() -} - -/// Loans the buffer, allowing you to call functions that only need a loan of it. -#[no_mangle] -pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { - buffer.as_ref().into() -} - -/// A loan of a `z_owned_buffer_t`. -/// -/// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. -#[repr(C)] -#[derive(Clone, Copy, Default)] -pub struct z_buffer_t { - _inner: Option>, -} - -impl From> for z_buffer_t { - fn from(value: Option<&ZBuf>) -> Self { - unsafe { core::mem::transmute(value) } - } -} - -impl From for Option<&'static ZBuf> { - fn from(value: z_buffer_t) -> Self { - unsafe { core::mem::transmute(value) } - } -} - -/// Increments the buffer's reference count, returning an owned version of the buffer. -#[no_mangle] -pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { - match buffer._inner { - Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, - None => ZBuf::empty().into(), - } -} - -/// Returns the number of slices in the buffer. -/// -/// If the return value is 0 or 1, then the buffer's data is contiguous in memory. -#[no_mangle] -pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { - match buffer.into() { - None => 0, - Some(buf) => ZBuf::slices(buf).len(), - } -} - -/// Returns total number bytes in the buffer. -#[no_mangle] -pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { - match buffer.into() { - None => 0, - Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), - } -} - -/// Returns the `index`th slice of the buffer, aliasing it. -/// -/// Out of bounds accesses will return `z_bytes_empty`. -#[no_mangle] -pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { - match buffer.into() { - None => z_bytes_empty(), - Some(buf) => ZBuf::slices(buf) - .nth(index) - .map_or(z_bytes_empty(), |slice| slice.into()), - } -} diff --git a/src/commons.rs b/src/commons.rs index 5f8ede970..ed0f9dbf0 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -12,21 +12,18 @@ // ZettaScale Zenoh team, // -use std::any::Any; use std::ops::Deref; -use std::slice; use crate::collections::*; use crate::keyexpr::*; use crate::z_congestion_control_t; use crate::z_id_t; use crate::z_priority_t; +use crate::zc_owned_payload_t; +use crate::zc_payload_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; -use zenoh::buffers::buffer::SplitBuffer; -use zenoh::buffers::ZBuf; -use zenoh::buffers::ZSliceBuffer; use zenoh::prelude::SampleKind; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; @@ -95,135 +92,6 @@ impl From> for z_timestamp_t { } } -/// An owned payload, backed by a reference counted owner. -/// -/// The `payload` field may be modified, and Zenoh will take the new values into account. -#[allow(non_camel_case_types)] -pub type zc_owned_payload_t = z_owned_buffer_t; - -/// Clones the `payload` by incrementing its reference counter. -#[no_mangle] -pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { - z_buffer_clone(z_buffer_loan(payload)) -} -/// Returns `false` if `payload` is the gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { - z_buffer_check(payload) -} -/// Decrements `payload`'s backing refcount, releasing the memory if appropriate. -#[no_mangle] -pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { - z_buffer_drop(payload) -} -/// Constructs `zc_owned_payload_t`'s gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { - z_buffer_null() -} - -/// Returns a :c:type:`zc_payload_t` loaned from `payload`. -#[no_mangle] -pub extern "C" fn zc_payload_loan(payload: &zc_owned_payload_t) -> zc_payload_t { - z_buffer_loan(payload) -} - -#[allow(non_camel_case_types)] -pub type zc_payload_t = z_buffer_t; - -/// Increments internal payload reference count, returning owned payload. -#[no_mangle] -pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t { - z_buffer_clone(payload) -} - -/// Decodes payload into null-terminated string -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_string( - payload: zc_payload_t, - cstr: &mut z_owned_str_t, -) -> i8 { - let payload: Option<&ZBuf> = payload.into(); - if payload.is_none() { - *cstr = z_str_null(); - return 0; - } - *cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); - let payload = payload.unwrap(); - - let mut pos = 0; - for s in payload.slices() { - cstr.insert_unchecked(pos, s); - pos += s.len(); - } - 0 -} - -/// Decodes payload into null-terminated string -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_bytes( - payload: zc_payload_t, - b: &mut z_owned_bytes_t, -) -> i8 { - let payload: Option<&ZBuf> = payload.into(); - if payload.is_none() { - *b = z_bytes_null(); - return 0; - } - *b = z_owned_bytes_t::preallocate(zc_payload_len(payload.into())); - let payload = payload.unwrap(); - - let mut pos = 0; - for s in payload.slices() { - b.insert_unchecked(pos, s); - pos += s.len(); - } - 0 -} - -unsafe impl Send for z_bytes_t {} -unsafe impl Sync for z_bytes_t {} - -impl ZSliceBuffer for z_bytes_t { - fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.start, self.len) } - } - fn as_mut_slice(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.start as *mut u8, self.len) } - } - fn as_any(&self) -> &dyn Any { - self - } -} - -/// Encodes byte sequence by aliasing. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_bytes(bytes: z_bytes_t) -> zc_owned_payload_t { - ZBuf::from(bytes).into() -} - -/// Encodes a null-terminated string by aliasing. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_string( - cstr: *const libc::c_char, -) -> zc_owned_payload_t { - let bytes = z_bytes_t { - start: cstr as *const u8, - len: libc::strlen(cstr), - }; - zc_payload_encode_from_bytes(bytes) -} - -/// Returns total number bytes in the payload. -#[no_mangle] -pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { - z_buffer_len(payload) -} - /// QoS settings of zenoh message. /// #[repr(C)] @@ -290,7 +158,7 @@ pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { /// /// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_buffer_t { +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { Some(&sample.payload).into() } /// Returns the sample's payload after incrementing its internal reference count. @@ -298,7 +166,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_buffer_t { /// Note that other samples may have received the same buffer, meaning that mutating this buffer may /// affect the samples received by other subscribers. #[no_mangle] -pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> z_owned_buffer_t { +pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { sample.payload.clone().into() } /// The sample's kind (put or delete). diff --git a/src/lib.rs b/src/lib.rs index 96cc4bd76..20f766352 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,8 @@ mod config; pub use crate::config::*; mod commons; pub use crate::commons::*; +mod payload; +pub use crate::payload::*; mod keyexpr; pub use crate::keyexpr::*; mod info; diff --git a/src/payload.rs b/src/payload.rs new file mode 100644 index 000000000..ba28eb3e4 --- /dev/null +++ b/src/payload.rs @@ -0,0 +1,261 @@ +use core::slice; +use std::{any::Any, ops::Deref, ptr::NonNull}; + +use zenoh::buffers::{buffer::SplitBuffer, ZBuf, ZSliceBuffer}; + +use crate::{ + impl_guarded_transmute, z_bytes_empty, z_bytes_null, z_bytes_t, z_owned_bytes_t, z_owned_str_t, + z_str_null, GuardedTransmute, +}; + +pub use crate::z_owned_buffer_t; +impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); +impl Default for z_owned_buffer_t { + fn default() -> Self { + z_buffer_null() + } +} +impl From for z_owned_buffer_t { + fn from(value: ZBuf) -> Self { + Some(value).transmute() + } +} + +impl From> for z_owned_buffer_t { + fn from(value: Option) -> Self { + match value { + Some(value) => value.into(), + None => z_buffer_null(), + } + } +} +impl core::ops::Deref for z_owned_buffer_t { + type Target = Option; + + fn deref(&self) -> &Self::Target { + unsafe { core::mem::transmute(self) } + } +} +impl core::ops::DerefMut for z_owned_buffer_t { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { core::mem::transmute(self) } + } +} + +/// The gravestone value for `z_owned_buffer_t`. +#[no_mangle] +pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { + unsafe { core::mem::transmute(None::) } +} + +/// Decrements the buffer's reference counter, destroying it if applicable. +/// +/// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. +#[no_mangle] +pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { + core::mem::drop(buffer.take()) +} + +/// Returns `true` if the buffer is in a valid state. +#[no_mangle] +pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { + buffer.is_some() +} + +/// Loans the buffer, allowing you to call functions that only need a loan of it. +#[no_mangle] +pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { + buffer.as_ref().into() +} + +/// A loan of a `z_owned_buffer_t`. +/// +/// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. +#[repr(C)] +#[derive(Clone, Copy, Default)] +pub struct z_buffer_t { + _inner: Option>, +} + +impl From> for z_buffer_t { + fn from(value: Option<&ZBuf>) -> Self { + unsafe { core::mem::transmute(value) } + } +} + +impl From for Option<&'static ZBuf> { + fn from(value: z_buffer_t) -> Self { + unsafe { core::mem::transmute(value) } + } +} + +/// Increments the buffer's reference count, returning an owned version of the buffer. +#[no_mangle] +pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { + match buffer._inner { + Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, + None => ZBuf::empty().into(), + } +} + +/// Returns the number of slices in the buffer. +/// +/// If the return value is 0 or 1, then the buffer's data is contiguous in memory. +#[no_mangle] +pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).len(), + } +} + +/// Returns total number bytes in the buffer. +#[no_mangle] +pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), + } +} + +/// Returns the `index`th slice of the buffer, aliasing it. +/// +/// Out of bounds accesses will return `z_bytes_empty`. +#[no_mangle] +pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { + match buffer.into() { + None => z_bytes_empty(), + Some(buf) => ZBuf::slices(buf) + .nth(index) + .map_or(z_bytes_empty(), |slice| slice.into()), + } +} + +/// An owned payload, backed by a reference counted owner. +/// +/// The `payload` field may be modified, and Zenoh will take the new values into account. +#[allow(non_camel_case_types)] +pub type zc_owned_payload_t = z_owned_buffer_t; + +/// Clones the `payload` by incrementing its reference counter. +#[no_mangle] +pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { + z_buffer_clone(z_buffer_loan(payload)) +} +/// Returns `false` if `payload` is the gravestone value. +#[no_mangle] +pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { + z_buffer_check(payload) +} +/// Decrements `payload`'s backing refcount, releasing the memory if appropriate. +#[no_mangle] +pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { + z_buffer_drop(payload) +} +/// Constructs `zc_owned_payload_t`'s gravestone value. +#[no_mangle] +pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { + z_buffer_null() +} + +/// Returns a :c:type:`zc_payload_t` loaned from `payload`. +#[no_mangle] +pub extern "C" fn zc_payload_loan(payload: &zc_owned_payload_t) -> zc_payload_t { + z_buffer_loan(payload) +} + +#[allow(non_camel_case_types)] +pub type zc_payload_t = z_buffer_t; + +/// Increments internal payload reference count, returning owned payload. +#[no_mangle] +pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t { + z_buffer_clone(payload) +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_string( + payload: zc_payload_t, + cstr: &mut z_owned_str_t, +) -> i8 { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + *cstr = z_str_null(); + return 0; + } + *cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + cstr.insert_unchecked(pos, s); + pos += s.len(); + } + 0 +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_bytes( + payload: zc_payload_t, + b: &mut z_owned_bytes_t, +) -> i8 { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + *b = z_bytes_null(); + return 0; + } + *b = z_owned_bytes_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + b.insert_unchecked(pos, s); + pos += s.len(); + } + 0 +} + +unsafe impl Send for z_bytes_t {} +unsafe impl Sync for z_bytes_t {} + +impl ZSliceBuffer for z_bytes_t { + fn as_slice(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.start, self.len) } + } + fn as_mut_slice(&mut self) -> &mut [u8] { + unsafe { slice::from_raw_parts_mut(self.start as *mut u8, self.len) } + } + fn as_any(&self) -> &dyn Any { + self + } +} + +/// Encodes byte sequence by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_bytes(bytes: z_bytes_t) -> zc_owned_payload_t { + ZBuf::from(bytes).into() +} + +/// Encodes a null-terminated string by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_string( + cstr: *const libc::c_char, +) -> zc_owned_payload_t { + let bytes = z_bytes_t { + start: cstr as *const u8, + len: libc::strlen(cstr), + }; + zc_payload_encode_from_bytes(bytes) +} + +/// Returns total number bytes in the payload. +#[no_mangle] +pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { + z_buffer_len(payload) +} diff --git a/src/put.rs b/src/put.rs index 5c8b8d807..5e2d59aec 100644 --- a/src/put.rs +++ b/src/put.rs @@ -14,6 +14,7 @@ use crate::commons::*; use crate::keyexpr::*; use crate::session::*; +use crate::zc_owned_payload_t; use crate::LOG_INVALID_SESSION; use libc::c_void; use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; From 90f25783bf5607303aa749b08af228243e0db12a Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 18:24:20 +0200 Subject: [PATCH 019/377] replace unsafe transmutes with safe ones --- src/payload.rs | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/src/payload.rs b/src/payload.rs index ba28eb3e4..2bc82e699 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -9,7 +9,8 @@ use crate::{ }; pub use crate::z_owned_buffer_t; -impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); +impl_guarded_transmute!(Option, z_owned_buffer_t); + impl Default for z_owned_buffer_t { fn default() -> Self { z_buffer_null() @@ -21,31 +22,10 @@ impl From for z_owned_buffer_t { } } -impl From> for z_owned_buffer_t { - fn from(value: Option) -> Self { - match value { - Some(value) => value.into(), - None => z_buffer_null(), - } - } -} -impl core::ops::Deref for z_owned_buffer_t { - type Target = Option; - - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} -impl core::ops::DerefMut for z_owned_buffer_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { core::mem::transmute(self) } - } -} - /// The gravestone value for `z_owned_buffer_t`. #[no_mangle] pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { - unsafe { core::mem::transmute(None::) } + None::.transmute() } /// Decrements the buffer's reference counter, destroying it if applicable. @@ -77,15 +57,18 @@ pub struct z_buffer_t { _inner: Option>, } +impl_guarded_transmute!(noderefs Option<&ZBuf>, z_buffer_t); +impl_guarded_transmute!(noderefs z_buffer_t, Option<&'static ZBuf>); + impl From> for z_buffer_t { fn from(value: Option<&ZBuf>) -> Self { - unsafe { core::mem::transmute(value) } + value.transmute() } } impl From for Option<&'static ZBuf> { fn from(value: z_buffer_t) -> Self { - unsafe { core::mem::transmute(value) } + value.transmute() } } From 32ac0af172334bccb9f480053b7e15bd30f04a3d Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 13:26:49 +0200 Subject: [PATCH 020/377] add payload reader --- build-resources/opaque-types/src/lib.rs | 7 ++-- include/zenoh_commons.h | 27 ++++++++++++++++ src/payload.rs | 42 ++++++++++++++++++++++++ tests/z_api_payload_test.c | 43 +++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 tests/z_api_payload_test.c diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 8ef08035c..354e8d999 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,5 +1,5 @@ use zenoh::sample::Sample; -use zenoh::buffers::ZBuf; +use zenoh::buffers::{ZBuf, ZBufReader}; #[macro_export] macro_rules! get_opaque_type_data { @@ -35,4 +35,7 @@ get_opaque_type_data!(Option, "z_owned_buffer_t"); /// /// This is a read only type that can only be constructed by cloning a `z_sample_t`. /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -get_opaque_type_data!(Option, "zc_owned_sample_t"); \ No newline at end of file +get_opaque_type_data!(Option, "zc_owned_sample_t"); + +/// A reader for payload data. +get_opaque_type_data!(ZBufReader, "zc_payload_reader"); \ No newline at end of file diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 7e6060df7..41129a653 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -885,6 +885,12 @@ typedef struct zc_owned_liveliness_token_t { typedef struct zc_liveliness_get_options_t { uint32_t timeout_ms; } zc_liveliness_get_options_t; +/** + * A reader for payload data. + */ +typedef struct ALIGN(8) zc_payload_reader { + uint8_t _0[24]; +} zc_payload_reader; /** * An owned sample. * @@ -2500,6 +2506,27 @@ ZENOHC_API zc_owned_payload_t zc_payload_null(void); * Clones the `payload` by incrementing its reference counter. */ ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); +/** + * Creates a reader for the specified `payload`. + * + * Returns 0 in case of success, -1 if `payload` is not valid. + */ +ZENOHC_API int8_t zc_payload_reader_init(zc_payload_t payload, struct zc_payload_reader *reader); +/** + * Reads data into specified destination. + * + * Will read at most `len` bytes. + * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. + */ +ZENOHC_API +size_t zc_payload_reader_read(struct zc_payload_reader *reader, + uint8_t *dest, + size_t len); +/** + * Returns number of the remaining bytes in the payload + * + */ +ZENOHC_API size_t zc_payload_reader_remaining(const struct zc_payload_reader *reader); /** * Creates a new blocking fifo channel, returned as a pair of closures. * diff --git a/src/payload.rs b/src/payload.rs index 2bc82e699..e43124bbb 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,6 +1,10 @@ use core::slice; +use std::slice::from_raw_parts_mut; use std::{any::Any, ops::Deref, ptr::NonNull}; +use zenoh::buffers::reader::HasReader; +use zenoh::buffers::reader::Reader; +use zenoh::buffers::ZBufReader; use zenoh::buffers::{buffer::SplitBuffer, ZBuf, ZSliceBuffer}; use crate::{ @@ -242,3 +246,41 @@ pub unsafe extern "C" fn zc_payload_encode_from_string( pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { z_buffer_len(payload) } + + + +pub use crate::zc_payload_reader; +impl_guarded_transmute!(ZBufReader<'static>, zc_payload_reader); +impl_guarded_transmute!(noderefs zc_payload_reader, ZBufReader<'static>); + +/// Creates a reader for the specified `payload`. +/// +/// Returns 0 in case of success, -1 if `payload` is not valid. +#[no_mangle] +pub unsafe extern "C" fn zc_payload_reader_init(payload: zc_payload_t, reader: *mut zc_payload_reader) -> i8 { + if payload._inner.is_none() { + return -1; + } + *reader = payload.transmute().unwrap().reader().transmute(); + 0 +} + + +/// Reads data into specified destination. +/// +/// Will read at most `len` bytes. +/// Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_reader_read(reader: *mut zc_payload_reader, dest: *mut u8, len: usize) -> usize { + let buf = unsafe { from_raw_parts_mut(dest, len) } ; + reader.as_mut().unwrap().read(buf).map(|n| n.get()).unwrap_or(0) +} + +/// Returns number of the remaining bytes in the payload +/// +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_reader_remaining(reader: *const zc_payload_reader) -> usize { + reader.as_ref().unwrap().remaining() +} \ No newline at end of file diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c new file mode 100644 index 000000000..d2d5da4d4 --- /dev/null +++ b/tests/z_api_payload_test.c @@ -0,0 +1,43 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#include +#include +#include +#include + +#include "zenoh.h" + +#undef NDEBUG +#include + +void test_reader() { + uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + uint8_t data_out[10] = {}; + z_bytes_t bytes = {.start = data, .len = 10 }; + + zc_owned_payload_t payload = zc_payload_encode_from_bytes(bytes); + zc_payload_reader reader; + zc_payload_reader_init(z_loan(payload), &reader); + assert(zc_payload_reader_remaining(&reader) == 10); + + zc_payload_reader_read(&reader, data_out, 5); + assert(zc_payload_reader_remaining(&reader) == 5); + zc_payload_reader_read(&reader, data_out, 5); + assert(zc_payload_reader_remaining(&reader) == 0); + assert(memcmp(data, data_out, 10)); +} + +int main(int argc, char **argv) { + test_reader(); +} From f1cdeda3375a415f7c3fc76b1f9606c8a8a1f1a4 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 14:33:47 +0200 Subject: [PATCH 021/377] fmt and clippy --- src/payload.rs | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/payload.rs b/src/payload.rs index e43124bbb..f7a737ef5 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -247,17 +247,19 @@ pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { z_buffer_len(payload) } - - pub use crate::zc_payload_reader; impl_guarded_transmute!(ZBufReader<'static>, zc_payload_reader); impl_guarded_transmute!(noderefs zc_payload_reader, ZBufReader<'static>); -/// Creates a reader for the specified `payload`. +/// Creates a reader for the specified `payload`. /// /// Returns 0 in case of success, -1 if `payload` is not valid. #[no_mangle] -pub unsafe extern "C" fn zc_payload_reader_init(payload: zc_payload_t, reader: *mut zc_payload_reader) -> i8 { +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_reader_init( + payload: zc_payload_t, + reader: *mut zc_payload_reader, +) -> i8 { if payload._inner.is_none() { return -1; } @@ -265,22 +267,30 @@ pub unsafe extern "C" fn zc_payload_reader_init(payload: zc_payload_t, reader: * 0 } - /// Reads data into specified destination. -/// -/// Will read at most `len` bytes. +/// +/// Will read at most `len` bytes. /// Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_read(reader: *mut zc_payload_reader, dest: *mut u8, len: usize) -> usize { - let buf = unsafe { from_raw_parts_mut(dest, len) } ; - reader.as_mut().unwrap().read(buf).map(|n| n.get()).unwrap_or(0) +pub unsafe extern "C" fn zc_payload_reader_read( + reader: *mut zc_payload_reader, + dest: *mut u8, + len: usize, +) -> usize { + let buf = unsafe { from_raw_parts_mut(dest, len) }; + reader + .as_mut() + .unwrap() + .read(buf) + .map(|n| n.get()) + .unwrap_or(0) } /// Returns number of the remaining bytes in the payload -/// +/// #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_reader_remaining(reader: *const zc_payload_reader) -> usize { reader.as_ref().unwrap().remaining() -} \ No newline at end of file +} From e2df814c1e4ebc5d8f79867a686ff0e1d63769c7 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 14:46:40 +0200 Subject: [PATCH 022/377] make all references to z_buffer_t private --- include/zenoh_commons.h | 70 ++++++++++------------------------------- include/zenoh_macros.h | 22 ++++++------- src/payload.rs | 16 +++++----- 3 files changed, 35 insertions(+), 73 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 41129a653..4326d856f 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -203,22 +203,6 @@ typedef struct z_attachment_t { const void *data; z_attachment_iter_driver_t iteration_driver; } z_attachment_t; -/** - * A split buffer that owns all of its data. - * - * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - */ -typedef struct ALIGN(8) z_owned_buffer_t { - uint8_t _0[40]; -} z_owned_buffer_t; -/** - * A loan of a `z_owned_buffer_t`. - * - * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. - */ -typedef struct z_buffer_t { - struct z_owned_buffer_t *_inner; -} z_buffer_t; typedef struct z_owned_bytes_t { uint8_t *start; size_t len; @@ -644,6 +628,14 @@ typedef struct z_owned_encoding_t { typedef struct z_query_consolidation_t { enum z_consolidation_mode_t mode; } z_query_consolidation_t; +/** + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + */ +typedef struct ALIGN(8) z_owned_buffer_t { + uint8_t _0[40]; +} z_owned_buffer_t; /** * An owned payload, backed by a reference counted owner. * @@ -788,6 +780,14 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; +/** + * A loan of a `z_owned_buffer_t`. + * + * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. + */ +typedef struct z_buffer_t { + struct z_owned_buffer_t *_inner; +} z_buffer_t; typedef struct z_buffer_t zc_payload_t; /** * A zenoh value. @@ -1073,44 +1073,6 @@ ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); -/** - * Returns `true` if the buffer is in a valid state. - */ -ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); -/** - * Increments the buffer's reference count, returning an owned version of the buffer. - */ -ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); -/** - * Decrements the buffer's reference counter, destroying it if applicable. - * - * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. - */ -ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); -/** - * Returns total number bytes in the buffer. - */ -ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); -/** - * Loans the buffer, allowing you to call functions that only need a loan of it. - */ -ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); -/** - * The gravestone value for `z_owned_buffer_t`. - */ -ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); -/** - * Returns the `index`th slice of the buffer, aliasing it. - * - * Out of bounds accesses will return `z_bytes_empty`. - */ -ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); -/** - * Returns the number of slices in the buffer. - * - * If the return value is 0 or 1, then the buffer's data is contiguous in memory. - */ -ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index bb50476a5..815b2df85 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -14,7 +14,7 @@ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ - z_owned_buffer_t: z_buffer_loan, \ + zc_owned_payload_t : zc_payload_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ )(&x) @@ -43,7 +43,7 @@ z_owned_reply_channel_t * : z_reply_channel_drop, \ z_owned_query_channel_t * : z_query_channel_drop, \ z_owned_bytes_map_t * : z_bytes_map_drop, \ - z_owned_buffer_t * : z_buffer_drop, \ + zc_owned_payload_t * : zc_payload_drop, \ zc_owned_shmbuf_t * : zc_shmbuf_drop, \ zc_owned_shm_manager_t * : zc_shm_manager_drop, \ zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ @@ -74,7 +74,7 @@ z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ z_owned_reply_channel_t * : z_reply_channel_null, \ z_owned_bytes_map_t * : z_bytes_map_null, \ - z_owned_buffer_t * : z_buffer_null, \ + zc_owned_payload_t * : zc_payload_null, \ z_attachment_t * : z_attachment_null, \ zc_owned_shmbuf_t * : zc_shmbuf_null, \ zc_owned_shm_manager_t * : zc_shm_manager_null, \ @@ -89,7 +89,7 @@ z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ - z_owned_bytes_t : z_bytes_check, \ + z_owned_bytes_t : z_bytes_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -99,7 +99,7 @@ z_owned_query_t : z_query_check, \ z_owned_str_t : z_str_check, \ z_owned_bytes_map_t : z_bytes_map_check, \ - z_owned_buffer_t : z_buffer_check, \ + zc_owned_payload_t: zc_payload_check, \ z_attachment_t : z_attachment_check, \ zc_owned_shmbuf_t : zc_shmbuf_check, \ zc_owned_shm_manager_t : zc_shm_manager_check, \ @@ -142,7 +142,7 @@ template<> struct zenoh_loan_type{ typedef z_pull_sub template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; -template<> struct zenoh_loan_type{ typedef z_buffer_t type; }; +template<> struct zenoh_loan_type{ typedef zc_payload_t type; }; template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } @@ -155,7 +155,7 @@ template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_en template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } -template<> inline z_buffer_t z_loan(const z_owned_buffer_t& x) { return z_buffer_loan(&x); } +template<> inline zc_payload_t z_loan(const zc_owned_payload& x) { return zc_payload_loan(&x); } template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } template struct zenoh_drop_type { typedef T type; }; @@ -174,7 +174,7 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -204,7 +204,7 @@ template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } -template<> inline void z_drop(z_owned_buffer_t* v) { z_buffer_drop(v); } +template<> inline void z_drop(zc_owned_payload* v) { zc_payload_drop(v); } template<> inline void z_drop(zc_owned_payload_t* v) { zc_payload_drop(v); } template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } @@ -234,7 +234,7 @@ inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } -inline void z_null(z_owned_buffer_t& v) { v = z_buffer_null(); } +inline void z_null(zc_owned_payload& v) { v = zc_payload_null(); } inline void z_null(zc_owned_payload_t& v) { v = zc_payload_null(); } inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } @@ -269,7 +269,7 @@ inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } -inline bool z_check(const z_owned_buffer_t& v) { return z_buffer_check(&v); } +inline bool z_check(const zc_owned_payload& v) { return zc_payload_check(&v); } inline bool z_check(const z_owned_bytes_map_t& v) { return z_bytes_map_check(&v); } inline bool z_check(const z_attachment_t& v) { return z_attachment_check(&v); } inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } diff --git a/src/payload.rs b/src/payload.rs index f7a737ef5..a1745ba36 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -28,7 +28,7 @@ impl From for z_owned_buffer_t { /// The gravestone value for `z_owned_buffer_t`. #[no_mangle] -pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { +extern "C" fn z_buffer_null() -> z_owned_buffer_t { None::.transmute() } @@ -36,19 +36,19 @@ pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { /// /// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. #[no_mangle] -pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { +extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { core::mem::drop(buffer.take()) } /// Returns `true` if the buffer is in a valid state. #[no_mangle] -pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { +extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { buffer.is_some() } /// Loans the buffer, allowing you to call functions that only need a loan of it. #[no_mangle] -pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { +extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { buffer.as_ref().into() } @@ -78,7 +78,7 @@ impl From for Option<&'static ZBuf> { /// Increments the buffer's reference count, returning an owned version of the buffer. #[no_mangle] -pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { +extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { match buffer._inner { Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, None => ZBuf::empty().into(), @@ -89,7 +89,7 @@ pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { /// /// If the return value is 0 or 1, then the buffer's data is contiguous in memory. #[no_mangle] -pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { +extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { match buffer.into() { None => 0, Some(buf) => ZBuf::slices(buf).len(), @@ -98,7 +98,7 @@ pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { /// Returns total number bytes in the buffer. #[no_mangle] -pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { +extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { match buffer.into() { None => 0, Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), @@ -109,7 +109,7 @@ pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { /// /// Out of bounds accesses will return `z_bytes_empty`. #[no_mangle] -pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { +extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { match buffer.into() { None => z_bytes_empty(), Some(buf) => ZBuf::slices(buf) From 05401fed3b493641e5034453a760fbae7a6cba0a Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 14:49:46 +0200 Subject: [PATCH 023/377] remove reference to z_buffer_t --- src/queryable.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/queryable.rs b/src/queryable.rs index c55820227..3c62fba4d 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -16,7 +16,7 @@ use crate::attachment::{ z_attachment_iterate, z_attachment_null, z_attachment_t, }; use crate::{ - impl_guarded_transmute, z_buffer_t, z_bytes_t, z_closure_query_call, z_encoding_default, + impl_guarded_transmute, zc_payload_t, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, LOG_INVALID_SESSION, }; @@ -348,7 +348,7 @@ pub unsafe extern "C" fn z_query_value(query: &z_query_t) -> z_value_t { value.into() } None => z_value_t { - payload: z_buffer_t::default(), + payload: zc_payload_t::default(), encoding: z_encoding_default(), }, } From 7a94a55dc296673d49d65d756d9c6f0fcbb13b21 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 14:56:56 +0200 Subject: [PATCH 024/377] fmt --- src/queryable.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/queryable.rs b/src/queryable.rs index 3c62fba4d..dd932188c 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -16,8 +16,8 @@ use crate::attachment::{ z_attachment_iterate, z_attachment_null, z_attachment_t, }; use crate::{ - impl_guarded_transmute, zc_payload_t, z_bytes_t, z_closure_query_call, z_encoding_default, - z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, + impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, + z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, zc_payload_t, LOG_INVALID_SESSION, }; use libc::c_void; From 0275363057328894f013cf101c3d3c1fa9d202b2 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 15:17:41 +0200 Subject: [PATCH 025/377] explicit zero-intialization --- tests/z_api_payload_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c index d2d5da4d4..10b1a3177 100644 --- a/tests/z_api_payload_test.c +++ b/tests/z_api_payload_test.c @@ -23,7 +23,7 @@ void test_reader() { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - uint8_t data_out[10] = {}; + uint8_t data_out[10] = {0}; z_bytes_t bytes = {.start = data, .len = 10 }; zc_owned_payload_t payload = zc_payload_encode_from_bytes(bytes); From 78c84aa2148c6c83714c4f248d23fb63009c898d Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 8 Apr 2024 22:41:57 +0200 Subject: [PATCH 026/377] relinked to explicit_api2, QoS removed --- Cargo.lock | 226 +++++++++++++++++++++++++++------------- Cargo.toml | 10 +- Cargo.toml.in | 10 +- include/zenoh_commons.h | 99 ++++++++++-------- src/commons.rs | 49 ++------- 5 files changed, 227 insertions(+), 167 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d52c4ed7..d4fb64d25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,7 +259,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -383,9 +383,9 @@ checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" [[package]] name = "cbindgen" -version = "0.24.5" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d" +checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" dependencies = [ "clap", "heck", @@ -802,7 +802,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -898,6 +898,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + [[package]] name = "hashbrown" version = "0.12.3" @@ -1087,6 +1093,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "iter-read" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c397ca3ea05ad509c4ec451fea28b4771236a376ca1c69fd5143aae0cf8f93c4" + [[package]] name = "itoa" version = "1.0.9" @@ -1285,6 +1297,17 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint-dig" version = "0.8.4" @@ -1443,7 +1466,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -1467,6 +1490,48 @@ dependencies = [ "indexmap 2.0.0", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1562,9 +1627,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -1619,9 +1684,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2007,22 +2072,45 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] +[[package]] +name = "serde-pickle" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762ad136a26407c6a80825813600ceeab5e613660d93d79a41f0ec877171e71" +dependencies = [ + "byteorder", + "iter-read", + "num-bigint", + "num-traits", + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -2038,9 +2126,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -2143,6 +2231,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -2246,9 +2340,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.33" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -2299,7 +2393,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -2351,7 +2445,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -2432,7 +2526,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -2662,7 +2756,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -2696,7 +2790,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2953,7 +3047,7 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -2969,11 +3063,15 @@ dependencies = [ "ordered-float", "paste", "petgraph", + "phf", "rand", "regex", "rustc_version", "serde", + "serde-pickle", + "serde_cbor", "serde_json", + "serde_yaml", "socket2 0.5.6", "stop-token", "tokio", @@ -2996,7 +3094,6 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", - "zenoh-task", "zenoh-transport", "zenoh-util", ] @@ -3004,7 +3101,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "zenoh-collections", ] @@ -3037,7 +3134,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "log", "serde", @@ -3050,12 +3147,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "flume", "json5", @@ -3075,7 +3172,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-global-executor", "lazy_static", @@ -3087,7 +3184,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "aes", "hmac", @@ -3100,29 +3197,25 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "bincode", "env_logger 0.11.2", "flume", "futures", "log", + "phf", "serde", + "serde_cbor", + "serde_json", "tokio", "zenoh", - "zenoh-core", - "zenoh-macros", - "zenoh-result", - "zenoh-runtime", - "zenoh-sync", - "zenoh-task", - "zenoh-util", ] [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3136,7 +3229,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "zenoh-config", @@ -3154,7 +3247,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "flume", @@ -3177,7 +3270,7 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3205,7 +3298,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "log", @@ -3223,7 +3316,7 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3251,7 +3344,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "log", @@ -3272,7 +3365,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "futures", @@ -3292,7 +3385,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "futures-util", @@ -3313,18 +3406,18 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", "zenoh-keyexpr", ] [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "const_format", "libloading", @@ -3340,7 +3433,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "const_format", "rand", @@ -3354,7 +3447,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "anyhow", ] @@ -3362,9 +3455,8 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ - "futures", "lazy_static", "tokio", "zenoh-collections", @@ -3374,7 +3466,7 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "log", "serde", @@ -3386,7 +3478,7 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "event-listener 4.0.0", "futures", @@ -3397,23 +3489,10 @@ dependencies = [ "zenoh-runtime", ] -[[package]] -name = "zenoh-task" -version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" -dependencies = [ - "futures", - "log", - "tokio", - "tokio-util", - "zenoh-core", - "zenoh-runtime", -] - [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "flume", @@ -3439,14 +3518,13 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", - "zenoh-task", "zenoh-util", ] [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-std", "async-trait", @@ -3482,7 +3560,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 8e0541888..f515f3b10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,13 +51,13 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } [build-dependencies] -cbindgen = "0.24.3" +cbindgen = "0.26.0" fs2 = "0.4.3" regex = "1.7.1" serde_yaml = "0.9.19" diff --git a/Cargo.toml.in b/Cargo.toml.in index a8123bcd5..16ea65bf8 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -51,13 +51,13 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } [build-dependencies] -cbindgen = "0.24.3" +cbindgen = "0.26.0" fs2 = "0.4.3" regex = "1.7.1" serde_yaml = "0.9.19" diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 4326d856f..a9a95cc1c 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -203,6 +203,22 @@ typedef struct z_attachment_t { const void *data; z_attachment_iter_driver_t iteration_driver; } z_attachment_t; +/** + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + */ +typedef struct ALIGN(8) z_owned_buffer_t { + uint8_t _0[40]; +} z_owned_buffer_t; +/** + * A loan of a `z_owned_buffer_t`. + * + * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. + */ +typedef struct z_buffer_t { + struct z_owned_buffer_t *_inner; +} z_buffer_t; typedef struct z_owned_bytes_t { uint8_t *start; size_t len; @@ -628,14 +644,6 @@ typedef struct z_owned_encoding_t { typedef struct z_query_consolidation_t { enum z_consolidation_mode_t mode; } z_query_consolidation_t; -/** - * A split buffer that owns all of its data. - * - * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - */ -typedef struct ALIGN(8) z_owned_buffer_t { - uint8_t _0[40]; -} z_owned_buffer_t; /** * An owned payload, backed by a reference counted owner. * @@ -736,13 +744,6 @@ typedef struct z_put_options_t { enum z_priority_t priority; struct z_attachment_t attachment; } z_put_options_t; -/** - * QoS settings of zenoh message. - * - */ -typedef struct z_qos_t { - uint8_t _0; -} z_qos_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -780,14 +781,6 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; -/** - * A loan of a `z_owned_buffer_t`. - * - * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. - */ -typedef struct z_buffer_t { - struct z_owned_buffer_t *_inner; -} z_buffer_t; typedef struct z_buffer_t zc_payload_t; /** * A zenoh value. @@ -1073,6 +1066,44 @@ ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); +/** + * Returns `true` if the buffer is in a valid state. + */ +ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); +/** + * Increments the buffer's reference count, returning an owned version of the buffer. + */ +ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); +/** + * Decrements the buffer's reference counter, destroying it if applicable. + * + * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ +ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +/** + * Returns total number bytes in the buffer. + */ +ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); +/** + * Loans the buffer, allowing you to call functions that only need a loan of it. + */ +ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); +/** + * The gravestone value for `z_owned_buffer_t`. + */ +ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); +/** + * Returns the `index`th slice of the buffer, aliasing it. + * + * Out of bounds accesses will return `z_bytes_empty`. + */ +ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); +/** + * Returns the number of slices in the buffer. + * + * If the return value is 0 or 1, then the buffer's data is contiguous in memory. + */ +ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ @@ -1845,22 +1876,6 @@ int8_t z_put(struct z_session_t session, * Constructs the default value for :c:type:`z_put_options_t`. */ ZENOHC_API struct z_put_options_t z_put_options_default(void); -/** - * Returns default qos settings. - */ -ZENOHC_API struct z_qos_t z_qos_default(void); -/** - * Returns message congestion control. - */ -ZENOHC_API enum z_congestion_control_t z_qos_get_congestion_control(struct z_qos_t qos); -/** - * Returns message express flag. If set to true, the message is not batched to reduce the latency. - */ -ZENOHC_API bool z_qos_get_express(struct z_qos_t qos); -/** - * Returns message priority. - */ -ZENOHC_API enum z_priority_t z_qos_get_priority(struct z_qos_t qos); /** * Returns the attachment to the query by aliasing. * @@ -2064,6 +2079,8 @@ ZENOHC_API struct z_owned_reply_t z_reply_null(void); ZENOHC_API struct z_sample_t z_reply_ok(const struct z_owned_reply_t *reply); /** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) * The sample's attachment. * * `sample` is aliased by the return value. @@ -2096,10 +2113,6 @@ ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sa * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); -/** - * The qos with which the sample was received. - */ -ZENOHC_API struct z_qos_t z_sample_qos(const struct z_sample_t *sample); /** * The samples timestamp */ diff --git a/src/commons.rs b/src/commons.rs index ed0f9dbf0..9031d6628 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -27,7 +27,6 @@ use libc::{c_char, c_ulong}; use zenoh::prelude::SampleKind; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; -use zenoh::sample::QoS; use zenoh::sample::Sample; use zenoh_protocol::core::Timestamp; @@ -92,34 +91,6 @@ impl From> for z_timestamp_t { } } -/// QoS settings of zenoh message. -/// -#[repr(C)] -pub struct z_qos_t(u8); - -impl_guarded_transmute!(QoS, z_qos_t); - -/// Returns message priority. -#[no_mangle] -pub extern "C" fn z_qos_get_priority(qos: z_qos_t) -> z_priority_t { - qos.transmute().priority().into() -} -/// Returns message congestion control. -#[no_mangle] -pub extern "C" fn z_qos_get_congestion_control(qos: z_qos_t) -> z_congestion_control_t { - qos.transmute().congestion_control().into() -} -/// Returns message express flag. If set to true, the message is not batched to reduce the latency. -#[no_mangle] -pub extern "C" fn z_qos_get_express(qos: z_qos_t) -> bool { - qos.transmute().express() -} -/// Returns default qos settings. -#[no_mangle] -pub extern "C" fn z_qos_default() -> z_qos_t { - QoS::default().transmute() -} - /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. @@ -147,19 +118,19 @@ impl<'a> z_sample_t<'a> { /// `sample` is aliased by its return value. #[no_mangle] pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { - (&sample.key_expr).into() + sample.key_expr().into() } /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { - (&sample.encoding).into() + sample.encoding().into() } /// The sample's data, the return value aliases the sample. /// /// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { - Some(&sample.payload).into() + sample.payload().into() } /// Returns the sample's payload after incrementing its internal reference count. /// @@ -167,29 +138,27 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { /// affect the samples received by other subscribers. #[no_mangle] pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { - sample.payload.clone().into() + sample.payload().clone().into() } /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { - sample.kind.into() + sample.kind().into() } /// The samples timestamp #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { - sample.timestamp.as_ref().into() + sample.timestamp().into() } /// The qos with which the sample was received. -#[no_mangle] -pub extern "C" fn z_sample_qos(sample: &z_sample_t) -> z_qos_t { - sample.qos.into() -} +/// TODO: split to methods (priority, congestion_control, express) + /// The sample's attachment. /// /// `sample` is aliased by the return value. #[no_mangle] pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { - match &sample.attachment { + match sample.attachment() { Some(attachment) => z_attachment_t { data: attachment as *const _ as *mut c_void, iteration_driver: Some(attachment_iteration_driver), From ef031b34e37045b3aa6ed3f78bb420a21d33258d Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Apr 2024 17:34:04 +0200 Subject: [PATCH 027/377] commons.rs compiles --- Cargo.lock | 33 ++--- Cargo.toml | 16 ++- Cargo.toml.in | 14 ++- include/zenoh_commons.h | 102 +++++---------- src/commons.rs | 269 +++++++--------------------------------- src/get.rs | 2 +- src/payload.rs | 6 +- src/publisher.rs | 9 +- 8 files changed, 113 insertions(+), 338 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4fb64d25..16f5478f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2638,6 +2638,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "unzip-n" version = "0.1.2" @@ -3047,7 +3053,6 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3101,7 +3106,6 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "zenoh-collections", ] @@ -3125,6 +3129,7 @@ dependencies = [ "regex", "serde_yaml", "spin 0.9.8", + "unwrap-infallible", "zenoh", "zenoh-ext", "zenoh-protocol", @@ -3134,7 +3139,6 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "log", "serde", @@ -3147,12 +3151,10 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "flume", "json5", @@ -3172,7 +3174,6 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-global-executor", "lazy_static", @@ -3184,7 +3185,6 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "aes", "hmac", @@ -3197,7 +3197,6 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "bincode", "env_logger 0.11.2", @@ -3215,7 +3214,6 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3229,7 +3227,6 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "zenoh-config", @@ -3247,7 +3244,6 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "flume", @@ -3270,7 +3266,6 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3298,7 +3293,6 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "log", @@ -3316,7 +3310,6 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3344,7 +3337,6 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "log", @@ -3365,7 +3357,6 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "futures", @@ -3385,7 +3376,6 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "futures-util", @@ -3406,7 +3396,6 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "proc-macro2", "quote", @@ -3417,7 +3406,6 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "const_format", "libloading", @@ -3433,7 +3421,6 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "const_format", "rand", @@ -3447,7 +3434,6 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "anyhow", ] @@ -3455,7 +3441,6 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "lazy_static", "tokio", @@ -3466,7 +3451,6 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "log", "serde", @@ -3478,7 +3462,6 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "event-listener 4.0.0", "futures", @@ -3492,7 +3475,6 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "flume", @@ -3524,7 +3506,6 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-std", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index f515f3b10..34366e392 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,11 +50,17 @@ libc = "0.2.139" log = "0.4.17" rand = "0.8.5" spin = "0.9.5" +unwrap-infallible = "0.1.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } +#zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +#zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +#zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +#zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } + +zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } +zenoh-util = { path = "../zenoh/commons/zenoh-util" } +zenoh-ext = { path = "../zenoh/zenoh-ext" } [build-dependencies] cbindgen = "0.26.0" @@ -64,7 +70,7 @@ serde_yaml = "0.9.19" [lib] path="src/lib.rs" -name = "zenohc" +name = "zenohcd" crate-type = ["cdylib", "staticlib"] doctest = false diff --git a/Cargo.toml.in b/Cargo.toml.in index 16ea65bf8..d31b3d0c6 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -50,11 +50,17 @@ libc = "0.2.139" log = "0.4.17" rand = "0.8.5" spin = "0.9.5" +unwrap-infallible = "0.1.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } +#zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +#zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +#zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +#zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } + +zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } +zenoh-util = { path = "../zenoh/commons/zenoh-util" } +zenoh-ext = { path = "../zenoh/zenoh-ext" } [build-dependencies] cbindgen = "0.26.0" diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index a9a95cc1c..9e4693788 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -45,54 +45,6 @@ typedef enum z_consolidation_mode_t { Z_CONSOLIDATION_MODE_MONOTONIC = 1, Z_CONSOLIDATION_MODE_LATEST = 2, } z_consolidation_mode_t; -/** - * A :c:type:`z_encoding_t` integer `prefix`. - * - * - **Z_ENCODING_PREFIX_EMPTY** - * - **Z_ENCODING_PREFIX_APP_OCTET_STREAM** - * - **Z_ENCODING_PREFIX_APP_CUSTOM** - * - **Z_ENCODING_PREFIX_TEXT_PLAIN** - * - **Z_ENCODING_PREFIX_APP_PROPERTIES** - * - **Z_ENCODING_PREFIX_APP_JSON** - * - **Z_ENCODING_PREFIX_APP_SQL** - * - **Z_ENCODING_PREFIX_APP_INTEGER** - * - **Z_ENCODING_PREFIX_APP_FLOAT** - * - **Z_ENCODING_PREFIX_APP_XML** - * - **Z_ENCODING_PREFIX_APP_XHTML_XML** - * - **Z_ENCODING_PREFIX_APP_X_WWW_FORM_URLENCODED** - * - **Z_ENCODING_PREFIX_TEXT_JSON** - * - **Z_ENCODING_PREFIX_TEXT_HTML** - * - **Z_ENCODING_PREFIX_TEXT_XML** - * - **Z_ENCODING_PREFIX_TEXT_CSS** - * - **Z_ENCODING_PREFIX_TEXT_CSV** - * - **Z_ENCODING_PREFIX_TEXT_JAVASCRIPT** - * - **Z_ENCODING_PREFIX_IMAGE_JPEG** - * - **Z_ENCODING_PREFIX_IMAGE_PNG** - * - **Z_ENCODING_PREFIX_IMAGE_GIF** - */ -typedef enum z_encoding_prefix_t { - Z_ENCODING_PREFIX_EMPTY = 0, - Z_ENCODING_PREFIX_APP_OCTET_STREAM = 1, - Z_ENCODING_PREFIX_APP_CUSTOM = 2, - Z_ENCODING_PREFIX_TEXT_PLAIN = 3, - Z_ENCODING_PREFIX_APP_PROPERTIES = 4, - Z_ENCODING_PREFIX_APP_JSON = 5, - Z_ENCODING_PREFIX_APP_SQL = 6, - Z_ENCODING_PREFIX_APP_INTEGER = 7, - Z_ENCODING_PREFIX_APP_FLOAT = 8, - Z_ENCODING_PREFIX_APP_XML = 9, - Z_ENCODING_PREFIX_APP_XHTML_XML = 10, - Z_ENCODING_PREFIX_APP_X_WWW_FORM_URLENCODED = 11, - Z_ENCODING_PREFIX_TEXT_JSON = 12, - Z_ENCODING_PREFIX_TEXT_HTML = 13, - Z_ENCODING_PREFIX_TEXT_XML = 14, - Z_ENCODING_PREFIX_TEXT_CSS = 15, - Z_ENCODING_PREFIX_TEXT_CSV = 16, - Z_ENCODING_PREFIX_TEXT_JAVASCRIPT = 17, - Z_ENCODING_PREFIX_IMAGE_JPEG = 18, - Z_ENCODING_PREFIX_IMAGE_PNG = 19, - Z_ENCODING_PREFIX_IMAGE_GIF = 20, -} z_encoding_prefix_t; /** * A :c:type:`z_keyexpr_intersection_level_t`. * @@ -607,37 +559,41 @@ typedef struct z_delete_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_delete_options_t; -/** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. - * - * Members: - * z_encoding_prefix_t prefix: The integer prefix of this encoding. - * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. - */ -typedef struct z_encoding_t { - enum z_encoding_prefix_t prefix; - struct z_bytes_t suffix; -} z_encoding_t; /** * An owned payload encoding. * - * Members: - * z_encoding_prefix_t prefix: The integer prefix of this encoding. - * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. - * * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. * * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ -typedef struct z_owned_encoding_t { - enum z_encoding_prefix_t prefix; - struct z_owned_bytes_t suffix; - bool _dropped; +#if !defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_owned_encoding_t { + uint64_t _0[4]; } z_owned_encoding_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_owned_encoding_t { + uint32_t _0[4]; +} z_owned_encoding_t; +#endif +/** + * The encoding of a payload, in a MIME-like format. + * + * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + * + */ +#if !defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_encoding_t { + uint64_t _0[4]; +} z_encoding_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_encoding_t { + uint32_t _0[4]; +} z_encoding_t; +#endif /** * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. */ @@ -1527,10 +1483,6 @@ int8_t z_delete(struct z_session_t session, * Constructs the default value for :c:type:`z_put_options_t`. */ ZENOHC_API struct z_delete_options_t z_delete_options_default(void); -/** - * Constructs a specific :c:type:`z_encoding_t`. - */ -ZENOHC_API struct z_encoding_t z_encoding(enum z_encoding_prefix_t prefix, const char *suffix); /** * Returns ``true`` if `encoding` is valid. */ @@ -1543,6 +1495,10 @@ ZENOHC_API struct z_encoding_t z_encoding_default(void); * Frees `encoding`, invalidating it for double-drop safety. */ ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); +/** + * Constructs a specific :c:type:`z_encoding_t`. + */ +ZENOHC_API struct z_owned_encoding_t z_encoding_from_str(const char *s); /** * Returns a :c:type:`z_encoding_t` loaned from `encoding`. */ diff --git a/src/commons.rs b/src/commons.rs index 9031d6628..0fb284322 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -12,23 +12,31 @@ // ZettaScale Zenoh team, // +use std::ffi::CStr; use std::ops::Deref; use crate::collections::*; use crate::keyexpr::*; use crate::z_congestion_control_t; use crate::z_id_t; +use crate::z_owned_buffer_t; use crate::z_priority_t; use crate::zc_owned_payload_t; use crate::zc_payload_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; +use zenoh::buffers::ZBuf; +use zenoh::encoding::Encoding; +use zenoh::payload::Deserialize; +use zenoh::payload::ZSerde; use zenoh::prelude::SampleKind; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::Sample; use zenoh_protocol::core::Timestamp; +use unwrap_infallible::UnwrapInfallible; +use std::convert::Infallible; use crate::attachment::{attachment_iteration_driver, z_attachment_null, z_attachment_t}; @@ -123,22 +131,30 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { - sample.encoding().into() + Some(sample.encoding()).into() } /// The sample's data, the return value aliases the sample. /// /// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { - sample.payload().into() + // TODO: here returning reference not to sample's payload, but to temporary copy + // THIS WILL CRASH FOR SURE, MADE IT ONLY TO MAKE IT COMPILE + // Need a way to get reference to sample's payload + let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); + let owned_buffer: z_owned_buffer_t = Some(buffer).into(); + owned_buffer.as_ref().into() } + /// Returns the sample's payload after incrementing its internal reference count. /// /// Note that other samples may have received the same buffer, meaning that mutating this buffer may /// affect the samples received by other subscribers. #[no_mangle] pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { - sample.payload().clone().into() + let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); + let owned_buffer: z_owned_buffer_t = Some(buffer).into(); + owned_buffer.into() } /// The sample's kind (put or delete). #[no_mangle] @@ -204,273 +220,82 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { None.into() } -/// A :c:type:`z_encoding_t` integer `prefix`. -/// -/// - **Z_ENCODING_PREFIX_EMPTY** -/// - **Z_ENCODING_PREFIX_APP_OCTET_STREAM** -/// - **Z_ENCODING_PREFIX_APP_CUSTOM** -/// - **Z_ENCODING_PREFIX_TEXT_PLAIN** -/// - **Z_ENCODING_PREFIX_APP_PROPERTIES** -/// - **Z_ENCODING_PREFIX_APP_JSON** -/// - **Z_ENCODING_PREFIX_APP_SQL** -/// - **Z_ENCODING_PREFIX_APP_INTEGER** -/// - **Z_ENCODING_PREFIX_APP_FLOAT** -/// - **Z_ENCODING_PREFIX_APP_XML** -/// - **Z_ENCODING_PREFIX_APP_XHTML_XML** -/// - **Z_ENCODING_PREFIX_APP_X_WWW_FORM_URLENCODED** -/// - **Z_ENCODING_PREFIX_TEXT_JSON** -/// - **Z_ENCODING_PREFIX_TEXT_HTML** -/// - **Z_ENCODING_PREFIX_TEXT_XML** -/// - **Z_ENCODING_PREFIX_TEXT_CSS** -/// - **Z_ENCODING_PREFIX_TEXT_CSV** -/// - **Z_ENCODING_PREFIX_TEXT_JAVASCRIPT** -/// - **Z_ENCODING_PREFIX_IMAGE_JPEG** -/// - **Z_ENCODING_PREFIX_IMAGE_PNG** -/// - **Z_ENCODING_PREFIX_IMAGE_GIF** -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(C)] -pub enum z_encoding_prefix_t { - Empty = 0, - AppOctetStream = 1, - AppCustom = 2, - TextPlain = 3, - AppProperties = 4, - AppJson = 5, - AppSql = 6, - AppInteger = 7, - AppFloat = 8, - AppXml = 9, - AppXhtmlXml = 10, - AppXWwwFormUrlencoded = 11, - TextJson = 12, - TextHtml = 13, - TextXml = 14, - TextCss = 15, - TextCsv = 16, - TextJavascript = 17, - ImageJpeg = 18, - ImagePng = 19, - ImageGif = 20, -} - -impl From for zenoh_protocol::core::KnownEncoding { - fn from(val: z_encoding_prefix_t) -> Self { - if cfg!(debug_assertions) { - match val { - z_encoding_prefix_t::Empty => zenoh_protocol::core::KnownEncoding::Empty, - z_encoding_prefix_t::AppOctetStream => { - zenoh_protocol::core::KnownEncoding::AppOctetStream - } - z_encoding_prefix_t::AppCustom => zenoh_protocol::core::KnownEncoding::AppCustom, - z_encoding_prefix_t::TextPlain => zenoh_protocol::core::KnownEncoding::TextPlain, - z_encoding_prefix_t::AppProperties => { - zenoh_protocol::core::KnownEncoding::AppProperties - } - z_encoding_prefix_t::AppJson => zenoh_protocol::core::KnownEncoding::AppJson, - z_encoding_prefix_t::AppSql => zenoh_protocol::core::KnownEncoding::AppSql, - z_encoding_prefix_t::AppInteger => zenoh_protocol::core::KnownEncoding::AppInteger, - z_encoding_prefix_t::AppFloat => zenoh_protocol::core::KnownEncoding::AppFloat, - z_encoding_prefix_t::AppXml => zenoh_protocol::core::KnownEncoding::AppXml, - z_encoding_prefix_t::AppXhtmlXml => { - zenoh_protocol::core::KnownEncoding::AppXhtmlXml - } - z_encoding_prefix_t::AppXWwwFormUrlencoded => { - zenoh_protocol::core::KnownEncoding::AppXWwwFormUrlencoded - } - z_encoding_prefix_t::TextJson => zenoh_protocol::core::KnownEncoding::TextJson, - z_encoding_prefix_t::TextHtml => zenoh_protocol::core::KnownEncoding::TextHtml, - z_encoding_prefix_t::TextXml => zenoh_protocol::core::KnownEncoding::TextXml, - z_encoding_prefix_t::TextCss => zenoh_protocol::core::KnownEncoding::TextCss, - z_encoding_prefix_t::TextCsv => zenoh_protocol::core::KnownEncoding::TextCsv, - z_encoding_prefix_t::TextJavascript => { - zenoh_protocol::core::KnownEncoding::TextJavascript - } - z_encoding_prefix_t::ImageJpeg => zenoh_protocol::core::KnownEncoding::ImageJpeg, - z_encoding_prefix_t::ImagePng => zenoh_protocol::core::KnownEncoding::ImagePng, - z_encoding_prefix_t::ImageGif => zenoh_protocol::core::KnownEncoding::ImageGif, - } - } else { - unsafe { std::mem::transmute(val as u8) } - } - } -} - -impl From for z_encoding_prefix_t { - fn from(val: zenoh_protocol::core::KnownEncoding) -> Self { - if cfg!(debug_assertions) { - match val { - zenoh_protocol::core::KnownEncoding::Empty => z_encoding_prefix_t::Empty, - zenoh_protocol::core::KnownEncoding::AppOctetStream => { - z_encoding_prefix_t::AppOctetStream - } - zenoh_protocol::core::KnownEncoding::AppCustom => z_encoding_prefix_t::AppCustom, - zenoh_protocol::core::KnownEncoding::TextPlain => z_encoding_prefix_t::TextPlain, - zenoh_protocol::core::KnownEncoding::AppProperties => { - z_encoding_prefix_t::AppProperties - } - zenoh_protocol::core::KnownEncoding::AppJson => z_encoding_prefix_t::AppJson, - zenoh_protocol::core::KnownEncoding::AppSql => z_encoding_prefix_t::AppSql, - zenoh_protocol::core::KnownEncoding::AppInteger => z_encoding_prefix_t::AppInteger, - zenoh_protocol::core::KnownEncoding::AppFloat => z_encoding_prefix_t::AppFloat, - zenoh_protocol::core::KnownEncoding::AppXml => z_encoding_prefix_t::AppXml, - zenoh_protocol::core::KnownEncoding::AppXhtmlXml => { - z_encoding_prefix_t::AppXhtmlXml - } - zenoh_protocol::core::KnownEncoding::AppXWwwFormUrlencoded => { - z_encoding_prefix_t::AppXWwwFormUrlencoded - } - zenoh_protocol::core::KnownEncoding::TextJson => z_encoding_prefix_t::TextJson, - zenoh_protocol::core::KnownEncoding::TextHtml => z_encoding_prefix_t::TextHtml, - zenoh_protocol::core::KnownEncoding::TextXml => z_encoding_prefix_t::TextXml, - zenoh_protocol::core::KnownEncoding::TextCss => z_encoding_prefix_t::TextCss, - zenoh_protocol::core::KnownEncoding::TextCsv => z_encoding_prefix_t::TextCsv, - zenoh_protocol::core::KnownEncoding::TextJavascript => { - z_encoding_prefix_t::TextJavascript - } - zenoh_protocol::core::KnownEncoding::ImageJpeg => z_encoding_prefix_t::ImageJpeg, - zenoh_protocol::core::KnownEncoding::ImagePng => z_encoding_prefix_t::ImagePng, - zenoh_protocol::core::KnownEncoding::ImageGif => z_encoding_prefix_t::ImageGif, - } - } else { - unsafe { std::mem::transmute(val as u32) } - } - } -} - /// The encoding of a payload, in a MIME-like format. /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// -/// Members: -/// z_encoding_prefix_t prefix: The integer prefix of this encoding. -/// z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. -#[repr(C)] -#[derive(Clone, Copy, Debug)] -pub struct z_encoding_t { - pub prefix: z_encoding_prefix_t, - pub suffix: z_bytes_t, -} +#[cfg(not(target_arch = "arm"))] +#[repr(C, align(8))] +pub struct z_encoding_t([u64; 4]); -impl From for zenoh_protocol::core::Encoding { - fn from(enc: z_encoding_t) -> Self { - if enc.suffix.len == 0 { - zenoh_protocol::core::Encoding::Exact(enc.prefix.into()) - } else { - let suffix = unsafe { - let slice: &'static [u8] = - std::slice::from_raw_parts(enc.suffix.start, enc.suffix.len); - std::str::from_utf8_unchecked(slice) - }; - zenoh_protocol::core::Encoding::WithSuffix(enc.prefix.into(), suffix.into()) - } - } -} +#[cfg(target_arch = "arm")] +#[repr(C, align(4))] +pub struct z_encoding_t([u32; 4]); -impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { - fn from(val: &zenoh_protocol::core::Encoding) -> Self { - let suffix = val.suffix(); - z_encoding_t { - prefix: (*val.prefix()).into(), - suffix: z_bytes_t { - start: suffix.as_ptr(), - len: suffix.len(), - }, - } - } -} +impl_guarded_transmute!(Option<&'static Encoding>, z_encoding_t); /// An owned payload encoding. /// -/// Members: -/// z_encoding_prefix_t prefix: The integer prefix of this encoding. -/// z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. -/// /// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. /// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[repr(C)] -pub struct z_owned_encoding_t { - pub prefix: z_encoding_prefix_t, - pub suffix: z_owned_bytes_t, - pub _dropped: bool, -} - -impl z_owned_encoding_t { - pub fn null() -> Self { - z_owned_encoding_t { - prefix: z_encoding_prefix_t::Empty, - suffix: z_bytes_null(), - _dropped: true, - } - } -} +#[cfg(not(target_arch = "arm"))] +#[repr(C, align(8))] +pub struct z_owned_encoding_t([u64; 4]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(4))] +pub struct z_owned_encoding_t([u32; 4]); + +impl_guarded_transmute!(Option, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null() -> z_owned_encoding_t { - z_owned_encoding_t::null() + None::.into() } /// Constructs a specific :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding( - prefix: z_encoding_prefix_t, - suffix: *const c_char, -) -> z_encoding_t { - let suffix = if suffix.is_null() { - z_bytes_t::empty() +pub unsafe extern "C" fn z_encoding_from_str(s: *const c_char) -> z_owned_encoding_t { + if s.is_null() { + z_encoding_null() } else { - z_bytes_t { - start: suffix as *const u8, - len: libc::strlen(suffix), - } - }; - z_encoding_t { prefix, suffix } + let s = CStr::from_ptr(s).to_string_lossy().as_ref(); + Some(Encoding::from(s)).into() + } } /// Constructs a default :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - (&zenoh_protocol::core::Encoding::default()).into() + let encoding = Some(&Encoding::default()); + encoding.into() } /// Frees `encoding`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - z_bytes_drop(&mut encoding.suffix); - encoding._dropped = true + std::mem::drop(encoding.take()); } /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { - !encoding._dropped + encoding.is_some() } /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { - z_encoding_t { - prefix: encoding.prefix, - suffix: z_bytes_loan(&encoding.suffix), - } -} - -impl From for z_owned_encoding_t { - fn from(val: z_encoding_t) -> Self { - z_owned_encoding_t { - prefix: val.prefix, - suffix: z_bytes_clone(&val.suffix), - _dropped: false, - } - } + encoding.as_ref().into() } /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` diff --git a/src/get.rs b/src/get.rs index 3e9e4ded4..065b9aba9 100644 --- a/src/get.rs +++ b/src/get.rs @@ -215,7 +215,7 @@ pub unsafe extern "C" fn z_get( if let Some(payload) = options.payload.take() { let mut value = Value::new(payload); - value = value.encoding(options.encoding.into()); + value.encoding = options.encoding.into(); q = q.with_value(value); } if options.timeout_ms != 0 { diff --git a/src/payload.rs b/src/payload.rs index a1745ba36..fa6603de6 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -2,10 +2,10 @@ use core::slice; use std::slice::from_raw_parts_mut; use std::{any::Any, ops::Deref, ptr::NonNull}; -use zenoh::buffers::reader::HasReader; -use zenoh::buffers::reader::Reader; +use zenoh::buffers::HasReader; +use zenoh::buffers::Reader; use zenoh::buffers::ZBufReader; -use zenoh::buffers::{buffer::SplitBuffer, ZBuf, ZSliceBuffer}; +use zenoh::buffers::{SplitBuffer, ZBuf, ZSliceBuffer}; use crate::{ impl_guarded_transmute, z_bytes_empty, z_bytes_null, z_bytes_t, z_owned_bytes_t, z_owned_str_t, diff --git a/src/publisher.rs b/src/publisher.rs index 6647655bd..73b14f6a3 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -16,6 +16,8 @@ use crate::zcu_closure_matching_status_call; use crate::zcu_owned_closure_matching_status_t; use std::ops::{Deref, DerefMut}; use zenoh::prelude::SessionDeclarations; +use zenoh::sample::SampleBuilderTrait; +use zenoh::sample::ValueBuilderTrait; use zenoh::{ prelude::{Priority, Value}, publication::MatchingListener, @@ -260,10 +262,9 @@ pub unsafe extern "C" fn z_publisher_put( log::debug!("Attempted to put without a payload"); return i8::MIN; }; - let value: Value = payload.into(); let put = match options { Some(options) => { - let mut put = p.put(value.encoding(options.encoding.into())); + let mut put = p.put(payload).encoding(options.encoding.into()); if z_attachment_check(&options.attachment) { let mut attachment_builder = AttachmentBuilder::new(); z_attachment_iterate( @@ -271,11 +272,11 @@ pub unsafe extern "C" fn z_publisher_put( insert_in_attachment_builder, &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, ); - put = put.with_attachment(attachment_builder.build()); + put = put.attachment(attachment_builder.build()); }; put } - None => p.put(value), + None => p.put(payload), }; if let Err(e) = put.res_sync() { log::error!("{}", e); From 9cf7c5c52caad16057e57e6aa6b1097dcb288d81 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Apr 2024 18:06:41 +0200 Subject: [PATCH 028/377] get compilation fix --- include/zenoh_commons.h | 21 ++++++++--------- src/commons.rs | 1 + src/get.rs | 51 ++++++++++++++++++++++------------------- src/keyexpr.rs | 1 - 4 files changed, 39 insertions(+), 35 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 9e4693788..f5981b620 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -737,18 +737,16 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; -typedef struct z_buffer_t zc_payload_t; -/** - * A zenoh value. - * - * Members: - * zc_payload_t payload: The payload of this zenoh value. - * z_encoding_t encoding: The encoding of this zenoh value `payload`. - */ -typedef struct z_value_t { - zc_payload_t payload; - struct z_encoding_t encoding; +#if !defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_value_t { + uint64_t _0[4]; } z_value_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_value_t { + uint32_t _0[4]; +} z_value_t; +#endif /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -774,6 +772,7 @@ typedef struct z_owned_reply_channel_t { struct z_owned_closure_reply_t send; struct z_owned_reply_channel_closure_t recv; } z_owned_reply_channel_t; +typedef struct z_buffer_t zc_payload_t; typedef struct z_timestamp_t { uint64_t time; struct z_id_t id; diff --git a/src/commons.rs b/src/commons.rs index 0fb284322..6c76669b7 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -233,6 +233,7 @@ pub struct z_encoding_t([u64; 4]); pub struct z_encoding_t([u32; 4]); impl_guarded_transmute!(Option<&'static Encoding>, z_encoding_t); +impl_guarded_transmute!(z_encoding_t, Option<&'static Encoding>); /// An owned payload encoding. /// diff --git a/src/get.rs b/src/get.rs index 065b9aba9..0effcc28a 100644 --- a/src/get.rs +++ b/src/get.rs @@ -14,6 +14,8 @@ use libc::c_char; use libc::c_void; +use zenoh::encoding::Encoding; +use zenoh::payload; use std::{ convert::TryFrom, ffi::CStr, @@ -105,15 +107,29 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { } /// A zenoh value. -/// -/// Members: -/// zc_payload_t payload: The payload of this zenoh value. -/// z_encoding_t encoding: The encoding of this zenoh value `payload`. +/// +/// + + #[repr(C)] -pub struct z_value_t { - pub payload: zc_payload_t, - pub encoding: z_encoding_t, -} +#[cfg(not(target_arch = "arm"))] +#[repr(C, align(8))] +pub struct z_owned_value_t([u64; 4]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(4))] +pub struct z_owned_value_t([u32; 4]); + +#[cfg(not(target_arch = "arm"))] +#[repr(C, align(8))] +pub struct z_value_t([u64; 4]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(4))] +pub struct z_value_t([u32; 4]); + +impl_guarded_transmute!(Value, z_owned_value_t); +impl_guarded_transmute!(Option<&'static Value>, z_value_t); /// Yields the contents of the reply by asserting it indicates a failure. /// @@ -122,10 +138,7 @@ pub struct z_value_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { if let Some(inner) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { - z_value_t { - payload: Some(&inner.payload).into(), - encoding: (&inner.encoding).into(), - } + inner.into() } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Err despite that not being the case") } @@ -215,7 +228,8 @@ pub unsafe extern "C" fn z_get( if let Some(payload) = options.payload.take() { let mut value = Value::new(payload); - value.encoding = options.encoding.into(); + let encoding: Option<&Encoding> = options.encoding.into(); + value.encoding = encoding.cloned().unwrap_or_default(); q = q.with_value(value); } if options.timeout_ms != 0 { @@ -312,16 +326,6 @@ impl From<&z_value_t> for Value { } } -impl From<&Value> for z_value_t { - #[inline] - fn from(val: &Value) -> z_value_t { - z_value_t { - encoding: (&val.encoding).into(), - payload: Some(&val.payload).into(), - } - } -} - /// Create a default :c:type:`z_query_target_t`. #[no_mangle] pub extern "C" fn z_query_target_default() -> z_query_target_t { @@ -364,6 +368,7 @@ impl From for z_consolidation_mode_t { #[inline] fn from(cm: ConsolidationMode) -> Self { match cm { + ConsolidationMode::Auto => z_consolidation_mode_t::AUTO, ConsolidationMode::None => z_consolidation_mode_t::NONE, ConsolidationMode::Monotonic => z_consolidation_mode_t::MONOTONIC, ConsolidationMode::Latest => z_consolidation_mode_t::LATEST, diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 7742b3948..51c47d211 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -26,7 +26,6 @@ use crate::LOG_INVALID_SESSION; use libc::c_char; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; -use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh_util::core::zresult::ErrNo; From c2f72fbe28cbda16a1a34b3f52013a880404af98 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Apr 2024 19:15:20 +0200 Subject: [PATCH 029/377] encoding unfinished --- include/zenoh_commons.h | 94 +------------------------------------- include/zenoh_concrete.h | 22 --------- splitguide.yaml | 1 - src/commons.rs | 22 +++++---- src/info.rs | 2 +- src/lib.rs | 4 +- src/publisher.rs | 3 ++ src/querying_subscriber.rs | 9 ++-- src/session.rs | 2 +- src/subscriber.rs | 66 +++++++++++++------------- 10 files changed, 58 insertions(+), 167 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index f5981b620..f0048010b 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -91,16 +91,6 @@ typedef enum z_query_target_t { Z_QUERY_TARGET_ALL, Z_QUERY_TARGET_ALL_COMPLETE, } z_query_target_t; -/** - * The subscription reliability. - * - * - **Z_RELIABILITY_BEST_EFFORT** - * - **Z_RELIABILITY_RELIABLE** - */ -typedef enum z_reliability_t { - Z_RELIABILITY_BEST_EFFORT, - Z_RELIABILITY_RELIABLE, -} z_reliability_t; typedef enum z_sample_kind_t { Z_SAMPLE_KIND_PUT = 0, Z_SAMPLE_KIND_DELETE = 1, @@ -524,16 +514,6 @@ typedef struct z_publisher_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_publisher_options_t; -/** - * Represents the set of options that can be applied to a pull subscriber, - * upon its declaration via :c:func:`z_declare_pull_subscriber`. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - */ -typedef struct z_pull_subscriber_options_t { - enum z_reliability_t reliability; -} z_pull_subscriber_options_t; /** * Options passed to the :c:func:`z_declare_queryable` function. * @@ -550,7 +530,7 @@ typedef struct z_queryable_options_t { * z_reliability_t reliability: The subscription reliability. */ typedef struct z_subscriber_options_t { - enum z_reliability_t reliability; + } z_subscriber_options_t; /** * Options passed to the :c:func:`z_delete` function. @@ -682,9 +662,6 @@ typedef struct z_publisher_put_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_publisher_put_options_t; -typedef struct z_pull_subscriber_t { - const struct z_owned_pull_subscriber_t *_0; -} z_pull_subscriber_t; /** * Options passed to the :c:func:`z_put` function. * @@ -962,7 +939,6 @@ typedef struct ze_owned_querying_subscriber_t { * uint64_t query_timeout_ms: The timeout to be used for queries. */ typedef struct ze_querying_subscriber_options_t { - enum z_reliability_t reliability; enum zcu_locality_t allowed_origin; struct z_keyexpr_t query_selector; enum z_query_target_t query_target; @@ -1371,44 +1347,6 @@ ZENOHC_API struct z_owned_publisher_t z_declare_publisher(struct z_session_t session, struct z_keyexpr_t keyexpr, const struct z_publisher_options_t *options); -/** - * Declares a pull subscriber for a given key expression. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to subscribe. - * callback: The callback function that will be called each time a data matching the subscribed expression is received. - * opts: additional options for the pull subscriber. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the pull subscriber is still valid, - * you may use `z_pull_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing ``NULL`` for the options: - * - * .. code-block:: C - * - * z_owned_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * z_owned_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -struct z_owned_pull_subscriber_t z_declare_pull_subscriber(struct z_session_t session, - struct z_keyexpr_t keyexpr, - struct z_owned_closure_sample_t *callback, - const struct z_pull_subscriber_options_t *opts); /** * Creates a Queryable for the given key expression. * @@ -1788,23 +1726,6 @@ int8_t z_publisher_put(struct z_publisher_t publisher, * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API bool z_pull_subscriber_check(const struct z_owned_pull_subscriber_t *sub); -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API -struct z_pull_subscriber_t z_pull_subscriber_loan(const struct z_owned_pull_subscriber_t *sub); -/** - * Constructs a null safe-to-drop value of 'z_owned_pull_subscriber_t' type - */ -ZENOHC_API struct z_owned_pull_subscriber_t z_pull_subscriber_null(void); -/** - * Constructs the default value for :c:type:`z_pull_subscriber_options_t`. - */ -ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default(void); /** * Put data, transfering the buffer ownership. * @@ -2161,14 +2082,6 @@ ZENOHC_API struct z_owned_subscriber_t z_subscriber_null(void); * Constructs the default value for :c:type:`z_subscriber_options_t`. */ ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); -/** - * Pull data for :c:type:`z_owned_pull_subscriber_t`. The pulled data will be provided - * by calling the **callback** function provided to the :c:func:`z_declare_subscriber` function. - * - * Parameters: - * sub: The :c:type:`z_owned_pull_subscriber_t` to pull from. - */ -ZENOHC_API int8_t z_subscriber_pull(struct z_pull_subscriber_t sub); ZENOHC_API int8_t z_task_init(struct z_task_t *task, const struct z_task_attr_t *_attr, @@ -2193,11 +2106,6 @@ ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned */ ZENOHC_API int8_t z_undeclare_publisher(struct z_owned_publisher_t *publisher); -/** - * Undeclares the given :c:type:`z_owned_pull_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -int8_t z_undeclare_pull_subscriber(struct z_owned_pull_subscriber_t *sub); /** * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. * diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 44f208496..8572e956b 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -51,28 +51,6 @@ typedef struct z_query_t { typedef struct z_session_t { size_t _0; } z_session_t; -/** - * An owned zenoh pull subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_pull_subscriber_t { - uint64_t _0[1]; -} z_owned_pull_subscriber_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_pull_subscriber_t { - uint32_t _0[1]; -} z_owned_pull_subscriber_t; -#endif /** * An owned zenoh queryable. * diff --git a/splitguide.yaml b/splitguide.yaml index 4cb19de82..5469f25de 100644 --- a/splitguide.yaml +++ b/splitguide.yaml @@ -9,6 +9,5 @@ zenoh_concrete.h: - z_owned_session_t! - z_session_t! - z_owned_subscriber_t! - - z_owned_pull_subscriber_t! - z_query_t! - z_owned_queryable_t! diff --git a/src/commons.rs b/src/commons.rs index 6c76669b7..2d4e76888 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -131,7 +131,7 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { - Some(sample.encoding()).into() + sample.encoding().into() } /// The sample's data, the return value aliases the sample. /// @@ -232,8 +232,7 @@ pub struct z_encoding_t([u64; 4]); #[repr(C, align(4))] pub struct z_encoding_t([u32; 4]); -impl_guarded_transmute!(Option<&'static Encoding>, z_encoding_t); -impl_guarded_transmute!(z_encoding_t, Option<&'static Encoding>); +impl_guarded_transmute!(&'static Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -246,16 +245,21 @@ impl_guarded_transmute!(z_encoding_t, Option<&'static Encoding>); #[repr(C, align(8))] pub struct z_owned_encoding_t([u64; 4]); +impl Drop for z_owned_encoding_t { + fn drop(&mut self) { + } +} + #[cfg(target_arch = "arm")] #[repr(C, align(4))] pub struct z_owned_encoding_t([u32; 4]); -impl_guarded_transmute!(Option, z_owned_encoding_t); +impl_guarded_transmute!(Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null() -> z_owned_encoding_t { - None::.into() + Encoding::default().into() } /// Constructs a specific :c:type:`z_encoding_t`. @@ -266,7 +270,7 @@ pub unsafe extern "C" fn z_encoding_from_str(s: *const c_char) -> z_owned_encodi z_encoding_null() } else { let s = CStr::from_ptr(s).to_string_lossy().as_ref(); - Some(Encoding::from(s)).into() + Encoding::from(s).into() } } @@ -274,7 +278,7 @@ pub unsafe extern "C" fn z_encoding_from_str(s: *const c_char) -> z_owned_encodi #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - let encoding = Some(&Encoding::default()); + let encoding = &Encoding::ZENOH_BYTES; encoding.into() } @@ -282,14 +286,14 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - std::mem::drop(encoding.take()); + std::mem::drop(std::mem::replace(encoding, z_encoding_null())); } /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { - encoding.is_some() + *encoding == Encoding::default() } /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. diff --git a/src/info.rs b/src/info.rs index 326b468bb..11ef031b3 100644 --- a/src/info.rs +++ b/src/info.rs @@ -13,7 +13,7 @@ // use crate::{session::*, z_closure_zid_call, z_owned_closure_zid_t}; use zenoh::prelude::sync::SyncResolve; -use zenoh::SessionDeclarations; +use zenoh::session::SessionDeclarations; use zenoh_protocol::core::ZenohId; /// Represents a Zenoh ID. diff --git a/src/lib.rs b/src/lib.rs index 20f766352..25d2a7fb8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,8 +41,8 @@ mod session; pub use crate::session::*; mod subscriber; pub use crate::subscriber::*; -mod pull_subscriber; -pub use crate::pull_subscriber::*; +// mod pull_subscriber; +// pub use crate::pull_subscriber::*; mod publisher; pub use crate::publisher::*; mod closures; diff --git a/src/publisher.rs b/src/publisher.rs index 73b14f6a3..26b355897 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -15,7 +15,9 @@ use crate::zcu_closure_matching_status_call; use crate::zcu_owned_closure_matching_status_t; use std::ops::{Deref, DerefMut}; +use zenoh::encoding::Encoding; use zenoh::prelude::SessionDeclarations; +use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; use zenoh::{ @@ -264,6 +266,7 @@ pub unsafe extern "C" fn z_publisher_put( }; let put = match options { Some(options) => { + let encoding = *options.encoding; let mut put = p.put(payload).encoding(options.encoding.into()); if z_attachment_check(&options.attachment) { let mut attachment_builder = AttachmentBuilder::new(); diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 910f1b89b..6f78d6bb9 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -16,13 +16,12 @@ use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh::prelude::SessionDeclarations; use zenoh_ext::*; -use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; use crate::{ impl_guarded_transmute, z_closure_sample_call, z_get_options_t, z_keyexpr_t, z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, - z_query_target_default, z_query_target_t, z_reliability_t, z_sample_t, z_session_t, + z_query_target_default, z_query_target_t, z_sample_t, z_session_t, zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, LOG_INVALID_SESSION, }; @@ -94,7 +93,7 @@ pub extern "C" fn ze_querying_subscriber_null() -> ze_owned_querying_subscriber_ #[repr(C)] #[allow(non_camel_case_types)] pub struct ze_querying_subscriber_options_t { - reliability: z_reliability_t, + // reliability: z_reliability_t, allowed_origin: zcu_locality_t, query_selector: z_keyexpr_t, query_target: z_query_target_t, @@ -107,7 +106,7 @@ pub struct ze_querying_subscriber_options_t { #[no_mangle] pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscriber_options_t { ze_querying_subscriber_options_t { - reliability: SubInfo::default().reliability.into(), + // reliability: SubInfo::default().reliability.into(), allowed_origin: zcu_locality_default(), query_selector: z_keyexpr_t::null(), query_target: z_query_target_default(), @@ -164,7 +163,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( let mut sub = s.declare_subscriber(keyexpr).querying(); if let Some(options) = options { sub = sub - .reliability(options.reliability.into()) + // .reliability(options.reliability.into()) .allowed_origin(options.allowed_origin.into()) .query_target(options.query_target.into()) .query_consolidation(options.query_consolidation) diff --git a/src/session.rs b/src/session.rs index 2caab85ea..f710e1703 100644 --- a/src/session.rs +++ b/src/session.rs @@ -15,7 +15,7 @@ use crate::{config::*, impl_guarded_transmute, zc_init_logger}; use std::sync::{Arc, Weak}; use zenoh::prelude::sync::SyncResolve; -use zenoh::Session; +use zenoh::session::Session; use zenoh_util::core::zresult::ErrNo; /// An owned zenoh session. diff --git a/src/subscriber.rs b/src/subscriber.rs index d82086f7f..acdae4f60 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -21,41 +21,41 @@ use crate::z_owned_closure_sample_t; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -use zenoh::subscriber::Reliability; -use zenoh_protocol::core::SubInfo; +// use zenoh::subscriber::Reliability; +// use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; /// The subscription reliability. /// /// - **Z_RELIABILITY_BEST_EFFORT** /// - **Z_RELIABILITY_RELIABLE** -#[allow(non_camel_case_types, clippy::upper_case_acronyms)] -#[repr(C)] -#[derive(Clone, Copy)] -pub enum z_reliability_t { - BEST_EFFORT, - RELIABLE, -} - -impl From for z_reliability_t { - #[inline] - fn from(r: Reliability) -> Self { - match r { - Reliability::BestEffort => z_reliability_t::BEST_EFFORT, - Reliability::Reliable => z_reliability_t::RELIABLE, - } - } -} - -impl From for Reliability { - #[inline] - fn from(val: z_reliability_t) -> Self { - match val { - z_reliability_t::BEST_EFFORT => Reliability::BestEffort, - z_reliability_t::RELIABLE => Reliability::Reliable, - } - } -} +// #[allow(non_camel_case_types, clippy::upper_case_acronyms)] +// #[repr(C)] +// #[derive(Clone, Copy)] +// pub enum z_reliability_t { +// BEST_EFFORT, +// RELIABLE, +// } + +// impl From for z_reliability_t { +// #[inline] +// fn from(r: Reliability) -> Self { +// match r { +// Reliability::BestEffort => z_reliability_t::BEST_EFFORT, +// Reliability::Reliable => z_reliability_t::RELIABLE, +// } +// } +// } + +// impl From for Reliability { +// #[inline] +// fn from(val: z_reliability_t) -> Self { +// match val { +// z_reliability_t::BEST_EFFORT => Reliability::BestEffort, +// z_reliability_t::RELIABLE => Reliability::Reliable, +// } +// } +// } /**************************************/ /* DECLARATION */ @@ -122,15 +122,15 @@ pub extern "C" fn z_subscriber_loan(p: &z_owned_subscriber_t) -> z_subscriber_t #[allow(non_camel_case_types)] #[repr(C)] pub struct z_subscriber_options_t { - pub reliability: z_reliability_t, + // pub reliability: z_reliability_t, } /// Constructs the default value for :c:type:`z_subscriber_options_t`. #[no_mangle] pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { - let info = SubInfo::default(); + // let info = SubInfo::default(); z_subscriber_options_t { - reliability: info.reliability.into(), + // reliability: info.reliability.into(), } } @@ -183,7 +183,7 @@ pub extern "C" fn z_declare_subscriber( z_closure_sample_call(&closure, &sample) }); if let Some(opts) = opts { - res = res.reliability(opts.reliability.into()) + // res = res.reliability(opts.reliability.into()) } match res.res() { Ok(sub) => z_owned_subscriber_t::new(sub), From d98c79a8a98f54942647b8bbbd704430995d9972 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Apr 2024 22:43:34 +0200 Subject: [PATCH 030/377] transmute size compile errors --- Cargo.toml | 4 +-- Cargo.toml.in | 2 +- src/commons.rs | 17 +++++++--- src/get.rs | 51 +++++++++++++----------------- src/keyexpr.rs | 1 + src/publisher.rs | 2 +- src/put.rs | 10 ++++-- src/queryable.rs | 80 ++++++++++++++++-------------------------------- 8 files changed, 72 insertions(+), 95 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 34366e392..e4d32cfdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ unwrap-infallible = "0.1.5" zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } zenoh-util = { path = "../zenoh/commons/zenoh-util" } -zenoh-ext = { path = "../zenoh/zenoh-ext" } +zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} [build-dependencies] cbindgen = "0.26.0" @@ -70,7 +70,7 @@ serde_yaml = "0.9.19" [lib] path="src/lib.rs" -name = "zenohcd" +name = "zenohc" crate-type = ["cdylib", "staticlib"] doctest = false diff --git a/Cargo.toml.in b/Cargo.toml.in index d31b3d0c6..59dbda418 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -60,7 +60,7 @@ unwrap-infallible = "0.1.5" zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } zenoh-util = { path = "../zenoh/commons/zenoh-util" } -zenoh-ext = { path = "../zenoh/zenoh-ext" } +zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} [build-dependencies] cbindgen = "0.26.0" diff --git a/src/commons.rs b/src/commons.rs index 2d4e76888..0b23a1eec 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -14,6 +14,7 @@ use std::ffi::CStr; use std::ops::Deref; +use std::ops::DerefMut; use crate::collections::*; use crate::keyexpr::*; @@ -26,7 +27,10 @@ use crate::zc_payload_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; +use std::convert::Infallible; +use unwrap_infallible::UnwrapInfallible; use zenoh::buffers::ZBuf; +use zenoh::encoding; use zenoh::encoding::Encoding; use zenoh::payload::Deserialize; use zenoh::payload::ZSerde; @@ -35,8 +39,6 @@ use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::Sample; use zenoh_protocol::core::Timestamp; -use unwrap_infallible::UnwrapInfallible; -use std::convert::Infallible; use crate::attachment::{attachment_iteration_driver, z_attachment_null, z_attachment_t}; @@ -247,6 +249,8 @@ pub struct z_owned_encoding_t([u64; 4]); impl Drop for z_owned_encoding_t { fn drop(&mut self) { + let encoding = self.deref_mut(); + *encoding = Encoding::default(); } } @@ -286,21 +290,24 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - std::mem::drop(std::mem::replace(encoding, z_encoding_null())); + let encoding = encoding.deref_mut(); + *encoding = Encoding::default(); } /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { - *encoding == Encoding::default() + let encoding = encoding.deref(); + *encoding != Encoding::default() } /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { - encoding.as_ref().into() + let encoding = encoding.deref(); + encoding.into() } /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` diff --git a/src/get.rs b/src/get.rs index 0effcc28a..6fd6aff43 100644 --- a/src/get.rs +++ b/src/get.rs @@ -14,14 +14,16 @@ use libc::c_char; use libc::c_void; -use zenoh::encoding::Encoding; -use zenoh::payload; use std::{ convert::TryFrom, ffi::CStr, ops::{Deref, DerefMut}, }; use zenoh::buffers::ZBuf; +use zenoh::encoding::Encoding; +use zenoh::payload; +use zenoh::sample::SampleBuilderTrait; +use zenoh::sample::ValueBuilderTrait; use zenoh::{ prelude::{ConsolidationMode, KeyExpr, QueryTarget}, @@ -107,9 +109,8 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { } /// A zenoh value. -/// -/// - +/// +/// #[repr(C)] #[cfg(not(target_arch = "arm"))] @@ -129,7 +130,18 @@ pub struct z_value_t([u64; 4]); pub struct z_value_t([u32; 4]); impl_guarded_transmute!(Value, z_owned_value_t); -impl_guarded_transmute!(Option<&'static Value>, z_value_t); +impl_guarded_transmute!(&'static Value, z_value_t); + +const Z_VALUE_NULL: Value = Value::empty(); + +impl From> for z_value_t { + fn from(val: Option<&Value>) -> Self { + match val { + Some(val) => val.transmute(), + None => (&Z_VALUE_NULL).transmute(), + } + } +} /// Yields the contents of the reply by asserting it indicates a failure. /// @@ -228,9 +240,8 @@ pub unsafe extern "C" fn z_get( if let Some(payload) = options.payload.take() { let mut value = Value::new(payload); - let encoding: Option<&Encoding> = options.encoding.into(); - value.encoding = encoding.cloned().unwrap_or_default(); - q = q.with_value(value); + value.encoding = **options.encoding; + q = q.value(value); } if options.timeout_ms != 0 { q = q.timeout(std::time::Duration::from_millis(options.timeout_ms)); @@ -242,7 +253,7 @@ pub unsafe extern "C" fn z_get( insert_in_attachment_builder, &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, ); - q = q.with_attachment(attachment_builder.build()); + q = q.attachment(attachment_builder.build()); }; } match q @@ -306,26 +317,6 @@ impl From for QueryTarget { } } -impl From<&z_value_t> for Value { - #[inline] - fn from(val: &z_value_t) -> Value { - let payload: Option<&ZBuf> = val.payload.into(); - let payload = match payload { - Some(b) => b.clone(), - None => ZBuf::empty(), - }; - let encoding = unsafe { - std::str::from_utf8(std::slice::from_raw_parts( - val.encoding.suffix.start, - val.encoding.suffix.len, - )) - .expect("encodings must be UTF8") - }; - let v = Value::new(payload); - v.encoding(zenoh::prelude::Encoding::new(val.encoding.prefix as u8, encoding).unwrap()) - } -} - /// Create a default :c:type:`z_query_target_t`. #[no_mangle] pub extern "C" fn z_query_target_default() -> z_query_target_t { diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 51c47d211..c88b01199 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -24,6 +24,7 @@ use crate::z_str_null; use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use libc::c_char; +use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; diff --git a/src/publisher.rs b/src/publisher.rs index 26b355897..47f2bb71f 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -267,7 +267,7 @@ pub unsafe extern "C" fn z_publisher_put( let put = match options { Some(options) => { let encoding = *options.encoding; - let mut put = p.put(payload).encoding(options.encoding.into()); + let mut put = p.put(payload).encoding(*encoding); if z_attachment_check(&options.attachment) { let mut attachment_builder = AttachmentBuilder::new(); z_attachment_iterate( diff --git a/src/put.rs b/src/put.rs index 5e2d59aec..a0c2e88d0 100644 --- a/src/put.rs +++ b/src/put.rs @@ -17,9 +17,13 @@ use crate::session::*; use crate::zc_owned_payload_t; use crate::LOG_INVALID_SESSION; use libc::c_void; +use zenoh::encoding; use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; use zenoh::publication::CongestionControl; use zenoh::sample::AttachmentBuilder; +use zenoh::sample::QoSBuilderTrait; +use zenoh::sample::SampleBuilderTrait; +use zenoh::sample::ValueBuilderTrait; use zenoh_util::core::zresult::ErrNo; use crate::attachment::{ @@ -161,10 +165,10 @@ pub extern "C" fn z_put( match session.upgrade() { Some(s) => { if let Some(payload) = payload.and_then(|p| p.take()) { - let mut res = s.put(keyexpr, payload).kind(SampleKind::Put); + let mut res = s.put(keyexpr, payload); if let Some(opts) = opts { res = res - .encoding(opts.encoding) + .encoding(**opts.encoding) .congestion_control(opts.congestion_control.into()) .priority(opts.priority.into()); if z_attachment_check(&opts.attachment) { @@ -174,7 +178,7 @@ pub extern "C" fn z_put( insert_in_attachment_builder, &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, ); - res = res.with_attachment(attachment_builder.build()); + res = res.attachment(attachment_builder.build()); }; } match res.res_sync() { diff --git a/src/queryable.rs b/src/queryable.rs index dd932188c..e6ca2195d 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -100,27 +100,8 @@ impl Deref for z_query_t { #[repr(C)] pub struct z_owned_query_t(*mut c_void); -impl From> for z_owned_query_t { - fn from(value: Option) -> Self { - unsafe { core::mem::transmute(value) } - } -} -impl From for z_owned_query_t { - fn from(value: Query) -> Self { - Some(value).into() - } -} -impl Deref for z_owned_query_t { - type Target = Option; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} -impl DerefMut for z_owned_query_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { core::mem::transmute(self) } - } -} +impl_guarded_transmute!(Option, z_owned_query_t); + impl Drop for z_owned_query_t { fn drop(&mut self) { let _: Option = self.take(); @@ -129,7 +110,7 @@ impl Drop for z_owned_query_t { /// The gravestone value of `z_owned_query_t`. #[no_mangle] pub extern "C" fn z_query_null() -> z_owned_query_t { - unsafe { core::mem::transmute(None::) } + None.into() } /// Returns `false` if `this` is in a gravestone state, `true` otherwise. /// @@ -287,26 +268,28 @@ pub unsafe extern "C" fn z_query_reply( return i8::MIN; }; if let Some(key) = &*key { - if let Some(payload) = payload.and_then(|p| p.take()) { - let mut s = Sample::new(key.clone().into_owned(), payload); - if let Some(o) = options { - s.encoding = o.encoding.into(); - if z_attachment_check(&o.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - o.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - s = s.with_attachment(attachment_builder.build()); - }; - } - if let Err(e) = query.reply(Ok(s)).res_sync() { - log::error!("{}", e); - return e.errno().get(); - } - return 0; - } + // TODO: reimplement with reply builder + // + // if let Some(payload) = payload.and_then(|p| p.take()) { + // let mut s = Sample::new(key.clone().into_owned(), payload); + // if let Some(o) = options { + // s.encoding = o.encoding.into(); + // if z_attachment_check(&o.attachment) { + // let mut attachment_builder = AttachmentBuilder::new(); + // z_attachment_iterate( + // o.attachment, + // insert_in_attachment_builder, + // &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, + // ); + // s = s.with_attachment(attachment_builder.build()); + // }; + // } + // if let Err(e) = query.reply(Ok(s)).res_sync() { + // log::error!("{}", e); + // return e.errno().get(); + // } + // return 0; + // } } i8::MIN } @@ -341,17 +324,8 @@ pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_bytes_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_value(query: &z_query_t) -> z_value_t { - match query.as_ref().and_then(|q| q.value()) { - Some(value) => - { - #[allow(mutable_transmutes)] - value.into() - } - None => z_value_t { - payload: zc_payload_t::default(), - encoding: z_encoding_default(), - }, - } + let v = query.as_ref().and_then(|q| q.value()); + v.into() } /// Returns the attachment to the query by aliasing. From 087210dae253f7239777833e37fe402e353bcd21 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 11 Apr 2024 11:22:31 +0200 Subject: [PATCH 031/377] merge main into protocol_changes --- build.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/build.rs b/build.rs index 5b0585cd5..f8df08447 100644 --- a/build.rs +++ b/build.rs @@ -2,7 +2,6 @@ use fs2::FileExt; use regex::Regex; use std::env; use std::io::{Read, Write}; -use std::path::PathBuf; use std::process::{Command, Stdio}; use std::{ borrow::Cow, @@ -32,8 +31,6 @@ const HEADER: &str = r"// #endif "; -use std::env; - fn main() { generate_opaque_types(); cbindgen::generate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) @@ -60,27 +57,6 @@ fn main() { println!("cargo:rerun-if-changed=include"); } -// See: https://github.com/rust-lang/cargo/issues/9661 -// See: https://github.com/rust-lang/cargo/issues/545 -fn cargo_target_dir() -> PathBuf { - let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR should be set")); - let profile = env::var("PROFILE").expect("PROFILE should be set"); - - let mut target_dir = None; - let mut out_dir_path = out_dir.as_path(); - while let Some(parent) = out_dir_path.parent() { - if parent.ends_with(&profile) { - target_dir = Some(parent); - break; - } - out_dir_path = parent; - } - - target_dir - .expect("OUT_DIR should be a child of a PROFILE directory") - .to_path_buf() -} - fn get_build_rs_path() -> PathBuf { let file_path = file!(); let mut path_buf = PathBuf::new(); From f41fb5ab8499bbe882420f766bf49d46c41834ac Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 11 Apr 2024 17:32:35 +0200 Subject: [PATCH 032/377] compilation fix unfinished --- Cargo.lock | 46 ++++--- build-resources/opaque-types/Cargo.lock | 154 +++++++++++++++++++++--- build-resources/opaque-types/Cargo.toml | 3 +- build-resources/opaque-types/src/lib.rs | 22 +++- include/zenoh_commons.h | 78 ++---------- src/closures/query_channel.rs | 4 +- src/commons.rs | 25 ++-- src/get.rs | 29 +---- src/queryable.rs | 5 +- 9 files changed, 206 insertions(+), 160 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a78021705..072e2a981 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -629,9 +629,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" dependencies = [ "anstream", "anstyle", @@ -976,9 +976,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1213,9 +1213,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" dependencies = [ "value-bag", ] @@ -1899,9 +1899,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" dependencies = [ "log", "ring 0.17.6", @@ -2470,7 +2470,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.2", + "rustls 0.22.3", "rustls-pki-types", "tokio", ] @@ -2719,9 +2719,9 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.4.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" [[package]] name = "vec_map" @@ -3063,7 +3063,7 @@ dependencies = [ "async-trait", "base64", "const_format", - "env_logger 0.11.2", + "env_logger 0.11.3", "event-listener 4.0.0", "flume", "form_urlencoded", @@ -3088,6 +3088,7 @@ dependencies = [ "tokio", "tokio-util", "uhlc", + "unwrap-infallible", "uuid", "vec_map", "zenoh-buffers", @@ -3105,6 +3106,7 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-transport", "zenoh-util", ] @@ -3206,7 +3208,7 @@ name = "zenoh-ext" version = "0.11.0-dev" dependencies = [ "bincode", - "env_logger 0.11.2", + "env_logger 0.11.3", "flume", "futures", "log", @@ -3256,7 +3258,7 @@ dependencies = [ "flume", "futures", "log", - "rustls 0.22.2", + "rustls 0.22.3", "rustls-webpki 0.102.2", "serde", "tokio", @@ -3322,7 +3324,7 @@ dependencies = [ "base64", "futures", "log", - "rustls 0.22.2", + "rustls 0.22.3", "rustls-pemfile 2.0.0", "rustls-pki-types", "rustls-webpki 0.102.2", @@ -3449,6 +3451,7 @@ dependencies = [ name = "zenoh-runtime" version = "0.11.0-dev" dependencies = [ + "futures", "lazy_static", "tokio", "zenoh-collections", @@ -3479,6 +3482,18 @@ dependencies = [ "zenoh-runtime", ] +[[package]] +name = "zenoh-task" +version = "0.11.0-dev" +dependencies = [ + "futures", + "log", + "tokio", + "tokio-util", + "zenoh-core", + "zenoh-runtime", +] + [[package]] name = "zenoh-transport" version = "0.11.0-dev" @@ -3507,6 +3522,7 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-util", ] diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index a6f37dab3..d7276add6 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -383,6 +383,12 @@ version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.6.0" @@ -833,6 +839,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + [[package]] name = "hashbrown" version = "0.13.2" @@ -930,6 +942,12 @@ dependencies = [ "serde", ] +[[package]] +name = "iter-read" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c397ca3ea05ad509c4ec451fea28b4771236a376ca1c69fd5143aae0cf8f93c4" + [[package]] name = "itoa" version = "1.0.11" @@ -1119,6 +1137,26 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -1248,6 +1286,48 @@ dependencies = [ "indexmap", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1596,6 +1676,29 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-pickle" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762ad136a26407c6a80825813600ceeab5e613660d93d79a41f0ec877171e71" +dependencies = [ + "byteorder", + "iter-read", + "num-bigint", + "num-traits", + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.197" @@ -1694,6 +1797,12 @@ dependencies = [ "libc", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -1926,6 +2035,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "unzip-n" version = "0.1.2" @@ -2291,7 +2406,6 @@ checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-trait", "base64", @@ -2307,16 +2421,21 @@ dependencies = [ "ordered-float", "paste", "petgraph", + "phf", "rand", "regex", "rustc_version", "serde", + "serde-pickle", + "serde_cbor", "serde_json", + "serde_yaml", "socket2 0.5.6", "stop-token", "tokio", "tokio-util", "uhlc", + "unwrap-infallible", "uuid", "vec_map", "zenoh-buffers", @@ -2334,6 +2453,7 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-transport", "zenoh-util", ] @@ -2341,7 +2461,6 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "zenoh-collections", ] @@ -2349,7 +2468,6 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "log", "serde", @@ -2362,12 +2480,10 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "flume", "json5", @@ -2387,7 +2503,6 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-global-executor", "lazy_static", @@ -2399,7 +2514,6 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "aes", "hmac", @@ -2412,7 +2526,6 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "hashbrown 0.14.3", "keyed-set", @@ -2426,7 +2539,6 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-trait", "zenoh-config", @@ -2438,7 +2550,6 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-trait", "flume", @@ -2461,7 +2572,6 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "proc-macro2", "quote", @@ -2472,7 +2582,6 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "const_format", "libloading", @@ -2488,7 +2597,6 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "const_format", "rand", @@ -2502,7 +2610,6 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "anyhow", ] @@ -2510,8 +2617,8 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ + "futures", "lazy_static", "tokio", "zenoh-collections", @@ -2521,7 +2628,6 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "log", "serde", @@ -2533,7 +2639,6 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "event-listener 4.0.3", "futures", @@ -2544,10 +2649,21 @@ dependencies = [ "zenoh-runtime", ] +[[package]] +name = "zenoh-task" +version = "0.11.0-dev" +dependencies = [ + "futures", + "log", + "tokio", + "tokio-util", + "zenoh-core", + "zenoh-runtime", +] + [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-trait", "flume", @@ -2572,13 +2688,13 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-util", ] [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-std", "async-trait", diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml index 6e8319bb0..51bf417a7 100644 --- a/build-resources/opaque-types/Cargo.toml +++ b/build-resources/opaque-types/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } \ No newline at end of file +# zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } +zenoh = { path="../../../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } \ No newline at end of file diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 354e8d999..4a9ebd013 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,13 +1,18 @@ -use zenoh::sample::Sample; use zenoh::buffers::{ZBuf, ZBufReader}; +use zenoh::encoding::Encoding; +use zenoh::query::Reply; +use zenoh::queryable::Query; +use zenoh::sample::Sample; +use zenoh::value::Value; #[macro_export] macro_rules! get_opaque_type_data { -($src_type:ty, $expr:expr) => { + ($src_type:ty, $expr:expr) => { const _: () = { let align = std::mem::align_of::<$src_type>(); let size = std::mem::size_of::<$src_type>(); - let mut msg: [u8; 61] = *b"type: , align: , size: "; + let mut msg: [u8; 61] = + *b"type: , align: , size: "; let mut i = 0; while i < 4 { msg[i as usize + 46] = b'0' + ((align / 10u32.pow(3 - i) as usize) % 10) as u8; @@ -23,7 +28,7 @@ macro_rules! get_opaque_type_data { std::str::from_utf8_unchecked(msg.as_slice()) }); }; - } + }; } /// A split buffer that owns all of its data. @@ -38,4 +43,11 @@ get_opaque_type_data!(Option, "z_owned_buffer_t"); get_opaque_type_data!(Option, "zc_owned_sample_t"); /// A reader for payload data. -get_opaque_type_data!(ZBufReader, "zc_payload_reader"); \ No newline at end of file +get_opaque_type_data!(ZBufReader, "zc_payload_reader"); + +get_opaque_type_data!(&'static Encoding, "z_encoding_t"); +get_opaque_type_data!(Encoding, "z_owned_encoding_t"); +get_opaque_type_data!(Option, "z_owned_reply_t"); +get_opaque_type_data!(Value, "z_owned_value_t"); +get_opaque_type_data!(&'static Value, "z_value_t"); +get_opaque_type_data!(Option, "z_owned_query_t"); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index f0048010b..2b35df84e 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -243,18 +243,8 @@ typedef struct z_owned_closure_hello_t { void (*call)(struct z_owned_hello_t*, void*); void (*drop)(void*); } z_owned_closure_hello_t; -/** - * Owned variant of a Query received by a Queryable. - * - * You may construct it by `z_query_clone`-ing a loaned query. - * When the last `z_owned_query_t` corresponding to a query is destroyed, or the callback that produced the query cloned to build them returns, - * the query will receive its termination signal. - * - * Holding onto an `z_owned_query_t` for too long (10s by default, can be set in `z_get`'s options) will trigger a timeout error - * to be sent to the querier by the infrastructure, and new responses to the outdated query will be silently dropped. - */ -typedef struct z_owned_query_t { - void *_0; +typedef struct ALIGN(8) z_owned_query_t { + uint8_t _0[16]; } z_owned_query_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: @@ -298,25 +288,9 @@ typedef struct z_owned_closure_query_t { void (*call)(const struct z_query_t*, void *context); void (*drop)(void*); } z_owned_closure_query_t; -/** - * An owned reply to a :c:func:`z_get`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_reply_t { - uint64_t _0[30]; -} z_owned_reply_t; -#endif -#if defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_reply_t { - uint64_t _0[19]; + uint8_t _0[256]; } z_owned_reply_t; -#endif /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * @@ -539,41 +513,12 @@ typedef struct z_delete_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_delete_options_t; -/** - * An owned payload encoding. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_encoding_t { - uint64_t _0[4]; -} z_owned_encoding_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_encoding_t { - uint32_t _0[4]; + uint8_t _0[48]; } z_owned_encoding_t; -#endif -/** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. - * - */ -#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_encoding_t { - uint64_t _0[4]; -} z_encoding_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_encoding_t { - uint32_t _0[4]; + uint8_t _0[8]; } z_encoding_t; -#endif /** * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. */ @@ -714,16 +659,9 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; -#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_value_t { - uint64_t _0[4]; -} z_value_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_value_t { - uint32_t _0[4]; + uint8_t _0[8]; } z_value_t; -#endif /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -823,7 +761,7 @@ typedef struct ALIGN(8) zc_payload_reader { * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. */ typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[224]; + uint8_t _0[240]; } zc_owned_sample_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; @@ -1965,7 +1903,7 @@ ZENOHC_API struct z_attachment_t z_sample_attachment(const struct z_sample_t *sa /** * The encoding of the payload. */ -ZENOHC_API struct z_encoding_t z_sample_encoding(const struct z_sample_t *sample); +ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); /** * The Key Expression of the sample. * diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index b7a51c9c0..b964add61 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -80,7 +80,7 @@ pub extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { send, recv: From::from(move |receptacle: &mut z_owned_query_t| { *receptacle = match rx.recv() { - Ok(val) => val.into(), + Ok(val) => Some(val).into(), Err(_) => None.into(), }; true @@ -129,7 +129,7 @@ pub extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned_query_ recv: From::from( move |receptacle: &mut z_owned_query_t| match rx.try_recv() { Ok(val) => { - let mut tmp = z_owned_query_t::from(val); + let mut tmp = z_owned_query_t::from(Some(val)); std::mem::swap(&mut tmp, receptacle); true } diff --git a/src/commons.rs b/src/commons.rs index 0b23a1eec..13ff43a0d 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -132,7 +132,9 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { } /// The encoding of the payload. #[no_mangle] -pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { +pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { + let encoding = sample.encoding(); + sample.encoding().into() } /// The sample's data, the return value aliases the sample. @@ -226,15 +228,8 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_encoding_t([u64; 4]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_encoding_t([u32; 4]); - -impl_guarded_transmute!(&'static Encoding, z_encoding_t); +pub use crate::z_encoding_t; +impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -243,9 +238,8 @@ impl_guarded_transmute!(&'static Encoding, z_encoding_t); /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_encoding_t([u64; 4]); +pub use crate::z_owned_encoding_t; +impl_guarded_transmute!(Encoding, z_owned_encoding_t); impl Drop for z_owned_encoding_t { fn drop(&mut self) { @@ -254,11 +248,6 @@ impl Drop for z_owned_encoding_t { } } -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_encoding_t([u32; 4]); - -impl_guarded_transmute!(Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] diff --git a/src/get.rs b/src/get.rs index 6fd6aff43..37ed192e0 100644 --- a/src/get.rs +++ b/src/get.rs @@ -55,14 +55,7 @@ type ReplyInner = Option; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_reply_t([u64; 30]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(8))] -pub struct z_owned_reply_t([u64; 19]); - +pub use crate::z_owned_reply_t; impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); impl From for z_owned_reply_t { @@ -111,25 +104,9 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { /// A zenoh value. /// /// - -#[repr(C)] -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_value_t([u64; 4]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_value_t([u32; 4]); - -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_value_t([u64; 4]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_value_t([u32; 4]); - +pub use crate::z_owned_value_t; impl_guarded_transmute!(Value, z_owned_value_t); +pub use crate::z_value_t; impl_guarded_transmute!(&'static Value, z_value_t); const Z_VALUE_NULL: Value = Value::empty(); diff --git a/src/queryable.rs b/src/queryable.rs index e6ca2195d..5d21824f4 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -96,10 +96,7 @@ impl Deref for z_query_t { /// /// Holding onto an `z_owned_query_t` for too long (10s by default, can be set in `z_get`'s options) will trigger a timeout error /// to be sent to the querier by the infrastructure, and new responses to the outdated query will be silently dropped. -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct z_owned_query_t(*mut c_void); - +pub use crate::z_owned_query_t; impl_guarded_transmute!(Option, z_owned_query_t); impl Drop for z_owned_query_t { From 95d059013dd7915358ac67a9d1113cbd4c690100 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 12 Apr 2024 19:27:43 +0200 Subject: [PATCH 033/377] transmute rework --- build.rs | 3 +- include/zenoh_commons.h | 4 +- src/commons.rs | 40 ++++++------ src/lib.rs | 3 + src/queryable.rs | 11 ++-- src/transmute.rs | 140 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 173 insertions(+), 28 deletions(-) create mode 100644 src/transmute.rs diff --git a/build.rs b/build.rs index f8df08447..89fffff0d 100644 --- a/build.rs +++ b/build.rs @@ -96,7 +96,8 @@ fn generate_opaque_types() { let re = Regex::new(r"type:(\w+) *, align:0*(\d+), size:0*(\d+)").unwrap(); for (_, [type_name, align, size]) in re.captures_iter(&data_in).map(|c| c.extract()) { let s = format!( - "#[repr(C, align({align}))] + "#[derive(Copy, Clone)] +#[repr(C, align({align}))] pub struct {type_name} {{ _0: [u8; {size}], }} diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 2b35df84e..689944ae2 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1373,7 +1373,7 @@ ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); /** * Constructs a specific :c:type:`z_encoding_t`. */ -ZENOHC_API struct z_owned_encoding_t z_encoding_from_str(const char *s); +ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); /** * Returns a :c:type:`z_encoding_t` loaned from `encoding`. */ @@ -1381,7 +1381,7 @@ ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t * /** * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type */ -ZENOHC_API struct z_owned_encoding_t z_encoding_null(void); +ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); /** * Query data from the matching queryables in the system. * Replies are provided through a callback function. diff --git a/src/commons.rs b/src/commons.rs index 13ff43a0d..ae2b9b744 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -15,9 +15,14 @@ use std::ffi::CStr; use std::ops::Deref; use std::ops::DerefMut; +use std::str::FromStr; use crate::collections::*; +use crate::decl_transmute_copy; use crate::keyexpr::*; +use crate::transmute::InplaceInit; +use crate::transmute::InplaceInitDefault; +use crate::transmute::TransmuteRef; use crate::z_congestion_control_t; use crate::z_id_t; use crate::z_owned_buffer_t; @@ -133,9 +138,8 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - let encoding = sample.encoding(); - - sample.encoding().into() + // let encoding = sample.encoding(); + // sample.encoding().transmute() } /// The sample's data, the return value aliases the sample. /// @@ -229,7 +233,9 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// pub use crate::z_encoding_t; -impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); +decl_transmute_copy!(&'static Encoding, z_encoding_t); + +// impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -239,31 +245,26 @@ impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. pub use crate::z_owned_encoding_t; -impl_guarded_transmute!(Encoding, z_owned_encoding_t); - -impl Drop for z_owned_encoding_t { - fn drop(&mut self) { - let encoding = self.deref_mut(); - *encoding = Encoding::default(); - } -} - +decl_transmute_ref!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] -pub extern "C" fn z_encoding_null() -> z_owned_encoding_t { - Encoding::default().into() +pub extern "C" fn z_encoding_null(encoding: &mut z_owned_encoding_t) { + encoding.transmute_mut().inplace_default(); } /// Constructs a specific :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding_from_str(s: *const c_char) -> z_owned_encoding_t { +pub unsafe extern "C" fn z_encoding_from_str(encoding: &mut z_owned_encoding_t, s: *const c_char) -> i8 { if s.is_null() { - z_encoding_null() + z_encoding_null(encoding); + 0 } else { let s = CStr::from_ptr(s).to_string_lossy().as_ref(); - Encoding::from(s).into() + let value = Encoding::from_str(s).unwrap_infallible(); + encoding.transmute_mut().inplace_init(value); + 0 } } @@ -279,8 +280,7 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - let encoding = encoding.deref_mut(); - *encoding = Encoding::default(); + } /// Returns ``true`` if `encoding` is valid. diff --git a/src/lib.rs b/src/lib.rs index 25d2a7fb8..90a7f27c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,9 @@ mod collections; use std::cmp::min; use std::slice; +#[macro_use] +mod transmute; + pub use crate::collections::*; mod config; pub use crate::config::*; diff --git a/src/queryable.rs b/src/queryable.rs index 5d21824f4..2fd38d296 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -99,11 +99,12 @@ impl Deref for z_query_t { pub use crate::z_owned_query_t; impl_guarded_transmute!(Option, z_owned_query_t); -impl Drop for z_owned_query_t { - fn drop(&mut self) { - let _: Option = self.take(); - } -} +// impl Drop for z_owned_query_t { +// fn drop(&mut self) { +// let _: Option = self.take(); +// } +// } + /// The gravestone value of `z_owned_query_t`. #[no_mangle] pub extern "C" fn z_query_null() -> z_owned_query_t { diff --git a/src/transmute.rs b/src/transmute.rs new file mode 100644 index 000000000..891c39ff8 --- /dev/null +++ b/src/transmute.rs @@ -0,0 +1,140 @@ +// +// Copyright (c) 2017, 2024 ZettaScale Technology. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh team, +// + +pub(crate) trait TransmuteRef { + fn transmute_ref(&self) -> &T; + fn transmute_mut(&mut self) -> &mut T; +} + +pub(crate) trait TransmuteCopy: TransmuteRef { + fn transmute(self) -> T; +} + + +pub(crate) trait InplaceInit: Sized { + // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized + fn inplace_init(&mut self, value: T) -> &mut Self { + unsafe { std::ptr::write(self as *mut Self as *mut T, value) }; + self + } + // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized + fn inplace_default(&mut self) -> &mut Self + where + T: Default, + { + unsafe { std::ptr::write(self as *mut Self as *mut T, T::default()) }; + self + } +} + +pub(crate) trait InplaceInitDefault: Default { + // Default implementation of inplace_init for object implementing Default trait. May be less efficient than a custom implementation + // because it involves a copy of the default value. + fn inplace_default_impl(&mut self) { + unsafe { std::ptr::write(self as *mut Self, Self::default()) }; + } +} + +// For types implementing Default, we can use provide default implementation of InplaceInit through InplaceInitDefault +impl InplaceInit for T { + fn inplace_default(&mut self) -> &mut Self { + self.inplace_default_impl(); + self + } +} + +macro_rules! validate_equivalence { + ($type_a:ty, $type_b:ty) => { + const _: () = { + let align_a = std::mem::align_of::<$type_a>(); + let align_b = std::mem::align_of::<$type_b>(); + if align_a != align_b { + panic!( + "Alingment mismatch: type `{}` has align {}, type `{}` has align {}", + stringify!($type_a), + align_a, + stringify!($type_b), + align_b + ); + } + let size_a = std::mem::size_of::<$type_a>(); + let size_b = std::mem::size_of::<$type_b>(); + if size_a != size_b { + panic!( + "Size mismatch: type `{}` has size {}, type `{}` has size {}", + stringify!($type_a), + size_a, + stringify!($type_b), + size_b + ); + } + }; + }; +} + +#[macro_export] +macro_rules! decl_transmute_ref { + (default_inplace_init $zenoh_type:ty, $c_type:ty) => { + impl InplaceInitDefault for $zenoh_type {} + decl_transmute_ref!(custom_inplace_init $zenoh_type, $c_type); + + }; + (custom_inplace_init $zenoh_type:ty, $c_type:ty) => { + validate_equivalence!($zenoh_type, $c_type); + impl_transmute_ref!($zenoh_type, $c_type); + impl_transmute_ref!($c_type, $zenoh_type); + impl InplaceInit<$zenoh_type> for $c_type { + fn inplace_init(&mut self, value: $zenoh_type) { + self.transmute_mut().inplace_init(value); + } + fn inplace_default(&mut self) { + self.transmute_mut().inplace_default(); + } + } + } +} + +#[macro_export] +macro_rules! decl_transmute_copy { + ($zenoh_type:ty, $c_type:ty) => { + validate_equivalence!($zenoh_type, $c_type); + impl_guarded_transmute_ref!($zenoh_type, $c_type); + impl_guarded_transmute_ref!($c_type, $zenoh_type); + impl_guarded_transmute_copy!($zenoh_type, $c_type); + impl_guarded_transmute_copy!($c_type, $zenoh_type); + }; +} + +macro_rules! impl_transmute_ref { + ($src_type:ty, $dst_type:ty) => { + impl $crate::transmute::TransmuteRef<$dst_type> for $src_type { + fn transmute_ref(&self) -> &$dst_type { + unsafe { std::mem::transmute::<&$src_type, &$dst_type>(self) } + } + fn transmute_mut(&mut self) -> &mut $dst_type { + unsafe { std::mem::transmute::<&mut $src_type, &mut $dst_type>(self) } + } + } + } +} + +macro_rules! impl_transmute_copy { + ($src_type:ty, $dst_type:ty) => { + impl $crate::transmute::TransmuteCopy<$dst_type> for $src_type { + fn transmute(self) -> $dst_type { + unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } + } + } + } +} From fb761dc37600dc123d314021629d0aa57bb689f0 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 12 Apr 2024 22:22:21 +0200 Subject: [PATCH 034/377] unfinished --- Cargo.lock | 2 -- Cargo.toml | 2 -- Cargo.toml.in | 2 -- src/commons.rs | 18 +++++++----------- src/transmute.rs | 19 ++++++++++--------- 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 072e2a981..336fce624 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3141,8 +3141,6 @@ dependencies = [ "unwrap-infallible", "zenoh", "zenoh-ext", - "zenoh-protocol", - "zenoh-util", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c2d338bd7..e3579e00e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,8 +58,6 @@ unwrap-infallible = "0.1.5" #zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } -zenoh-util = { path = "../zenoh/commons/zenoh-util" } zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} [build-dependencies] diff --git a/Cargo.toml.in b/Cargo.toml.in index a1f441b5d..b68560103 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -58,8 +58,6 @@ unwrap-infallible = "0.1.5" #zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } -zenoh-util = { path = "../zenoh/commons/zenoh-util" } zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} [build-dependencies] diff --git a/src/commons.rs b/src/commons.rs index ae2b9b744..345050822 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -35,15 +35,13 @@ use libc::{c_char, c_ulong}; use std::convert::Infallible; use unwrap_infallible::UnwrapInfallible; use zenoh::buffers::ZBuf; -use zenoh::encoding; -use zenoh::encoding::Encoding; use zenoh::payload::Deserialize; use zenoh::payload::ZSerde; use zenoh::prelude::SampleKind; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::Sample; -use zenoh_protocol::core::Timestamp; +use zenoh::time::Timestamp; use crate::attachment::{attachment_iteration_driver, z_attachment_null, z_attachment_t}; @@ -235,8 +233,6 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { pub use crate::z_encoding_t; decl_transmute_copy!(&'static Encoding, z_encoding_t); -// impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); - /// An owned payload encoding. /// /// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. @@ -256,7 +252,10 @@ pub extern "C" fn z_encoding_null(encoding: &mut z_owned_encoding_t) { /// Constructs a specific :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding_from_str(encoding: &mut z_owned_encoding_t, s: *const c_char) -> i8 { +pub unsafe extern "C" fn z_encoding_from_str( + encoding: &mut z_owned_encoding_t, + s: *const c_char, +) -> i8 { if s.is_null() { z_encoding_null(encoding); 0 @@ -272,16 +271,13 @@ pub unsafe extern "C" fn z_encoding_from_str(encoding: &mut z_owned_encoding_t, #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - let encoding = &Encoding::ZENOH_BYTES; - encoding.into() + let encoding = Encoding::ZENOH_BYTES; } /// Frees `encoding`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - -} +pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) {} /// Returns ``true`` if `encoding` is valid. #[no_mangle] diff --git a/src/transmute.rs b/src/transmute.rs index 891c39ff8..d4f7a5678 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -21,7 +21,6 @@ pub(crate) trait TransmuteCopy: TransmuteRef { fn transmute(self) -> T; } - pub(crate) trait InplaceInit: Sized { // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized fn inplace_init(&mut self, value: T) -> &mut Self { @@ -95,11 +94,13 @@ macro_rules! decl_transmute_ref { impl_transmute_ref!($zenoh_type, $c_type); impl_transmute_ref!($c_type, $zenoh_type); impl InplaceInit<$zenoh_type> for $c_type { - fn inplace_init(&mut self, value: $zenoh_type) { + fn inplace_init(&mut self, value: $zenoh_type) -> &mut Self { self.transmute_mut().inplace_init(value); + self } - fn inplace_default(&mut self) { + fn inplace_default(&mut self) -> &mut Self { self.transmute_mut().inplace_default(); + self } } } @@ -109,10 +110,10 @@ macro_rules! decl_transmute_ref { macro_rules! decl_transmute_copy { ($zenoh_type:ty, $c_type:ty) => { validate_equivalence!($zenoh_type, $c_type); - impl_guarded_transmute_ref!($zenoh_type, $c_type); - impl_guarded_transmute_ref!($c_type, $zenoh_type); - impl_guarded_transmute_copy!($zenoh_type, $c_type); - impl_guarded_transmute_copy!($c_type, $zenoh_type); + impl_transmute_ref!($zenoh_type, $c_type); + impl_transmute_ref!($c_type, $zenoh_type); + impl_transmute_copy!($zenoh_type, $c_type); + impl_transmute_copy!($c_type, $zenoh_type); }; } @@ -126,7 +127,7 @@ macro_rules! impl_transmute_ref { unsafe { std::mem::transmute::<&mut $src_type, &mut $dst_type>(self) } } } - } + }; } macro_rules! impl_transmute_copy { @@ -136,5 +137,5 @@ macro_rules! impl_transmute_copy { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } } - } + }; } From 4bc4f203b2c737f23575ac6b913d5120ad45730d Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 00:13:04 +0200 Subject: [PATCH 035/377] *mut MaybeUinit --- src/commons.rs | 22 ++++++++------- src/transmute.rs | 69 +++++++++++++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/commons.rs b/src/commons.rs index 345050822..90b3480df 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -13,6 +13,7 @@ // use std::ffi::CStr; +use std::mem::MaybeUninit; use std::ops::Deref; use std::ops::DerefMut; use std::str::FromStr; @@ -20,8 +21,10 @@ use std::str::FromStr; use crate::collections::*; use crate::decl_transmute_copy; use crate::keyexpr::*; -use crate::transmute::InplaceInit; -use crate::transmute::InplaceInitDefault; +use crate::transmute::Inplace; +use crate::transmute::InplaceDefault; +use crate::transmute::StaticRef; +use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteRef; use crate::z_congestion_control_t; use crate::z_id_t; @@ -35,6 +38,7 @@ use libc::{c_char, c_ulong}; use std::convert::Infallible; use unwrap_infallible::UnwrapInfallible; use zenoh::buffers::ZBuf; +use zenoh::encoding::Encoding; use zenoh::payload::Deserialize; use zenoh::payload::ZSerde; use zenoh::prelude::SampleKind; @@ -231,7 +235,7 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// pub use crate::z_encoding_t; -decl_transmute_copy!(&'static Encoding, z_encoding_t); +decl_transmute_copy!(StaticRef, z_encoding_t); /// An owned payload encoding. /// @@ -245,24 +249,24 @@ decl_transmute_ref!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] -pub extern "C" fn z_encoding_null(encoding: &mut z_owned_encoding_t) { - encoding.transmute_mut().inplace_default(); +pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { + Inplace::empty(encoding); } /// Constructs a specific :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_from_str( - encoding: &mut z_owned_encoding_t, + encoding: *mut MaybeUninit, s: *const c_char, ) -> i8 { if s.is_null() { - z_encoding_null(encoding); + Inplace::empty(encoding); 0 } else { let s = CStr::from_ptr(s).to_string_lossy().as_ref(); let value = Encoding::from_str(s).unwrap_infallible(); - encoding.transmute_mut().inplace_init(value); + Inplace::init(encoding, value); 0 } } @@ -271,7 +275,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - let encoding = Encoding::ZENOH_BYTES; + StaticRef::new(&Encoding::ZENOH_BYTES).transmute() } /// Frees `encoding`, invalidating it for double-drop safety. diff --git a/src/transmute.rs b/src/transmute.rs index d4f7a5678..1e4a01427 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -12,6 +12,19 @@ // ZettaScale Zenoh team, // +pub(crate) struct StaticRef(&'static T); +impl StaticRef { + pub(crate) fn new<'a>(value: &'a T) -> Self { + StaticRef(unsafe { std::mem::transmute::<&'a T, &'static T>(value) }) + } +} +impl Clone for StaticRef { + fn clone(&self) -> Self { + StaticRef(self.0) + } +} +impl Copy for StaticRef {} + pub(crate) trait TransmuteRef { fn transmute_ref(&self) -> &T; fn transmute_mut(&mut self) -> &mut T; @@ -21,35 +34,37 @@ pub(crate) trait TransmuteCopy: TransmuteRef { fn transmute(self) -> T; } -pub(crate) trait InplaceInit: Sized { +pub(crate) trait Inplace: Sized { // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized - fn inplace_init(&mut self, value: T) -> &mut Self { - unsafe { std::ptr::write(self as *mut Self as *mut T, value) }; - self + fn init(this: *mut std::mem::MaybeUninit, value: T) { + let this = this as *mut T; + unsafe { std::ptr::write(this, value) }; } - // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized - fn inplace_default(&mut self) -> &mut Self - where - T: Default, - { - unsafe { std::ptr::write(self as *mut Self as *mut T, T::default()) }; - self + // Initialize the object in place with an empty value + fn empty(this: *mut std::mem::MaybeUninit); +} + +pub(crate) trait InplaceDrop: Sized + Inplace { + // Drop the object in place and replaces it with default value + fn drop(this: &mut Self) { + unsafe { std::ptr::drop_in_place(this as *mut Self) }; + Inplace::empty(this as *mut Self as *mut std::mem::MaybeUninit); } } -pub(crate) trait InplaceInitDefault: Default { +pub(crate) trait InplaceDefault: Default { // Default implementation of inplace_init for object implementing Default trait. May be less efficient than a custom implementation - // because it involves a copy of the default value. - fn inplace_default_impl(&mut self) { - unsafe { std::ptr::write(self as *mut Self, Self::default()) }; + // because for `empty` operation it performs a copy of the default value from stack to provided memory + fn default(this: *mut std::mem::MaybeUninit) { + let this = this as *mut Self; + unsafe { std::ptr::write(this, ::default()) }; } } // For types implementing Default, we can use provide default implementation of InplaceInit through InplaceInitDefault -impl InplaceInit for T { - fn inplace_default(&mut self) -> &mut Self { - self.inplace_default_impl(); - self +impl Inplace for T { + fn empty(this: *mut std::mem::MaybeUninit) { + InplaceDefault::default(this); } } @@ -85,7 +100,7 @@ macro_rules! validate_equivalence { #[macro_export] macro_rules! decl_transmute_ref { (default_inplace_init $zenoh_type:ty, $c_type:ty) => { - impl InplaceInitDefault for $zenoh_type {} + impl InplaceDefault for $zenoh_type {} decl_transmute_ref!(custom_inplace_init $zenoh_type, $c_type); }; @@ -93,14 +108,14 @@ macro_rules! decl_transmute_ref { validate_equivalence!($zenoh_type, $c_type); impl_transmute_ref!($zenoh_type, $c_type); impl_transmute_ref!($c_type, $zenoh_type); - impl InplaceInit<$zenoh_type> for $c_type { - fn inplace_init(&mut self, value: $zenoh_type) -> &mut Self { - self.transmute_mut().inplace_init(value); - self + impl Inplace<$zenoh_type> for $c_type { + fn init(this: *mut std::mem::MaybeUninit, value: $zenoh_type) { + let this = this as *mut std::mem::MaybeUninit<$zenoh_type>; + Inplace::init(this, value); } - fn inplace_default(&mut self) -> &mut Self { - self.transmute_mut().inplace_default(); - self + fn empty(this: *mut std::mem::MaybeUninit) { + let this = this as *mut std::mem::MaybeUninit<$zenoh_type>; + Inplace::empty(this); } } } From 1ab939b87bdd11453b5e33715ec5ce614c1b23db Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 00:34:32 +0200 Subject: [PATCH 036/377] transmute encoding --- src/commons.rs | 14 +++++++------- src/transmute.rs | 9 +++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/commons.rs b/src/commons.rs index 90b3480df..ef1f8aa60 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -24,8 +24,8 @@ use crate::keyexpr::*; use crate::transmute::Inplace; use crate::transmute::InplaceDefault; use crate::transmute::StaticRef; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteValue; use crate::z_congestion_control_t; use crate::z_id_t; use crate::z_owned_buffer_t; @@ -140,8 +140,8 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - // let encoding = sample.encoding(); - // sample.encoding().transmute() + let encoding = sample.encoding(); + StaticRef::new(encoding).transmute_value() } /// The sample's data, the return value aliases the sample. /// @@ -275,7 +275,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - StaticRef::new(&Encoding::ZENOH_BYTES).transmute() + StaticRef::new(&Encoding::ZENOH_BYTES).transmute_value() } /// Frees `encoding`, invalidating it for double-drop safety. @@ -287,7 +287,7 @@ pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) {} #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { - let encoding = encoding.deref(); + let encoding = encoding.transmute_ref(); *encoding != Encoding::default() } @@ -295,8 +295,8 @@ pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { - let encoding = encoding.deref(); - encoding.into() + let encoding = encoding.transmute_ref(); + StaticRef::new(encoding).transmute_value() } /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` diff --git a/src/transmute.rs b/src/transmute.rs index 1e4a01427..e8dffc21e 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -30,8 +30,8 @@ pub(crate) trait TransmuteRef { fn transmute_mut(&mut self) -> &mut T; } -pub(crate) trait TransmuteCopy: TransmuteRef { - fn transmute(self) -> T; +pub(crate) trait TransmuteValue: TransmuteRef { + fn transmute_value(self) -> T; } pub(crate) trait Inplace: Sized { @@ -42,6 +42,7 @@ pub(crate) trait Inplace: Sized { } // Initialize the object in place with an empty value fn empty(this: *mut std::mem::MaybeUninit); + // TODO: for effective inplace_init, we can provide a method that takes a closure that initializes the object in place } pub(crate) trait InplaceDrop: Sized + Inplace { @@ -147,8 +148,8 @@ macro_rules! impl_transmute_ref { macro_rules! impl_transmute_copy { ($src_type:ty, $dst_type:ty) => { - impl $crate::transmute::TransmuteCopy<$dst_type> for $src_type { - fn transmute(self) -> $dst_type { + impl $crate::transmute::TransmuteValue<$dst_type> for $src_type { + fn transmute_value(self) -> $dst_type { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } } From 015eed1d53f0d5b84f43aa3e081d56e0f5f1b8a3 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 10:49:16 +0200 Subject: [PATCH 037/377] transmute simplified --- build-resources/opaque-types/src/lib.rs | 2 + include/zenoh_commons.h | 15 ++--- src/commons.rs | 75 +++++++++++-------------- src/transmute.rs | 63 +++++++++------------ 4 files changed, 67 insertions(+), 88 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 4a9ebd013..ca29316ad 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -42,6 +42,8 @@ get_opaque_type_data!(Option, "z_owned_buffer_t"); /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. get_opaque_type_data!(Option, "zc_owned_sample_t"); +get_opaque_type_data!(&'static Sample, "z_sample_t"); + /// A reader for payload data. get_opaque_type_data!(ZBufReader, "zc_payload_reader"); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 689944ae2..b5f38695a 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -312,13 +312,8 @@ typedef struct z_owned_closure_reply_t { void (*call)(struct z_owned_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; -/** - * A data sample. - * - * A sample is the value associated to a given resource at a given point in time. - */ -typedef struct z_sample_t { - const void *_inner; +typedef struct ALIGN(8) z_sample_t { + uint8_t _0[8]; } z_sample_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. @@ -2362,11 +2357,11 @@ struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); * unless the value has been dropped already. */ ZENOHC_API -bool zc_sample_check(const struct zc_owned_sample_t *sample); +bool zc_sample_check(const struct z_sample_t *sample); /** * Clone a sample in the cheapest way available. */ -ZENOHC_API struct zc_owned_sample_t zc_sample_clone(const struct z_sample_t *sample); +ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); /** * Destroy the sample. */ @@ -2377,7 +2372,7 @@ ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); * Calling this function using a dropped sample is undefined behaviour. */ ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); -ZENOHC_API struct zc_owned_sample_t zc_sample_null(void); +ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ diff --git a/src/commons.rs b/src/commons.rs index ef1f8aa60..a423bc206 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -15,27 +15,21 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use std::ops::Deref; -use std::ops::DerefMut; use std::str::FromStr; -use crate::collections::*; use crate::decl_transmute_copy; use crate::keyexpr::*; +use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::InplaceDefault; -use crate::transmute::StaticRef; +use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteRef; -use crate::transmute::TransmuteValue; -use crate::z_congestion_control_t; use crate::z_id_t; use crate::z_owned_buffer_t; -use crate::z_priority_t; use crate::zc_owned_payload_t; use crate::zc_payload_t; -use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; -use std::convert::Infallible; use unwrap_infallible::UnwrapInfallible; use zenoh::buffers::ZBuf; use zenoh::encoding::Encoding; @@ -111,37 +105,22 @@ impl From> for z_timestamp_t { /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. -#[repr(C)] -pub struct z_sample_t<'a> { - _inner: &'a (), -} -impl<'a> core::ops::Deref for z_sample_t<'a> { - type Target = Sample; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute::<&(), &Sample>(self._inner) } - } -} - -impl<'a> z_sample_t<'a> { - pub fn new(sample: &'a Sample) -> Self { - z_sample_t { - _inner: unsafe { core::mem::transmute(sample) }, - } - } -} +use crate::z_sample_t; +decl_transmute_copy!(&'static Option, z_sample_t); /// The Key Expression of the sample. /// /// `sample` is aliased by its return value. #[no_mangle] pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); sample.key_expr().into() } /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - let encoding = sample.encoding(); - StaticRef::new(encoding).transmute_value() + let sample = unwrap_ref_unchecked(sample.transmute_copy()); + sample.encoding().transmute_copy() } /// The sample's data, the return value aliases the sample. /// @@ -151,6 +130,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { // TODO: here returning reference not to sample's payload, but to temporary copy // THIS WILL CRASH FOR SURE, MADE IT ONLY TO MAKE IT COMPILE // Need a way to get reference to sample's payload + let sample = unwrap_ref_unchecked(sample.transmute_copy()); let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); let owned_buffer: z_owned_buffer_t = Some(buffer).into(); owned_buffer.as_ref().into() @@ -162,6 +142,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { /// affect the samples received by other subscribers. #[no_mangle] pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); let owned_buffer: z_owned_buffer_t = Some(buffer).into(); owned_buffer.into() @@ -169,11 +150,13 @@ pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payloa /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); sample.kind().into() } /// The samples timestamp #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); sample.timestamp().into() } /// The qos with which the sample was received. @@ -184,6 +167,7 @@ pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { /// `sample` is aliased by the return value. #[no_mangle] pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); match sample.attachment() { Some(attachment) => z_attachment_t { data: attachment as *const _ as *mut c_void, @@ -194,12 +178,15 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } pub use crate::zc_owned_sample_t; -impl_guarded_transmute!(Option, zc_owned_sample_t); +decl_transmute_ref!(default_inplace_init Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] -pub extern "C" fn zc_sample_clone(sample: &z_sample_t) -> zc_owned_sample_t { - Some(sample.deref().clone()).into() +pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { + let src = unwrap_ref_unchecked(src.transmute_copy()); + let src = src.deref().clone(); + let dst = zc_owned_sample_t::transmute_uninit_ptr(dst); + Inplace::init(dst, Some(src)); } /// Returns `true` if `sample` is valid. @@ -207,7 +194,8 @@ pub extern "C" fn zc_sample_clone(sample: &z_sample_t) -> zc_owned_sample_t { /// Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed /// unless the value has been dropped already. #[no_mangle] -pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { +pub extern "C" fn zc_sample_check(sample: &z_sample_t) -> bool { + let sample = sample.transmute_copy(); sample.is_some() } @@ -216,18 +204,20 @@ pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> z_sample_t { - z_sample_t::new(unsafe { sample.as_ref().unwrap_unchecked() }) + sample.transmute_ref().transmute_copy() } /// Destroy the sample. #[no_mangle] pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { - core::mem::drop(sample.take()); + let sample = sample.transmute_mut(); + Inplace::drop(sample); } #[no_mangle] -pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { - None.into() +pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { + let sample = zc_owned_sample_t::transmute_uninit_ptr(sample); + Inplace::empty(sample); } /// The encoding of a payload, in a MIME-like format. @@ -235,7 +225,7 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// pub use crate::z_encoding_t; -decl_transmute_copy!(StaticRef, z_encoding_t); +decl_transmute_copy!(&'static Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -250,6 +240,7 @@ decl_transmute_ref!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { + let encoding = z_owned_encoding_t::transmute_uninit_ptr(encoding); Inplace::empty(encoding); } @@ -260,6 +251,7 @@ pub unsafe extern "C" fn z_encoding_from_str( encoding: *mut MaybeUninit, s: *const c_char, ) -> i8 { + let encoding = z_owned_encoding_t::transmute_uninit_ptr(encoding); if s.is_null() { Inplace::empty(encoding); 0 @@ -275,7 +267,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - StaticRef::new(&Encoding::ZENOH_BYTES).transmute_value() + (&Encoding::ZENOH_BYTES).transmute_copy() } /// Frees `encoding`, invalidating it for double-drop safety. @@ -286,7 +278,7 @@ pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) {} /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { +pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> bool { let encoding = encoding.transmute_ref(); *encoding != Encoding::default() } @@ -294,9 +286,8 @@ pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { - let encoding = encoding.transmute_ref(); - StaticRef::new(encoding).transmute_value() +pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_encoding_t { + encoding.transmute_ref().transmute_copy() } /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` diff --git a/src/transmute.rs b/src/transmute.rs index e8dffc21e..76b9ac9b1 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -12,45 +12,46 @@ // ZettaScale Zenoh team, // -pub(crate) struct StaticRef(&'static T); -impl StaticRef { - pub(crate) fn new<'a>(value: &'a T) -> Self { - StaticRef(unsafe { std::mem::transmute::<&'a T, &'static T>(value) }) - } -} -impl Clone for StaticRef { - fn clone(&self) -> Self { - StaticRef(self.0) - } +// pub fn as_static_ref<'a, T: 'a>(value: &'a T) -> &'static T { +// unsafe { std::mem::transmute::<&'a T, &'static T>(value) } +// } + +pub fn unwrap_ref_unchecked(value: &Option) -> &T { + debug_assert!(value.is_some()); + unsafe { value.as_ref().unwrap_unchecked() } } -impl Copy for StaticRef {} -pub(crate) trait TransmuteRef { +pub(crate) trait TransmuteRef: Sized { fn transmute_ref(&self) -> &T; fn transmute_mut(&mut self) -> &mut T; + fn transmute_uninit_ptr( + this: *mut std::mem::MaybeUninit, + ) -> *mut std::mem::MaybeUninit { + this as *mut std::mem::MaybeUninit + } } -pub(crate) trait TransmuteValue: TransmuteRef { - fn transmute_value(self) -> T; +pub(crate) trait TransmuteCopy: TransmuteRef { + fn transmute_copy(self) -> T; } -pub(crate) trait Inplace: Sized { +pub(crate) trait Inplace: Sized { // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized - fn init(this: *mut std::mem::MaybeUninit, value: T) { - let this = this as *mut T; + fn init(this: *mut std::mem::MaybeUninit, value: Self) { + let this = this as *mut Self; unsafe { std::ptr::write(this, value) }; } + // Initialize the object in place with an empty value fn empty(this: *mut std::mem::MaybeUninit); - // TODO: for effective inplace_init, we can provide a method that takes a closure that initializes the object in place -} -pub(crate) trait InplaceDrop: Sized + Inplace { - // Drop the object in place and replaces it with default value + // Drop the object in place and replaces it with empty value fn drop(this: &mut Self) { - unsafe { std::ptr::drop_in_place(this as *mut Self) }; - Inplace::empty(this as *mut Self as *mut std::mem::MaybeUninit); + let this = this as *mut Self; + unsafe { std::ptr::drop_in_place(this) }; + Inplace::empty(this as *mut std::mem::MaybeUninit); } + // TODO: for effective inplace_init, we can provide a method that takes a closure that initializes the object in place } pub(crate) trait InplaceDefault: Default { @@ -63,7 +64,7 @@ pub(crate) trait InplaceDefault: Default { } // For types implementing Default, we can use provide default implementation of InplaceInit through InplaceInitDefault -impl Inplace for T { +impl Inplace for T { fn empty(this: *mut std::mem::MaybeUninit) { InplaceDefault::default(this); } @@ -109,16 +110,6 @@ macro_rules! decl_transmute_ref { validate_equivalence!($zenoh_type, $c_type); impl_transmute_ref!($zenoh_type, $c_type); impl_transmute_ref!($c_type, $zenoh_type); - impl Inplace<$zenoh_type> for $c_type { - fn init(this: *mut std::mem::MaybeUninit, value: $zenoh_type) { - let this = this as *mut std::mem::MaybeUninit<$zenoh_type>; - Inplace::init(this, value); - } - fn empty(this: *mut std::mem::MaybeUninit) { - let this = this as *mut std::mem::MaybeUninit<$zenoh_type>; - Inplace::empty(this); - } - } } } @@ -148,8 +139,8 @@ macro_rules! impl_transmute_ref { macro_rules! impl_transmute_copy { ($src_type:ty, $dst_type:ty) => { - impl $crate::transmute::TransmuteValue<$dst_type> for $src_type { - fn transmute_value(self) -> $dst_type { + impl $crate::transmute::TransmuteCopy<$dst_type> for $src_type { + fn transmute_copy(self) -> $dst_type { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } } From fd2153bd8b659a347b2d34e517632fc22495d537 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 12:39:29 +0200 Subject: [PATCH 038/377] explicit opaque types, renaming --- include/zenoh_commons.h | 2 +- src/commons.rs | 55 +++++++++++++++++++---------------------- src/lib.rs | 3 +-- src/transmute.rs | 4 +-- 4 files changed, 30 insertions(+), 34 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index b5f38695a..90d1ee819 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -2357,7 +2357,7 @@ struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); * unless the value has been dropped already. */ ZENOHC_API -bool zc_sample_check(const struct z_sample_t *sample); +bool zc_sample_check(const struct zc_owned_sample_t *sample); /** * Clone a sample in the cheapest way available. */ diff --git a/src/commons.rs b/src/commons.rs index a423bc206..902a2361f 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -17,15 +17,14 @@ use std::mem::MaybeUninit; use std::ops::Deref; use std::str::FromStr; -use crate::decl_transmute_copy; use crate::keyexpr::*; +use crate::opaque_types::z_owned_buffer_t; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::InplaceDefault; use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteRef; use crate::z_id_t; -use crate::z_owned_buffer_t; use crate::zc_owned_payload_t; use crate::zc_payload_t; use libc::c_void; @@ -105,21 +104,21 @@ impl From> for z_timestamp_t { /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. -use crate::z_sample_t; -decl_transmute_copy!(&'static Option, z_sample_t); +use crate::opaque_types::z_sample_t; +decl_transmute_copy!(&'static Sample, z_sample_t); /// The Key Expression of the sample. /// /// `sample` is aliased by its return value. #[no_mangle] pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); sample.key_expr().into() } /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); sample.encoding().transmute_copy() } /// The sample's data, the return value aliases the sample. @@ -130,7 +129,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { // TODO: here returning reference not to sample's payload, but to temporary copy // THIS WILL CRASH FOR SURE, MADE IT ONLY TO MAKE IT COMPILE // Need a way to get reference to sample's payload - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); let owned_buffer: z_owned_buffer_t = Some(buffer).into(); owned_buffer.as_ref().into() @@ -142,7 +141,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { /// affect the samples received by other subscribers. #[no_mangle] pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); let owned_buffer: z_owned_buffer_t = Some(buffer).into(); owned_buffer.into() @@ -150,13 +149,13 @@ pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payloa /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); sample.kind().into() } /// The samples timestamp #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); sample.timestamp().into() } /// The qos with which the sample was received. @@ -167,7 +166,7 @@ pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { /// `sample` is aliased by the return value. #[no_mangle] pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); match sample.attachment() { Some(attachment) => z_attachment_t { data: attachment as *const _ as *mut c_void, @@ -177,13 +176,13 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } } -pub use crate::zc_owned_sample_t; -decl_transmute_ref!(default_inplace_init Option, zc_owned_sample_t); +pub use crate::opaque_types::zc_owned_sample_t; +decl_transmute_owned!(default_inplace_init Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { - let src = unwrap_ref_unchecked(src.transmute_copy()); + let src = src.transmute_copy(); let src = src.deref().clone(); let dst = zc_owned_sample_t::transmute_uninit_ptr(dst); Inplace::init(dst, Some(src)); @@ -194,8 +193,8 @@ pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit bool { - let sample = sample.transmute_copy(); +pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { + let sample = sample.transmute_ref(); sample.is_some() } @@ -204,27 +203,25 @@ pub extern "C" fn zc_sample_check(sample: &z_sample_t) -> bool { /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> z_sample_t { - sample.transmute_ref().transmute_copy() + unwrap_ref_unchecked(sample.transmute_ref()).transmute_copy() } /// Destroy the sample. #[no_mangle] pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { - let sample = sample.transmute_mut(); - Inplace::drop(sample); + Inplace::drop(sample.transmute_mut()); } #[no_mangle] pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { - let sample = zc_owned_sample_t::transmute_uninit_ptr(sample); - Inplace::empty(sample); + Inplace::empty(zc_owned_sample_t::transmute_uninit_ptr(sample)); } /// The encoding of a payload, in a MIME-like format. /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// -pub use crate::z_encoding_t; +pub use crate::opaque_types::z_encoding_t; decl_transmute_copy!(&'static Encoding, z_encoding_t); /// An owned payload encoding. @@ -234,14 +231,13 @@ decl_transmute_copy!(&'static Encoding, z_encoding_t); /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -pub use crate::z_owned_encoding_t; -decl_transmute_ref!(default_inplace_init Encoding, z_owned_encoding_t); +pub use crate::opaque_types::z_owned_encoding_t; +decl_transmute_owned!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { - let encoding = z_owned_encoding_t::transmute_uninit_ptr(encoding); - Inplace::empty(encoding); + Inplace::empty(z_owned_encoding_t::transmute_uninit_ptr(encoding)); } /// Constructs a specific :c:type:`z_encoding_t`. @@ -273,14 +269,15 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { /// Frees `encoding`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) {} +pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { + Inplace::drop(encoding); +} /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> bool { - let encoding = encoding.transmute_ref(); - *encoding != Encoding::default() + *encoding.transmute_ref() != Encoding::default() } /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. diff --git a/src/lib.rs b/src/lib.rs index 90a7f27c5..90b185add 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,9 +59,8 @@ mod querying_subscriber; pub use querying_subscriber::*; pub mod attachment; pub use platform::*; -pub mod platform; -pub use opaque_types::*; pub mod opaque_types; +pub mod platform; #[cfg(feature = "shared-memory")] mod shm; diff --git a/src/transmute.rs b/src/transmute.rs index 76b9ac9b1..2eccd4117 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -100,10 +100,10 @@ macro_rules! validate_equivalence { } #[macro_export] -macro_rules! decl_transmute_ref { +macro_rules! decl_transmute_owned { (default_inplace_init $zenoh_type:ty, $c_type:ty) => { impl InplaceDefault for $zenoh_type {} - decl_transmute_ref!(custom_inplace_init $zenoh_type, $c_type); + decl_transmute_owned!(custom_inplace_init $zenoh_type, $c_type); }; (custom_inplace_init $zenoh_type:ty, $c_type:ty) => { From 758eb2f03a0f4a1b0f336f735fce639f0a7b4595 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 19:45:06 +0200 Subject: [PATCH 039/377] more structs converted --- build-resources/opaque-types/Cargo.lock | 27 ++++++ build-resources/opaque-types/Cargo.toml | 6 +- build-resources/opaque-types/src/lib.rs | 18 ++++ include/zenoh_commons.h | 118 +----------------------- include/zenoh_concrete.h | 31 +------ src/get.rs | 68 ++++---------- src/info.rs | 2 +- src/keyexpr.rs | 7 +- src/lib.rs | 5 +- src/liveliness.rs | 5 +- src/payload.rs | 10 +- src/publication_cache.rs | 2 - src/publisher.rs | 3 +- src/put.rs | 1 - src/queryable.rs | 81 +++++----------- src/querying_subscriber.rs | 63 +++++-------- src/transmute.rs | 2 +- 17 files changed, 143 insertions(+), 306 deletions(-) diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index d7276add6..5ed408409 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -340,6 +340,15 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -1196,6 +1205,7 @@ name = "opaque-types" version = "0.1.0" dependencies = [ "zenoh", + "zenoh-ext", ] [[package]] @@ -2523,6 +2533,23 @@ dependencies = [ "zenoh-result", ] +[[package]] +name = "zenoh-ext" +version = "0.11.0-dev" +dependencies = [ + "bincode", + "env_logger", + "flume", + "futures", + "log", + "phf", + "serde", + "serde_cbor", + "serde_json", + "tokio", + "zenoh", +] + [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml index 51bf417a7..93f88d05d 100644 --- a/build-resources/opaque-types/Cargo.toml +++ b/build-resources/opaque-types/Cargo.toml @@ -8,4 +8,8 @@ edition = "2021" [dependencies] # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` # zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } -zenoh = { path="../../../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } \ No newline at end of file +zenoh = { path = "../../../zenoh/zenoh", features = [ + "shared-memory", + "unstable", +], default-features = false } +zenoh-ext = { path = "../../../zenoh/zenoh-ext", features = ["unstable"] } diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index ca29316ad..698646271 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -2,9 +2,16 @@ use zenoh::buffers::{ZBuf, ZBufReader}; use zenoh::encoding::Encoding; use zenoh::query::Reply; use zenoh::queryable::Query; +use zenoh::queryable::Queryable; use zenoh::sample::Sample; use zenoh::value::Value; +// Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. +// pub struct FetchingSubscriberWrapper { +// fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, +// session: z_session_t, +// } + #[macro_export] macro_rules! get_opaque_type_data { ($src_type:ty, $expr:expr) => { @@ -53,3 +60,14 @@ get_opaque_type_data!(Option, "z_owned_reply_t"); get_opaque_type_data!(Value, "z_owned_value_t"); get_opaque_type_data!(&'static Value, "z_value_t"); get_opaque_type_data!(Option, "z_owned_query_t"); +get_opaque_type_data!(&'static Query, "z_query_t"); +get_opaque_type_data!(Option>, "z_owned_queryable_t"); +get_opaque_type_data!(&'static Queryable<'static, ()>, "z_queryable_t"); +// get_opaque_type_data!( +// Option>, +// "ze_owned_querying_subscriber_t" +// ); +// get_opaque_type_data!( +// &'static FetchingSubscriberWrapper, +// "ze_querying_subscriber_t" +// ); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 90d1ee819..0d5331ab6 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -842,46 +842,6 @@ typedef struct ze_publication_cache_options_t { size_t history; size_t resources_limit; } ze_publication_cache_options_t; -/** - * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ze_owned_querying_subscriber_t { - size_t _0[1]; -} ze_owned_querying_subscriber_t; -/** - * Represents the set of options that can be applied to a querying subscriber, - * upon its declaration via :c:func:`ze_declare_querying_subscriber`. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - * zcu_locality_t allowed_origin: The restriction for the matching publications that will be - * receive by this subscriber. - * z_keyexpr_t query_selector: The selector to be used for queries. - * z_query_target_t query_target: The target to be used for queries. - * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. - * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. - * uint64_t query_timeout_ms: The timeout to be used for queries. - */ -typedef struct ze_querying_subscriber_options_t { - enum zcu_locality_t allowed_origin; - struct z_keyexpr_t query_selector; - enum z_query_target_t query_target; - struct z_query_consolidation_t query_consolidation; - enum zcu_reply_keyexpr_t query_accept_replies; - uint64_t query_timeout_ms; -} ze_querying_subscriber_options_t; -typedef struct ze_querying_subscriber_t { - const struct ze_owned_querying_subscriber_t *_0; -} ze_querying_subscriber_t; ZENOHC_API extern const unsigned int Z_ROUTER; ZENOHC_API extern const unsigned int Z_PEER; ZENOHC_API extern const unsigned int Z_CLIENT; @@ -1716,14 +1676,14 @@ ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); * This function may not be called with the null pointer, but can be called with the gravestone value. */ ZENOHC_API -bool z_query_check(const struct z_owned_query_t *this_); +bool z_query_check(const struct z_owned_query_t *query); /** * Clones the query, allowing to keep it in an "open" state past the callback's return. * * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). */ ZENOHC_API -struct z_owned_query_t z_query_clone(const struct z_query_t *query); +struct z_owned_query_t z_query_clone(struct z_query_t query); /** * Automatic query consolidation strategy selection. * @@ -1772,7 +1732,7 @@ struct z_query_t z_query_loan(const struct z_owned_query_t *this_); /** * The gravestone value of `z_owned_query_t`. */ -ZENOHC_API struct z_owned_query_t z_query_null(void); +ZENOHC_API void z_query_null(struct z_owned_query_t *query); /** * Get a query's `value selector `_ by aliasing it. */ @@ -1819,7 +1779,7 @@ ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); /** * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type */ -ZENOHC_API struct z_owned_queryable_t z_queryable_null(void); +ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ @@ -1879,7 +1839,7 @@ bool z_reply_is_ok(const struct z_owned_reply_t *reply); * - overwrite the pointee with this function's return value, * - you are now responsible for dropping your copy of the reply. */ -ZENOHC_API struct z_owned_reply_t z_reply_null(void); +ZENOHC_API void z_reply_null(struct z_owned_reply_t *reply); /** * Yields the contents of the reply by asserting it indicates a success. * @@ -2503,44 +2463,6 @@ ZENOHC_API struct ze_owned_publication_cache_t ze_declare_publication_cache(struct z_session_t session, struct z_keyexpr_t keyexpr, const struct ze_publication_cache_options_t *options); -/** - * Declares a Querying Subscriber for a given key expression. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to subscribe. - * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. - * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. - * - * Returns: - * :c:type:`ze_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the querying subscriber is still valid, - * you may use `ze_querying_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing ``NULL`` for the options: - * - * .. code-block:: C - * - * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -struct ze_owned_querying_subscriber_t ze_declare_querying_subscriber(struct z_session_t session, - struct z_keyexpr_t keyexpr, - struct z_owned_closure_sample_t *callback, - const struct ze_querying_subscriber_options_t *options); /** * Returns ``true`` if `pub_cache` is valid. */ @@ -2553,38 +2475,8 @@ ZENOHC_API struct ze_owned_publication_cache_t ze_publication_cache_null(void); * Constructs the default value for :c:type:`ze_publication_cache_options_t`. */ ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subscriber_t *sub); -/** - * Make a :c:type:`ze_owned_querying_subscriber_t` to perform an additional query on a specified selector. - * The queried samples will be merged with the received publications and made available in the subscriber callback. - */ -ZENOHC_API -int8_t ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, - struct z_keyexpr_t selector, - const struct z_get_options_t *options); -/** - * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `p`. - */ -ZENOHC_API -struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *p); -/** - * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type - */ -ZENOHC_API struct ze_owned_querying_subscriber_t ze_querying_subscriber_null(void); -/** - * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. - */ -ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); /** * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API int8_t ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *pub_cache); -/** - * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -int8_t ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *sub); diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 8572e956b..491551ee1 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -36,14 +36,8 @@ typedef struct z_owned_session_t { size_t _0; } z_owned_session_t; -/** - * Loaned variant of a Query received by a Queryable. - * - * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. - * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. - */ -typedef struct z_query_t { - void *_0; +typedef struct ALIGN(8) z_query_t { + uint8_t _0[8]; } z_query_t; /** * A loaned zenoh session. @@ -51,28 +45,9 @@ typedef struct z_query_t { typedef struct z_session_t { size_t _0; } z_session_t; -/** - * An owned zenoh queryable. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_queryable_t { - uint64_t _0[4]; + uint8_t _0[32]; } z_owned_queryable_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_queryable_t { - uint32_t _0[4]; -} z_owned_queryable_t; -#endif /** * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. * diff --git a/src/get.rs b/src/get.rs index 37ed192e0..5274a86b5 100644 --- a/src/get.rs +++ b/src/get.rs @@ -14,6 +14,7 @@ use libc::c_char; use libc::c_void; +use std::mem::MaybeUninit; use std::{ convert::TryFrom, ffi::CStr, @@ -31,23 +32,23 @@ use zenoh::{ sample::AttachmentBuilder, value::Value, }; -use zenoh_util::core::{zresult::ErrNo, SyncResolve}; use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, z_attachment_t, }; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteRef; use crate::z_encoding_default; use crate::zc_owned_payload_t; use crate::zc_payload_null; use crate::zc_payload_t; use crate::{ - impl_guarded_transmute, z_closure_reply_call, z_encoding_t, z_keyexpr_t, - z_owned_closure_reply_t, z_sample_t, z_session_t, GuardedTransmute, LOG_INVALID_SESSION, + opaque_types::z_sample_t, z_closure_reply_call, z_encoding_t, z_keyexpr_t, + z_owned_closure_reply_t, z_session_t, LOG_INVALID_SESSION, }; -type ReplyInner = Option; - /// An owned reply to a :c:func:`z_get`. /// /// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. @@ -55,36 +56,16 @@ type ReplyInner = Option; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -pub use crate::z_owned_reply_t; -impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); +pub use crate::opaque_types::z_owned_reply_t; +decl_transmute_owned!(default_inplace_init Option, z_owned_reply_t); -impl From for z_owned_reply_t { - fn from(val: ReplyInner) -> Self { - val.transmute() - } -} -impl From for z_owned_reply_t { - fn from(val: Reply) -> z_owned_reply_t { - Some(val).into() - } -} -impl Deref for z_owned_reply_t { - type Target = ReplyInner; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute::<&Self, &Self::Target>(self) } - } -} -impl DerefMut for z_owned_reply_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute::<&mut Self, &mut Self::Target>(self) } - } -} /// Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. /// /// If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { + let reply = reply.transmute_ref(); reply.as_ref().map(|r| r.sample.is_ok()).unwrap_or(false) } @@ -94,8 +75,9 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { + let reply = reply.transmute_ref(); if let Some(sample) = reply.as_ref().and_then(|s| s.sample.as_ref().ok()) { - z_sample_t::new(sample) + sample.transmute_copy() } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Ok despite that not being the case") } @@ -104,21 +86,10 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { /// A zenoh value. /// /// -pub use crate::z_owned_value_t; -impl_guarded_transmute!(Value, z_owned_value_t); -pub use crate::z_value_t; -impl_guarded_transmute!(&'static Value, z_value_t); - -const Z_VALUE_NULL: Value = Value::empty(); - -impl From> for z_value_t { - fn from(val: Option<&Value>) -> Self { - match val { - Some(val) => val.transmute(), - None => (&Z_VALUE_NULL).transmute(), - } - } -} +pub use crate::opaque_types::z_owned_value_t; +decl_transmute_owned!(default_inplace_init Value, z_owned_value_t); +pub use crate::opaque_types::z_value_t; +decl_transmute_copy!(&'static Value, z_value_t); /// Yields the contents of the reply by asserting it indicates a failure. /// @@ -126,8 +97,9 @@ impl From> for z_value_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { - if let Some(inner) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { - inner.into() + let reply = reply.transmute_ref(); + if let Some(value) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { + value.into() } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Err despite that not being the case") } @@ -142,8 +114,8 @@ pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { /// - you are now responsible for dropping your copy of the reply. #[no_mangle] #[allow(improper_ctypes_definitions)] -pub extern "C" fn z_reply_null() -> z_owned_reply_t { - None.into() +pub extern "C" fn z_reply_null(reply: *mut MaybeUninit) { + Inplace::empty(z_owned_reply_t::transmute_uninit_ptr(reply)); } /// Options passed to the :c:func:`z_get` function. diff --git a/src/info.rs b/src/info.rs index 11ef031b3..2ee4d9384 100644 --- a/src/info.rs +++ b/src/info.rs @@ -12,9 +12,9 @@ // ZettaScale Zenoh team, // use crate::{session::*, z_closure_zid_call, z_owned_closure_zid_t}; +use zenoh::config::ZenohId; use zenoh::prelude::sync::SyncResolve; use zenoh::session::SessionDeclarations; -use zenoh_protocol::core::ZenohId; /// Represents a Zenoh ID. /// diff --git a/src/keyexpr.rs b/src/keyexpr.rs index c88b01199..6b7adeacf 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -28,7 +28,6 @@ use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; -use zenoh_util::core::zresult::ErrNo; /// A zenoh-allocated key expression. /// @@ -46,11 +45,11 @@ use zenoh_util::core::zresult::ErrNo; /// - A pure numerical id. /// - The combination of a numerical prefix and a string suffix. /// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. /// /// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. diff --git a/src/lib.rs b/src/lib.rs index 90b185add..547d9178d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,8 +55,9 @@ use libc::c_void; pub use liveliness::*; mod publication_cache; pub use publication_cache::*; -mod querying_subscriber; -pub use querying_subscriber::*; +// Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. +// mod querying_subscriber; +// pub use querying_subscriber::*; pub mod attachment; pub use platform::*; pub mod opaque_types; diff --git a/src/liveliness.rs b/src/liveliness.rs index b3c61a7de..46ec7c8a5 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -16,11 +16,10 @@ use zenoh::{ liveliness::{Liveliness, LivelinessToken}, prelude::SessionDeclarations, }; -use zenoh_util::core::{zresult::ErrNo, SyncResolve}; use crate::{ - z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, - z_owned_closure_sample_t, z_owned_subscriber_t, z_sample_t, z_session_t, + opaque_types::z_sample_t, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, + z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, }; /// A liveliness token that can be used to provide the network with information about connectivity to its diff --git a/src/payload.rs b/src/payload.rs index fa6603de6..b77b46dd7 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,4 +1,5 @@ use core::slice; +use std::mem::MaybeUninit; use std::slice::from_raw_parts_mut; use std::{any::Any, ops::Deref, ptr::NonNull}; @@ -12,7 +13,7 @@ use crate::{ z_str_null, GuardedTransmute, }; -pub use crate::z_owned_buffer_t; +pub use crate::opaque_types::z_owned_buffer_t; impl_guarded_transmute!(Option, z_owned_buffer_t); impl Default for z_owned_buffer_t { @@ -247,9 +248,8 @@ pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { z_buffer_len(payload) } -pub use crate::zc_payload_reader; -impl_guarded_transmute!(ZBufReader<'static>, zc_payload_reader); -impl_guarded_transmute!(noderefs zc_payload_reader, ZBufReader<'static>); +pub use crate::opaque_types::zc_payload_reader; +decl_transmute_copy!(ZBufReader<'static>, zc_payload_reader); /// Creates a reader for the specified `payload`. /// @@ -258,7 +258,7 @@ impl_guarded_transmute!(noderefs zc_payload_reader, ZBufReader<'static>); #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_reader_init( payload: zc_payload_t, - reader: *mut zc_payload_reader, + reader: *mut MaybeUninit, ) -> i8 { if payload._inner.is_none() { return -1; diff --git a/src/publication_cache.rs b/src/publication_cache.rs index ee4c85959..50e1dad47 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -15,8 +15,6 @@ use std::ops::Deref; use zenoh_ext::SessionExt; -use zenoh_util::core::zresult::ErrNo; -use zenoh_util::core::SyncResolve; use crate::{ impl_guarded_transmute, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t, diff --git a/src/publisher.rs b/src/publisher.rs index 47f2bb71f..c829a8533 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -17,6 +17,7 @@ use crate::zcu_owned_closure_matching_status_t; use std::ops::{Deref, DerefMut}; use zenoh::encoding::Encoding; use zenoh::prelude::SessionDeclarations; +use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; @@ -26,8 +27,6 @@ use zenoh::{ publication::Publisher, sample::AttachmentBuilder, }; -use zenoh_protocol::core::CongestionControl; -use zenoh_util::core::{zresult::ErrNo, SyncResolve}; use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, diff --git a/src/put.rs b/src/put.rs index a0c2e88d0..59e9e5e3c 100644 --- a/src/put.rs +++ b/src/put.rs @@ -24,7 +24,6 @@ use zenoh::sample::AttachmentBuilder; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; -use zenoh_util::core::zresult::ErrNo; use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, diff --git a/src/queryable.rs b/src/queryable.rs index 2fd38d296..30baf5af2 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -15,22 +15,22 @@ use crate::attachment::{ attachment_iteration_driver, insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, z_attachment_t, }; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteRef}; use crate::{ - impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, zc_payload_t, + z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, z_keyexpr_t, + z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, zc_payload_t, LOG_INVALID_SESSION, }; use libc::c_void; +use std::mem::MaybeUninit; use std::ops::{Deref, DerefMut}; use zenoh::prelude::SessionDeclarations; use zenoh::{ prelude::Sample, - queryable::{Query, Queryable as CallbackQueryable}, + queryable::{Query, Queryable}, sample::AttachmentBuilder, }; -use zenoh_util::core::{zresult::ErrNo, SyncResolve}; -type Queryable = Option>; /// An owned zenoh queryable. /// /// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. @@ -41,52 +41,22 @@ type Queryable = Option>; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_queryable_t([u64; 4]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_queryable_t([u32; 4]); - -impl_guarded_transmute!(Queryable, z_owned_queryable_t); - -impl z_owned_queryable_t { - pub fn null() -> Self { - None.into() - } -} +pub use crate::opaque_types::z_owned_queryable_t; +decl_transmute_owned!(default_inplace_init Option>, z_owned_queryable_t); /// Constructs a null safe-to-drop value of 'z_owned_queryable_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_queryable_null() -> z_owned_queryable_t { - z_owned_queryable_t::null() +pub extern "C" fn z_queryable_null(this: *mut MaybeUninit) { + Inplace::empty(z_owned_queryable_t::transmute_uninit_ptr(this)); } -/// Loaned variant of a Query received by a Queryable. +// Loaned variant of a Query received by a Queryable. /// /// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. /// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct z_query_t(*mut c_void); -impl From<&Query> for z_query_t { - fn from(value: &Query) -> Self { - z_query_t(value as *const _ as *mut _) - } -} -impl From> for z_query_t { - fn from(value: Option<&Query>) -> Self { - value.map_or(Self(core::ptr::null_mut()), Into::into) - } -} -impl Deref for z_query_t { - type Target = Option<&'static Query>; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} +pub use crate::opaque_types::z_query_t; +decl_transmute_copy!(&'static Query, z_query_t); /// Owned variant of a Query received by a Queryable. /// @@ -96,46 +66,43 @@ impl Deref for z_query_t { /// /// Holding onto an `z_owned_query_t` for too long (10s by default, can be set in `z_get`'s options) will trigger a timeout error /// to be sent to the querier by the infrastructure, and new responses to the outdated query will be silently dropped. -pub use crate::z_owned_query_t; -impl_guarded_transmute!(Option, z_owned_query_t); - -// impl Drop for z_owned_query_t { -// fn drop(&mut self) { -// let _: Option = self.take(); -// } -// } +pub use crate::opaque_types::z_owned_query_t; +decl_transmute_owned!(default_inplace_init Option, z_owned_query_t); /// The gravestone value of `z_owned_query_t`. #[no_mangle] -pub extern "C" fn z_query_null() -> z_owned_query_t { - None.into() +pub extern "C" fn z_query_null(query: *mut MaybeUninit) { + Inplace::empty(z_owned_query_t::transmute_uninit_ptr(query)); } /// Returns `false` if `this` is in a gravestone state, `true` otherwise. /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] -pub extern "C" fn z_query_check(this: &z_owned_query_t) -> bool { - this.is_some() +pub extern "C" fn z_query_check(query: &z_owned_query_t) -> bool { + query.transmute_ref().is_some() } /// Aliases the query. /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] pub extern "C" fn z_query_loan(this: &z_owned_query_t) -> z_query_t { - this.as_ref().into() + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_copy() } /// Destroys the query, setting `this` to its gravestone value to prevent double-frees. /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] pub extern "C" fn z_query_drop(this: &mut z_owned_query_t) { - let _: Option = this.take(); + Inplace::drop(this.transmute_mut()) } /// Clones the query, allowing to keep it in an "open" state past the callback's return. /// /// This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). #[no_mangle] -pub extern "C" fn z_query_clone(query: Option<&z_query_t>) -> z_owned_query_t { +pub extern "C" fn z_query_clone(query: z_query_t) -> z_owned_query_t { + let query = query.transmute_copy(); query.and_then(|q| q.cloned()).into() } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 6f78d6bb9..92e797e2e 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -12,70 +12,55 @@ // ZettaScale Zenoh team, // +use std::mem::MaybeUninit; + use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh::prelude::SessionDeclarations; use zenoh_ext::*; -use zenoh_util::core::zresult::ErrNo; +use crate::z_closure_owned_query_call; +use crate::ze_owned_publication_cache_t; use crate::{ - impl_guarded_transmute, z_closure_sample_call, z_get_options_t, z_keyexpr_t, - z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, - z_query_target_default, z_query_target_t, z_sample_t, z_session_t, - zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, - LOG_INVALID_SESSION, + impl_guarded_transmute, opaque_types::z_sample_t, z_closure_sample_call, z_get_options_t, + z_keyexpr_t, z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, + z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, + zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, LOG_INVALID_SESSION, }; pub struct FetchingSubscriberWrapper { fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, session: z_session_t, } -type FetchingSubscriber = Option>; //type FetchingSubscriber = Option>>; /// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. /// -/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. /// /// Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C)] -pub struct ze_owned_querying_subscriber_t([usize; 1]); +use crate::opaque_types::ze_owned_querying_subscriber_t; +decl_transmute_owned!(default_inplace_init Option>, z_owned_querying_subscriber_t); -impl_guarded_transmute!(FetchingSubscriber, ze_owned_querying_subscriber_t); - -#[repr(C)] -#[allow(non_camel_case_types)] -pub struct ze_querying_subscriber_t<'a>(&'a ze_owned_querying_subscriber_t); - -impl<'a> AsRef for ze_querying_subscriber_t<'a> { - fn as_ref(&self) -> &FetchingSubscriber { - self.0 - } -} - -impl ze_owned_querying_subscriber_t { - pub fn new(sub: zenoh_ext::FetchingSubscriber<'static, ()>, session: z_session_t) -> Self { - Some(Box::new(FetchingSubscriberWrapper { - fetching_subscriber: sub, - session, - })) - .into() - } - pub fn null() -> Self { - None.into() - } -} +use crate::opaque_types::ze_querying_subscriber_t; +decl_transmute_copy!( + &'static Option>, + z_querying_subscriber_t +); /// Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn ze_querying_subscriber_null() -> ze_owned_querying_subscriber_t { - ze_owned_querying_subscriber_t::null() +pub extern "C" fn ze_querying_subscriber_null( + this: *mut MaybeUninit, +) { + let this = ze_owned_querying_subscriber_t::transmute_uninit_ptr(this); + Inplace::empty(this); } /// Represents the set of options that can be applied to a querying subscriber, @@ -251,6 +236,8 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn ze_undeclare_querying_subscriber(sub: &mut ze_owned_querying_subscriber_t) -> i8 { + let sub = sub.transmute_mut(); + if let Some(s) = sub.take() { if let Err(e) = s.fetching_subscriber.close().res_sync() { log::warn!("{}", e); diff --git a/src/transmute.rs b/src/transmute.rs index 2eccd4117..70ec1d863 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -102,7 +102,7 @@ macro_rules! validate_equivalence { #[macro_export] macro_rules! decl_transmute_owned { (default_inplace_init $zenoh_type:ty, $c_type:ty) => { - impl InplaceDefault for $zenoh_type {} + impl $crate::transmute::InplaceDefault for $zenoh_type {} decl_transmute_owned!(custom_inplace_init $zenoh_type, $c_type); }; From 41f2a0bae88f106e2b888762991383000033cbf1 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 20:02:21 +0200 Subject: [PATCH 040/377] commented out all, removed old macro --- include/zenoh-gen.h | 14 + include/zenoh_commons.h | 2465 -------------------------------------- include/zenoh_concrete.h | 55 - src/lib.rs | 175 +-- 4 files changed, 60 insertions(+), 2649 deletions(-) create mode 100644 include/zenoh-gen.h diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h new file mode 100644 index 000000000..0e648f1e9 --- /dev/null +++ b/include/zenoh-gen.h @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include + + +/** + * Initialises the zenoh runtime logger. + * + * Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, + * this will be performed automatically by `z_open` and `z_scout`. + */ +ZENOHC_API void zc_init_logger(void); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 0d5331ab6..9ef5cb4e1 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -15,2468 +15,3 @@ #define ALIGN(n) #define ZENOHC_API #endif -/** - * The kind of congestion control. - * - * - **BLOCK** - * - **DROP** - */ -typedef enum z_congestion_control_t { - Z_CONGESTION_CONTROL_BLOCK, - Z_CONGESTION_CONTROL_DROP, -} z_congestion_control_t; -/** - * Consolidation mode values. - * - * - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector - * If the selector contains time range properties, consolidation mode `NONE` is used. - * Otherwise the `LATEST` consolidation mode is used. - * - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. - * - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time - * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple - * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp - * ts2 > ts1. It optimizes latency. - * - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. - * It optimizes bandwidth. - */ -typedef enum z_consolidation_mode_t { - Z_CONSOLIDATION_MODE_AUTO = -1, - Z_CONSOLIDATION_MODE_NONE = 0, - Z_CONSOLIDATION_MODE_MONOTONIC = 1, - Z_CONSOLIDATION_MODE_LATEST = 2, -} z_consolidation_mode_t; -/** - * A :c:type:`z_keyexpr_intersection_level_t`. - * - * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** - */ -typedef enum z_keyexpr_intersection_level_t { - Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT = 0, - Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS = 1, - Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, - Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, -} z_keyexpr_intersection_level_t; -/** - * The priority of zenoh messages. - * - * - **REAL_TIME** - * - **INTERACTIVE_HIGH** - * - **INTERACTIVE_LOW** - * - **DATA_HIGH** - * - **DATA** - * - **DATA_LOW** - * - **BACKGROUND** - */ -typedef enum z_priority_t { - Z_PRIORITY_REAL_TIME = 1, - Z_PRIORITY_INTERACTIVE_HIGH = 2, - Z_PRIORITY_INTERACTIVE_LOW = 3, - Z_PRIORITY_DATA_HIGH = 4, - Z_PRIORITY_DATA = 5, - Z_PRIORITY_DATA_LOW = 6, - Z_PRIORITY_BACKGROUND = 7, -} z_priority_t; -/** - * The Queryables that should be target of a :c:func:`z_get`. - * - * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. - * - **ALL_COMPLETE**: All complete queryables. - * - **ALL**: All matching queryables. - */ -typedef enum z_query_target_t { - Z_QUERY_TARGET_BEST_MATCHING, - Z_QUERY_TARGET_ALL, - Z_QUERY_TARGET_ALL_COMPLETE, -} z_query_target_t; -typedef enum z_sample_kind_t { - Z_SAMPLE_KIND_PUT = 0, - Z_SAMPLE_KIND_DELETE = 1, -} z_sample_kind_t; -typedef enum zcu_locality_t { - ZCU_LOCALITY_ANY = 0, - ZCU_LOCALITY_SESSION_LOCAL = 1, - ZCU_LOCALITY_REMOTE = 2, -} zcu_locality_t; -typedef enum zcu_reply_keyexpr_t { - ZCU_REPLY_KEYEXPR_ANY = 0, - ZCU_REPLY_KEYEXPR_MATCHING_QUERY = 1, -} zcu_reply_keyexpr_t; -/** - * A contiguous view of bytes owned by some other entity. - * - * `start` being `null` is considered a gravestone value, - * and empty slices are represented using a possibly dangling pointer for `start`. - */ -typedef struct z_bytes_t { - const uint8_t *start; - size_t len; -} z_bytes_t; -/** - * The body of a loop over an attachment's key-value pairs. - * - * `key` and `value` are loaned to the body for the duration of a single call. - * `context` is passed transparently through the iteration driver. - * - * Returning `0` is treated as `continue`. - * Returning any other value is treated as `break`. - */ -typedef int8_t (*z_attachment_iter_body_t)(struct z_bytes_t key, - struct z_bytes_t value, - void *context); -/** - * The driver of a loop over an attachment's key-value pairs. - * - * This function is expected to call `loop_body` once for each key-value pair - * within `iterator`, passing `context`, and returning any non-zero value immediately (breaking iteration). - */ -typedef int8_t (*z_attachment_iter_driver_t)(const void *iterator, - z_attachment_iter_body_t loop_body, - void *context); -/** - * A iteration based map of byte slice to byte slice. - * - * `iteration_driver == NULL` marks the gravestone value, as this type is often optional. - * Users are encouraged to use `z_attachment_null` and `z_attachment_check` to interact. - */ -typedef struct z_attachment_t { - const void *data; - z_attachment_iter_driver_t iteration_driver; -} z_attachment_t; -/** - * A split buffer that owns all of its data. - * - * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - */ -typedef struct ALIGN(8) z_owned_buffer_t { - uint8_t _0[40]; -} z_owned_buffer_t; -/** - * A loan of a `z_owned_buffer_t`. - * - * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. - */ -typedef struct z_buffer_t { - struct z_owned_buffer_t *_inner; -} z_buffer_t; -typedef struct z_owned_bytes_t { - uint8_t *start; - size_t len; -} z_owned_bytes_t; -/** - * A map of maybe-owned vector of bytes to owned vector of bytes. - * - * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher - */ -typedef struct z_owned_bytes_map_t { - uint64_t _0[2]; - size_t _1[4]; -} z_owned_bytes_map_t; -/** - * Clock - * Uses monotonic clock - */ -typedef struct z_clock_t { - uint64_t t; - const void *t_base; -} z_clock_t; -/** - * Represents a Zenoh ID. - * - * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. - */ -typedef struct z_id_t { - uint8_t id[16]; -} z_id_t; -/** - * An owned array of owned, zenoh allocated, NULL terminated strings. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_str_array_t { - char **val; - size_t len; -} z_owned_str_array_t; -/** - * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct z_owned_hello_t { - unsigned int _whatami; - struct z_id_t _pid; - struct z_owned_str_array_t _locators; -} z_owned_hello_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_hello_t { - void *context; - void (*call)(struct z_owned_hello_t*, void*); - void (*drop)(void*); -} z_owned_closure_hello_t; -typedef struct ALIGN(8) z_owned_query_t { - uint8_t _0[16]; -} z_owned_query_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_owned_query_t { - void *context; - void (*call)(struct z_owned_query_t*, void *context); - void (*drop)(void*); -} z_owned_closure_owned_query_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_query_t { - void *context; - void (*call)(const struct z_query_t*, void *context); - void (*drop)(void*); -} z_owned_closure_query_t; -typedef struct ALIGN(8) z_owned_reply_t { - uint8_t _0[256]; -} z_owned_reply_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_reply_t { - void *context; - void (*call)(struct z_owned_reply_t*, void*); - void (*drop)(void*); -} z_owned_closure_reply_t; -typedef struct ALIGN(8) z_sample_t { - uint8_t _0[8]; -} z_sample_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_sample_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_sample_t { - void *context; - void (*call)(const struct z_sample_t*, void *context); - void (*drop)(void*); -} z_owned_closure_sample_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_zid_t { - void *context; - void (*call)(const struct z_id_t*, void*); - void (*drop)(void*); -} z_owned_closure_zid_t; -/** - * Condvar - * - */ -typedef struct z_condvar_t { - size_t _0; -} z_condvar_t; -/** - * Mutex - * - */ -typedef struct z_mutex_t { - size_t _0; -} z_mutex_t; -/** - * An owned zenoh configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_config_t { - void *_0; -} z_owned_config_t; -/** - * A loaned zenoh configuration. - */ -typedef struct z_config_t { - const struct z_owned_config_t *_0; -} z_config_t; -/** - * A zenoh-allocated key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` - * for wire and computation efficiency. - * - * A `key expression `_ can be either: - * - A plain string expression. - * - A pure numerical id. - * - The combination of a numerical prefix and a string suffix. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_keyexpr_t { - uint64_t _0[4]; -} z_owned_keyexpr_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_keyexpr_t { - uint32_t _0[5]; -} z_owned_keyexpr_t; -#endif -/** - * A loaned key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, - * both for local processing and network-wise. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_keyexpr_t { - uint64_t _0[4]; -} z_keyexpr_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_keyexpr_t { - uint32_t _0[5]; -} z_keyexpr_t; -#endif -/** - * An owned zenoh publisher. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_publisher_t { - uint64_t _0[7]; -} z_owned_publisher_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_publisher_t { - uint32_t _0[8]; -} z_owned_publisher_t; -#endif -/** - * Options passed to the :c:func:`z_declare_publisher` function. - * - * Members: - * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. - * z_priority_t priority: The priority of messages from this publisher. - */ -typedef struct z_publisher_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_publisher_options_t; -/** - * Options passed to the :c:func:`z_declare_queryable` function. - * - * Members: - * bool complete: The completeness of the Queryable. - */ -typedef struct z_queryable_options_t { - bool complete; -} z_queryable_options_t; -/** - * Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - */ -typedef struct z_subscriber_options_t { - -} z_subscriber_options_t; -/** - * Options passed to the :c:func:`z_delete` function. - */ -typedef struct z_delete_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_delete_options_t; -typedef struct ALIGN(8) z_owned_encoding_t { - uint8_t _0[48]; -} z_owned_encoding_t; -typedef struct ALIGN(8) z_encoding_t { - uint8_t _0[8]; -} z_encoding_t; -/** - * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. - */ -typedef struct z_query_consolidation_t { - enum z_consolidation_mode_t mode; -} z_query_consolidation_t; -/** - * An owned payload, backed by a reference counted owner. - * - * The `payload` field may be modified, and Zenoh will take the new values into account. - */ -typedef struct z_owned_buffer_t zc_owned_payload_t; -/** - * Options passed to the :c:func:`z_get` function. - * - * Members: - * z_query_target_t target: The Queryables that should be target of the query. - * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. - * z_value_t value: An optional value to attach to the query. - * z_attachment_t attachment: The attachment to attach to the query. - * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. - */ -typedef struct z_get_options_t { - enum z_query_target_t target; - struct z_query_consolidation_t consolidation; - zc_owned_payload_t payload; - struct z_encoding_t encoding; - struct z_attachment_t attachment; - uint64_t timeout_ms; -} z_get_options_t; -/** - * An borrowed array of borrowed, zenoh allocated, NULL terminated strings. - */ -typedef struct z_str_array_t { - size_t len; - const char *const *val; -} z_str_array_t; -/** - * A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct z_hello_t { - unsigned int whatami; - struct z_id_t pid; - struct z_str_array_t locators; -} z_hello_t; -/** - * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` - * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with - * `z_check` and `z_str_check` correspondently - */ -typedef struct z_owned_str_t { - char *_cstr; -} z_owned_str_t; -/** - * A loaned zenoh publisher. - */ -typedef struct z_publisher_t { - const struct z_owned_publisher_t *_0; -} z_publisher_t; -/** - * Represents the set of options that can be applied to the delete operation by a previously declared publisher, - * whenever issued via :c:func:`z_publisher_delete`. - */ -typedef struct z_publisher_delete_options_t { - uint8_t __dummy; -} z_publisher_delete_options_t; -/** - * Options passed to the :c:func:`z_publisher_put` function. - * - * Members: - * z_encoding_t encoding: The encoding of the payload. - * z_attachment_t attachment: The attachment to attach to the publication. - */ -typedef struct z_publisher_put_options_t { - struct z_encoding_t encoding; - struct z_attachment_t attachment; -} z_publisher_put_options_t; -/** - * Options passed to the :c:func:`z_put` function. - * - * Members: - * z_encoding_t encoding: The encoding of the payload. - * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. - * z_priority_t priority: The priority of this message. - * z_attachment_t attachment: The attachment to this message. - */ -typedef struct z_put_options_t { - struct z_encoding_t encoding; - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; - struct z_attachment_t attachment; -} z_put_options_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - `this` is a pointer to an arbitrary state. - * - `call` is the typical callback function. `this` will be passed as its last argument. - * - `drop` allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * We guarantee that: - * - `call` will never be called once `drop` has started. - * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_query_channel_closure_t { - void *context; - bool (*call)(struct z_owned_query_t*, void*); - void (*drop)(void*); -} z_owned_query_channel_closure_t; -/** - * A pair of closures - */ -typedef struct z_owned_query_channel_t { - struct z_owned_closure_owned_query_t send; - struct z_owned_query_channel_closure_t recv; -} z_owned_query_channel_t; -/** - * Represents the set of options that can be applied to a query reply, - * sent via :c:func:`z_query_reply`. - * - * Members: - * z_encoding_t encoding: The encoding of the payload. - * z_attachment_t attachment: The attachment to this reply. - */ -typedef struct z_query_reply_options_t { - struct z_encoding_t encoding; - struct z_attachment_t attachment; -} z_query_reply_options_t; -typedef struct ALIGN(8) z_value_t { - uint8_t _0[8]; -} z_value_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - `this` is a pointer to an arbitrary state. - * - `call` is the typical callback function. `this` will be passed as its last argument. - * - `drop` allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * We guarantee that: - * - `call` will never be called once `drop` has started. - * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_reply_channel_closure_t { - void *context; - bool (*call)(struct z_owned_reply_t*, void*); - void (*drop)(void*); -} z_owned_reply_channel_closure_t; -/** - * A pair of closures, the `send` one accepting - */ -typedef struct z_owned_reply_channel_t { - struct z_owned_closure_reply_t send; - struct z_owned_reply_channel_closure_t recv; -} z_owned_reply_channel_t; -typedef struct z_buffer_t zc_payload_t; -typedef struct z_timestamp_t { - uint64_t time; - struct z_id_t id; -} z_timestamp_t; -typedef struct z_owned_scouting_config_t { - struct z_owned_config_t _config; - unsigned long zc_timeout_ms; - uint8_t zc_what; -} z_owned_scouting_config_t; -/** - * A loaned zenoh subscriber. - */ -typedef struct z_subscriber_t { - const struct z_owned_subscriber_t *_0; -} z_subscriber_t; -/** - * Task - * - */ -typedef struct z_task_t { - size_t _0; -} z_task_t; -typedef struct z_task_attr_t { - size_t _0; -} z_task_attr_t; -/** - * Time - * Uses system clock - */ -typedef struct z_time_t { - uint64_t t; -} z_time_t; -/** - * The options for `zc_liveliness_declare_token` - */ -typedef struct zc_owned_liveliness_declaration_options_t { - uint8_t _inner; -} zc_owned_liveliness_declaration_options_t; -/** - * The options for :c:func:`zc_liveliness_declare_subscriber` - */ -typedef struct zc_owned_liveliness_declare_subscriber_options_t { - uint8_t _inner; -} zc_owned_liveliness_declare_subscriber_options_t; -/** - * A liveliness token that can be used to provide the network with information about connectivity to its - * declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key - * expressions. - * - * A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. - */ -typedef struct zc_owned_liveliness_token_t { - size_t _inner[4]; -} zc_owned_liveliness_token_t; -/** - * The options for :c:func:`zc_liveliness_declare_subscriber` - */ -typedef struct zc_liveliness_get_options_t { - uint32_t timeout_ms; -} zc_liveliness_get_options_t; -/** - * A reader for payload data. - */ -typedef struct ALIGN(8) zc_payload_reader { - uint8_t _0[24]; -} zc_payload_reader; -/** - * An owned sample. - * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. - */ -typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[240]; -} zc_owned_sample_t; -typedef struct zc_owned_shmbuf_t { - size_t _0[9]; -} zc_owned_shmbuf_t; -typedef struct zc_owned_shm_manager_t { - size_t _0; -} zc_owned_shm_manager_t; -/** - * A struct that indicates if there exist Subscribers matching the Publisher's key expression. - * - * Members: - * bool matching: true if there exist Subscribers matching the Publisher's key expression. - */ -typedef struct zcu_matching_status_t { - bool matching; -} zcu_matching_status_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct zcu_owned_closure_matching_status_t { - void *context; - void (*call)(const struct zcu_matching_status_t*, void*); - void (*drop)(void*); -} zcu_owned_closure_matching_status_t; -/** - * An owned zenoh matching listener. Destroying the matching listener cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) zcu_owned_matching_listener_t { - uint64_t _0[4]; -} zcu_owned_matching_listener_t; -/** - * An owned zenoh publication_cache. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ze_owned_publication_cache_t { - size_t _0[1]; -} ze_owned_publication_cache_t; -/** - * Options passed to the :c:func:`ze_declare_publication_cache` function. - * - * Members: - * z_keyexpr_t queryable_prefix: The prefix used for queryable - * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this - * publication cache - * bool queryable_complete: the `complete` option for the queryable - * size_t history: The the history size - * size_t resources_limit: The limit number of cached resources - */ -typedef struct ze_publication_cache_options_t { - struct z_keyexpr_t queryable_prefix; - enum zcu_locality_t queryable_origin; - bool queryable_complete; - size_t history; - size_t resources_limit; -} ze_publication_cache_options_t; -ZENOHC_API extern const unsigned int Z_ROUTER; -ZENOHC_API extern const unsigned int Z_PEER; -ZENOHC_API extern const unsigned int Z_CLIENT; -ZENOHC_API extern const char *Z_CONFIG_MODE_KEY; -ZENOHC_API extern const char *Z_CONFIG_CONNECT_KEY; -ZENOHC_API extern const char *Z_CONFIG_LISTEN_KEY; -ZENOHC_API extern const char *Z_CONFIG_USER_KEY; -ZENOHC_API extern const char *Z_CONFIG_PASSWORD_KEY; -ZENOHC_API extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; -ZENOHC_API extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; -ZENOHC_API extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; -ZENOHC_API extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; -ZENOHC_API extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; -ZENOHC_API extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; -/** - * Returns the gravestone value for `z_attachment_t`. - */ -ZENOHC_API bool z_attachment_check(const struct z_attachment_t *this_); -/** - * Returns the value associated with the key. - */ -ZENOHC_API struct z_bytes_t z_attachment_get(struct z_attachment_t this_, struct z_bytes_t key); -/** - * Returns true if `z_attachment_t` contains no key-value pairs, false otherwise. - */ -ZENOHC_API bool z_attachment_is_empty(struct z_attachment_t this_); -/** - * Iterate over `this`'s key-value pairs, breaking if `body` returns a non-zero - * value for a key-value pair, and returning the latest return value. - * - * `context` is passed to `body` to allow stateful closures. - * - * This function takes no ownership whatsoever. - */ -ZENOHC_API -int8_t z_attachment_iterate(struct z_attachment_t this_, - z_attachment_iter_body_t body, - void *context); -/** - * Returns number of key-value pairs for `z_attachment_t`. - * - * Does so by iterating over all existing key-value pairs. - */ -ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); -/** - * Returns the gravestone value for `z_attachment_t`. - */ -ZENOHC_API struct z_attachment_t z_attachment_null(void); -/** - * Returns `true` if the buffer is in a valid state. - */ -ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); -/** - * Increments the buffer's reference count, returning an owned version of the buffer. - */ -ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); -/** - * Decrements the buffer's reference counter, destroying it if applicable. - * - * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. - */ -ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); -/** - * Returns total number bytes in the buffer. - */ -ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); -/** - * Loans the buffer, allowing you to call functions that only need a loan of it. - */ -ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); -/** - * The gravestone value for `z_owned_buffer_t`. - */ -ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); -/** - * Returns the `index`th slice of the buffer, aliasing it. - * - * Out of bounds accesses will return `z_bytes_empty`. - */ -ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); -/** - * Returns the number of slices in the buffer. - * - * If the return value is 0 or 1, then the buffer's data is contiguous in memory. - */ -ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *b); -ZENOHC_API struct z_owned_bytes_t z_bytes_clone(const struct z_bytes_t *b); -/** - * Returns the gravestone value for `z_bytes_t` - */ -ZENOHC_API struct z_bytes_t z_bytes_empty(void); -/** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_bytes_empty()` - */ -ZENOHC_API struct z_bytes_t z_bytes_from_str(const char *str); -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_bytes_is_initialized(const struct z_bytes_t *b); -ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *b); -/** - * Aliases `this` into a generic `z_attachment_t`, allowing it to be passed to corresponding APIs. - */ -ZENOHC_API struct z_attachment_t z_bytes_map_as_attachment(const struct z_owned_bytes_map_t *this_); -/** - * Returns `true` if the map is not in its gravestone state - */ -ZENOHC_API bool z_bytes_map_check(const struct z_owned_bytes_map_t *this_); -/** - * Destroys the map, resetting `this` to its gravestone value. - * - * This function is double-free safe, passing a pointer to the gravestone value will have no effect. - */ -ZENOHC_API void z_bytes_map_drop(struct z_owned_bytes_map_t *this_); -/** - * Constructs a map from the provided attachment, copying keys and values. - * - * If `this` is at gravestone value, the returned value will also be at gravestone value. - */ -ZENOHC_API struct z_owned_bytes_map_t z_bytes_map_from_attachment(struct z_attachment_t this_); -/** - * Constructs a map from the provided attachment, aliasing the attachment's keys and values. - * - * If `this` is at gravestone value, the returned value will also be at gravestone value. - */ -ZENOHC_API -struct z_owned_bytes_map_t z_bytes_map_from_attachment_aliasing(struct z_attachment_t this_); -/** - * Returns the value associated with `key`, returning a gravestone value if: - * - `this` or `key` is in gravestone state. - * - `this` has no value associated to `key` - */ -ZENOHC_API -struct z_bytes_t z_bytes_map_get(const struct z_owned_bytes_map_t *this_, - struct z_bytes_t key); -/** - * Associates `value` to `key` in the map, aliasing them. - * - * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. - * - * Calling this with `NULL` or the gravestone value is undefined behaviour. - */ -ZENOHC_API -void z_bytes_map_insert_by_alias(const struct z_owned_bytes_map_t *this_, - struct z_bytes_t key, - struct z_bytes_t value); -/** - * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. - * - * Calling this with `NULL` or the gravestone value is undefined behaviour. - */ -ZENOHC_API -void z_bytes_map_insert_by_copy(const struct z_owned_bytes_map_t *this_, - struct z_bytes_t key, - struct z_bytes_t value); -/** - * Returns true if the map is empty, false otherwise. - */ -ZENOHC_API bool z_bytes_map_is_empty(struct z_owned_bytes_map_t *this_); -/** - * Iterates over the key-value pairs in the map. - * - * `body` will be called once per pair, with `ctx` as its last argument. - * If `body` returns a non-zero value, the iteration will stop immediately and the value will be returned. - * Otherwise, this will return 0 once all pairs have been visited. - * `body` is not given ownership of the key nor value, which alias the pairs in the map. - * It is safe to keep these aliases until existing keys are modified/removed, or the map is destroyed. - * Note that this map is unordered. - * - * Calling this with `NULL` or the gravestone value is undefined behaviour. - */ -ZENOHC_API -int8_t z_bytes_map_iter(const struct z_owned_bytes_map_t *this_, - z_attachment_iter_body_t body, - void *ctx); -/** - * Returns number of key-value pairs in the map. - */ -ZENOHC_API size_t z_bytes_map_len(struct z_owned_bytes_map_t *this_); -/** - * Constructs a new map. - */ -ZENOHC_API struct z_owned_bytes_map_t z_bytes_map_new(void); -/** - * Constructs the gravestone value for `z_owned_bytes_map_t` - */ -ZENOHC_API struct z_owned_bytes_map_t z_bytes_map_null(void); -/** - * Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_bytes_empty()` - */ -ZENOHC_API -struct z_bytes_t z_bytes_new(const char *str); -/** - * Returns the gravestone value for `z_owned_bytes_t` - */ -ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); -/** - * Constructs a `len` bytes long view starting at `start`. - */ -ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); -ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); -ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); -ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); -ZENOHC_API struct z_clock_t z_clock_now(void); -/** - * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. - * - * Returns a negative value if an error occured while closing the session. - * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. - */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_hello_call(const struct z_owned_closure_hello_t *closure, - struct z_owned_hello_t *hello); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_hello_drop(struct z_owned_closure_hello_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type - */ -ZENOHC_API struct z_owned_closure_hello_t z_closure_hello_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_owned_query_call(const struct z_owned_closure_owned_query_t *closure, - struct z_owned_query_t *query); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_owned_query_drop(struct z_owned_closure_owned_query_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type - */ -ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_query_call(const struct z_owned_closure_query_t *closure, - const struct z_query_t *query); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_query_drop(struct z_owned_closure_query_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type - */ -ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, - struct z_owned_reply_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_reply_drop(struct z_owned_closure_reply_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type - */ -ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - const struct z_sample_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_sample_drop(struct z_owned_closure_sample_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type - */ -ZENOHC_API struct z_owned_closure_sample_t z_closure_sample_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_zid_call(const struct z_owned_closure_zid_t *closure, - const struct z_id_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type - */ -ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); -ZENOHC_API int8_t z_condvar_free(struct z_condvar_t *cv); -ZENOHC_API int8_t z_condvar_init(struct z_condvar_t *cv); -ZENOHC_API int8_t z_condvar_signal(struct z_condvar_t *cv); -ZENOHC_API int8_t z_condvar_wait(struct z_condvar_t *cv, struct z_mutex_t *m); -/** - * Returns ``true`` if `config` is valid. - */ -ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); -/** - * Constructs a default, zenoh-allocated, client mode configuration. - * If `peer` is not null, it is added to the configuration as remote peer. - */ -ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); -/** - * Creates a default, zenoh-allocated, configuration. - */ -ZENOHC_API struct z_owned_config_t z_config_default(void); -/** - * Frees `config`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); -/** - * Returns a :c:type:`z_config_t` loaned from `s`. - */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); -/** - * Return a new, zenoh-allocated, empty configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -struct z_owned_config_t z_config_new(void); -/** - * Constructs a null safe-to-drop value of 'z_owned_config_t' type - */ -ZENOHC_API struct z_owned_config_t z_config_null(void); -/** - * Constructs a default, zenoh-allocated, peer mode configuration. - */ -ZENOHC_API struct z_owned_config_t z_config_peer(void); -/** - * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. - * - * This numerical id will be used on the network to save bandwidth and - * ease the retrieval of the concerned resource in the routing tables. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_declare_keyexpr(struct z_session_t session, - struct z_keyexpr_t keyexpr); -/** - * Declares a publisher for the given key expression. - * - * Data can be put and deleted with this publisher with the help of the - * :c:func:`z_publisher_put` and :c:func:`z_publisher_delete` functions. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to publish. - * options: additional options for the publisher. - * - * Returns: - * A :c:type:`z_owned_publisherr_t`. - * - * To check if the publisher decalration succeeded and if the publisher is still valid, - * you may use `z_publisher_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a publisher passing `NULL` for the options: - * - * .. code-block:: C - * - * z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(expr), NULL); - * - * is equivalent to initializing and passing the default publisher options: - * - * .. code-block:: C - * - * z_publisher_options_t opts = z_publisher_options_default(); - * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); - */ -ZENOHC_API -struct z_owned_publisher_t z_declare_publisher(struct z_session_t session, - struct z_keyexpr_t keyexpr, - const struct z_publisher_options_t *options); -/** - * Creates a Queryable for the given key expression. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression the Queryable will reply to. - * callback: The callback function that will be called each time a matching query is received. - * options: Options for the queryable. - * - * Returns: - * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. - */ -ZENOHC_API -struct z_owned_queryable_t z_declare_queryable(struct z_session_t session, - struct z_keyexpr_t keyexpr, - struct z_owned_closure_query_t *callback, - const struct z_queryable_options_t *options); -/** - * Declare a subscriber for a given key expression. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to subscribe. - * callback: The callback function that will be called each time a data matching the subscribed expression is received. - * opts: The options to be passed to describe the options to be passed to the subscriber declaration. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the subscriber is still valid, - * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing `NULL` for the options: - * - * .. code-block:: C - * - * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -struct z_owned_subscriber_t z_declare_subscriber(struct z_session_t session, - struct z_keyexpr_t keyexpr, - struct z_owned_closure_sample_t *callback, - const struct z_subscriber_options_t *opts); -/** - * Delete data. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to delete. - * options: The put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -int8_t z_delete(struct z_session_t session, - struct z_keyexpr_t keyexpr, - const struct z_delete_options_t *opts); -/** - * Constructs the default value for :c:type:`z_put_options_t`. - */ -ZENOHC_API struct z_delete_options_t z_delete_options_default(void); -/** - * Returns ``true`` if `encoding` is valid. - */ -ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); -/** - * Constructs a default :c:type:`z_encoding_t`. - */ -ZENOHC_API struct z_encoding_t z_encoding_default(void); -/** - * Frees `encoding`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); -/** - * Constructs a specific :c:type:`z_encoding_t`. - */ -ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); -/** - * Returns a :c:type:`z_encoding_t` loaned from `encoding`. - */ -ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); -/** - * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type - */ -ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); -/** - * Query data from the matching queryables in the system. - * Replies are provided through a callback function. - * - * Returns a negative value upon failure. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression matching resources to query. - * parameters: The query's parameters, similar to a url's query segment. - * callback: The callback function that will be called on reception of replies for this query. - * Note that the `reply` parameter of the callback is passed by mutable reference, - * but **will** be dropped once your callback exits to help you avoid memory leaks. - * If you'd rather take ownership, please refer to the documentation of :c:func:`z_reply_null` - * options: additional options for the get. - */ -ZENOHC_API -int8_t z_get(struct z_session_t session, - struct z_keyexpr_t keyexpr, - const char *parameters, - struct z_owned_closure_reply_t *callback, - struct z_get_options_t *options); -ZENOHC_API struct z_get_options_t z_get_options_default(void); -/** - * Returns ``true`` if `hello` is valid. - */ -ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *hello); -/** - * Frees `hello`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); -/** - * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. - */ -ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); -/** - * Constructs a gravestone value for hello, useful to steal one from a callback - */ -ZENOHC_API struct z_owned_hello_t z_hello_null(void); -/** - * Fetches the Zenoh IDs of all connected peers. - * - * `callback` will be called once for each ID, is guaranteed to never be called concurrently, - * and is guaranteed to be dropped before this function exits. - * - * Retuns 0 on success, negative values on failure - */ -ZENOHC_API -int8_t z_info_peers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); -/** - * Fetches the Zenoh IDs of all connected routers. - * - * `callback` will be called once for each ID, is guaranteed to never be called concurrently, - * and is guaranteed to be dropped before this function exits. - * - * Retuns 0 on success, negative values on failure. - */ -ZENOHC_API -int8_t z_info_routers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); -/** - * Returns the local Zenoh ID. - * - * Unless the `session` is invalid, that ID is guaranteed to be non-zero. - * In other words, this function returning an array of 16 zeros means you failed - * to pass it a valid session. - */ -ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr(const char *name); -/** - * Returns the key expression's internal string by aliasing it. - * - * 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`. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -int8_t z_keyexpr_canonize(char *start, - size_t *len); -/** - * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -int8_t z_keyexpr_canonize_null_terminated(char *start); -/** - * Returns ``true`` if `keyexpr` is valid. - */ -ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); -/** - * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - * - * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. - * - * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, - * as this would extremely likely cause bugs. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_keyexpr_concat(struct z_keyexpr_t left, - const char *right_start, - size_t right_len); -/** - * Frees `keyexpr` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); -/** - * Returns ``0`` if both ``left`` and ``right`` are equal. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_equals(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set - * defined by ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_includes(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the - * sets defined by ``left`` and ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_intersects(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Returns ``0`` if the passed string is a valid (and canon) key expression. - * Otherwise returns error value - */ -ZENOHC_API int8_t z_keyexpr_is_canon(const char *start, size_t len); -/** - * Returns ``true`` if `keyexpr` is initialized. - */ -ZENOHC_API bool z_keyexpr_is_initialized(const struct z_keyexpr_t *keyexpr); -/** - * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *keyexpr); -/** - * 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 - */ -ZENOHC_API struct z_owned_keyexpr_t z_keyexpr_null(void); -/** - * Returns the relation between `left` and `right` from `left`'s point of view. - * - * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. - */ -ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. - * The user is responsible of droping the returned string using `z_drop` - */ -ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t keyexpr); -/** - * 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: - * - * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. - * - any instance of `**` may only be lead or followed by `/`. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -struct z_keyexpr_t z_keyexpr_unchecked(const char *name); -ZENOHC_API int8_t z_mutex_free(struct z_mutex_t *m); -ZENOHC_API int8_t z_mutex_init(struct z_mutex_t *m); -ZENOHC_API int8_t z_mutex_lock(struct z_mutex_t *m); -ZENOHC_API int8_t z_mutex_try_lock(struct z_mutex_t *m); -ZENOHC_API int8_t z_mutex_unlock(struct z_mutex_t *m); -/** - * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. - */ -ZENOHC_API -struct z_owned_session_t z_open(struct z_owned_config_t *config); -/** - * Returns ``true`` if `pub` is valid. - */ -ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); -/** - * Sends a `DELETE` message onto the publisher's key expression. - * - * Returns: - * ``0`` in case of success, ``1`` in case of failure. - */ -ZENOHC_API -int8_t z_publisher_delete(struct z_publisher_t publisher, - const struct z_publisher_delete_options_t *_options); -/** - * Constructs the default values for the delete operation via a publisher entity. - * - * Returns: - * Returns the constructed :c:type:`z_publisher_delete_options_t`. - */ -ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); -/** - * Returns the key expression of the publisher - */ -ZENOHC_API struct z_owned_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); -/** - * Returns a :c:type:`z_publisher_t` loaned from `p`. - */ -ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); -/** - * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type - */ -ZENOHC_API struct z_owned_publisher_t z_publisher_null(void); -/** - * Constructs the default value for :c:type:`z_publisher_options_t`. - */ -ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); -/** - * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload's encoding can be sepcified through the options. - * - * Parameters: - * session: The zenoh session. - * payload: The value to put. - * options: The publisher put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -int8_t z_publisher_put(struct z_publisher_t publisher, - zc_owned_payload_t *payload, - const struct z_publisher_put_options_t *options); -/** - * Constructs the default value for :c:type:`z_publisher_put_options_t`. - */ -ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); -/** - * Put data, transfering the buffer ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload's encoding can be sepcified through the options. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to put. - * payload: The value to put. - * options: The put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -int8_t z_put(struct z_session_t session, - struct z_keyexpr_t keyexpr, - zc_owned_payload_t *payload, - const struct z_put_options_t *opts); -/** - * Constructs the default value for :c:type:`z_put_options_t`. - */ -ZENOHC_API struct z_put_options_t z_put_options_default(void); -/** - * Returns the attachment to the query by aliasing. - * - * `z_check(return_value) == false` if there was no attachment to the query. - */ -ZENOHC_API struct z_attachment_t z_query_attachment(const struct z_query_t *query); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -bool z_query_channel_closure_call(const struct z_owned_query_channel_closure_t *closure, - struct z_owned_query_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_query_channel_closure_drop(struct z_owned_query_channel_closure_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type - */ -ZENOHC_API struct z_owned_query_channel_closure_t z_query_channel_closure_null(void); -ZENOHC_API void z_query_channel_drop(struct z_owned_query_channel_t *channel); -/** - * Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type - */ -ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); -/** - * Returns `false` if `this` is in a gravestone state, `true` otherwise. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -bool z_query_check(const struct z_owned_query_t *query); -/** - * Clones the query, allowing to keep it in an "open" state past the callback's return. - * - * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). - */ -ZENOHC_API -struct z_owned_query_t z_query_clone(struct z_query_t query); -/** - * Automatic query consolidation strategy selection. - * - * A query consolidation strategy will automatically be selected depending the query selector. - * If the selector contains time range properties, no consolidation is performed. - * Otherwise the :c:func:`z_query_consolidation_latest` strategy is used. - * - * Returns: - * Returns the constructed :c:type:`z_query_consolidation_t`. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_auto(void); -/** - * Creates a default :c:type:`z_query_consolidation_t` (consolidation mode AUTO). - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_default(void); -/** - * Latest value consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_latest(void); -/** - * Monotonic consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_monotonic(void); -/** - * Disable consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); -/** - * Destroys the query, setting `this` to its gravestone value to prevent double-frees. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -void z_query_drop(struct z_owned_query_t *this_); -/** - * Get a query's key by aliasing it. - */ -ZENOHC_API struct z_keyexpr_t z_query_keyexpr(const struct z_query_t *query); -/** - * Aliases the query. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -struct z_query_t z_query_loan(const struct z_owned_query_t *this_); -/** - * The gravestone value of `z_owned_query_t`. - */ -ZENOHC_API void z_query_null(struct z_owned_query_t *query); -/** - * Get a query's `value selector `_ by aliasing it. - */ -ZENOHC_API -struct z_bytes_t z_query_parameters(const struct z_query_t *query); -/** - * Send a reply to a query. - * - * This function must be called inside of a Queryable callback passing the - * query received as parameters of the callback function. This function can - * be called multiple times to send multiple replies to a query. The reply - * will be considered complete when the Queryable callback returns. - * - * Parameters: - * query: The query to reply to. - * key: The key of this reply. - * payload: The value of this reply. - * options: The options of this reply. - */ -ZENOHC_API -int8_t z_query_reply(const struct z_query_t *query, - struct z_keyexpr_t key, - zc_owned_payload_t *payload, - const struct z_query_reply_options_t *options); -/** - * Constructs the default value for :c:type:`z_query_reply_options_t`. - */ -ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); -/** - * Create a default :c:type:`z_query_target_t`. - */ -ZENOHC_API enum z_query_target_t z_query_target_default(void); -/** - * Get a query's `payload value `_ by aliasing it. - * - * **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** - */ -ZENOHC_API -struct z_value_t z_query_value(const struct z_query_t *query); -/** - * Returns ``true`` if `qable` is valid. - */ -ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); -/** - * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type - */ -ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); -/** - * Constructs the default value for :c:type:`z_query_reply_options_t`. - */ -ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); -ZENOHC_API void z_random_fill(void *buf, size_t len); -ZENOHC_API uint16_t z_random_u16(void); -ZENOHC_API uint32_t z_random_u32(void); -ZENOHC_API uint64_t z_random_u64(void); -ZENOHC_API uint8_t z_random_u8(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -bool z_reply_channel_closure_call(const struct z_owned_reply_channel_closure_t *closure, - struct z_owned_reply_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_reply_channel_closure_drop(struct z_owned_reply_channel_closure_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type - */ -ZENOHC_API struct z_owned_reply_channel_closure_t z_reply_channel_closure_null(void); -ZENOHC_API void z_reply_channel_drop(struct z_owned_reply_channel_t *channel); -/** - * Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type - */ -ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); -/** - * Returns ``true`` if `reply_data` is valid. - */ -ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *reply_data); -/** - * Frees `reply_data`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_reply_drop(struct z_owned_reply_t *reply_data); -/** - * Yields the contents of the reply by asserting it indicates a failure. - * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. - */ -ZENOHC_API -struct z_value_t z_reply_err(const struct z_owned_reply_t *reply); -/** - * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. - * - * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. - */ -ZENOHC_API -bool z_reply_is_ok(const struct z_owned_reply_t *reply); -/** - * Returns an invalidated :c:type:`z_owned_reply_t`. - * - * This is useful when you wish to take ownership of a value from a callback to :c:func:`z_get`: - * - * - copy the value of the callback's argument's pointee, - * - overwrite the pointee with this function's return value, - * - you are now responsible for dropping your copy of the reply. - */ -ZENOHC_API void z_reply_null(struct z_owned_reply_t *reply); -/** - * Yields the contents of the reply by asserting it indicates a success. - * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. - */ -ZENOHC_API -struct z_sample_t z_reply_ok(const struct z_owned_reply_t *reply); -/** - * The qos with which the sample was received. - * TODO: split to methods (priority, congestion_control, express) - * The sample's attachment. - * - * `sample` is aliased by the return value. - */ -ZENOHC_API struct z_attachment_t z_sample_attachment(const struct z_sample_t *sample); -/** - * The encoding of the payload. - */ -ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); -/** - * The Key Expression of the sample. - * - * `sample` is aliased by its return value. - */ -ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); -/** - * The sample's kind (put or delete). - */ -ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); -/** - * Returns the sample's payload after incrementing its internal reference count. - * - * Note that other samples may have received the same buffer, meaning that mutating this buffer may - * affect the samples received by other subscribers. - */ -ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sample); -/** - * The sample's data, the return value aliases the sample. - * - * If you need ownership of the buffer, you may use `z_sample_owned_payload`. - */ -ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); -/** - * The samples timestamp - */ -ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); -/** - * Scout for routers and/or peers. - * - * Parameters: - * what: A whatami bitmask of zenoh entities kind to scout for. - * config: A set of properties to configure the scouting. - * timeout: The time (in milliseconds) that should be spent scouting. - * - * Returns 0 if successful, negative values upon failure. - */ -ZENOHC_API -int8_t z_scout(struct z_owned_scouting_config_t *config, - struct z_owned_closure_hello_t *callback); -ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); -ZENOHC_API struct z_owned_scouting_config_t z_scouting_config_default(void); -ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); -ZENOHC_API struct z_owned_scouting_config_t z_scouting_config_from(struct z_config_t config); -ZENOHC_API struct z_owned_scouting_config_t z_scouting_config_null(void); -/** - * Returns ``true`` if `session` is valid. - */ -ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); -/** - * Returns a :c:type:`z_session_t` loaned from `s`. - * - * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. - * - * # Safety - * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, - * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) - * have been destroyed is UB (likely SEGFAULT) - */ -ZENOHC_API -struct z_session_t z_session_loan(const struct z_owned_session_t *s); -/** - * Constructs a null safe-to-drop value of 'z_owned_session_t' type - */ -ZENOHC_API struct z_owned_session_t z_session_null(void); -ZENOHC_API int8_t z_sleep_ms(size_t time); -ZENOHC_API int8_t z_sleep_s(size_t time); -ZENOHC_API int8_t z_sleep_us(size_t time); -/** - * Returns ``true`` if `strs` is valid. - */ -ZENOHC_API bool z_str_array_check(const struct z_owned_str_array_t *strs); -/** - * Frees `strs` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); -/** - * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. - */ -ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); -/** - * Returns ``true`` if `s` is a valid string - */ -ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); -/** - * Frees `z_owned_str_t`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_str_drop(struct z_owned_str_t *s); -/** - * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. - */ -ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); -/** - * Returns undefined `z_owned_str_t` - */ -ZENOHC_API struct z_owned_str_t z_str_null(void); -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *sub); -/** - * Returns the key expression of the subscriber. - */ -ZENOHC_API struct z_owned_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); -/** - * Returns a :c:type:`z_subscriber_t` loaned from `p`. - */ -ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *p); -/** - * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type - */ -ZENOHC_API struct z_owned_subscriber_t z_subscriber_null(void); -/** - * Constructs the default value for :c:type:`z_subscriber_options_t`. - */ -ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); -ZENOHC_API -int8_t z_task_init(struct z_task_t *task, - const struct z_task_attr_t *_attr, - void (*fun)(void *arg), - void *arg); -ZENOHC_API int8_t z_task_join(struct z_task_t *task); -ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); -ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); -ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); -ZENOHC_API struct z_time_t z_time_now(void); -ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); -/** - * Returns ``true`` if `ts` is a valid timestamp - */ -ZENOHC_API bool z_timestamp_check(struct z_timestamp_t ts); -/** - * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. - */ -ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); -/** - * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -int8_t z_undeclare_publisher(struct z_owned_publisher_t *publisher); -/** - * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. - * - * Parameters: - * qable: The :c:type:`z_owned_queryable_t` to undeclare. - */ -ZENOHC_API int8_t z_undeclare_queryable(struct z_owned_queryable_t *qable); -/** - * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -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. - */ -ZENOHC_API -struct z_owned_config_t zc_config_from_file(const char *path); -/** - * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. - * - * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). - */ -ZENOHC_API -struct z_owned_config_t zc_config_from_str(const char *s); -/** - * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. - * Use `z_drop` to safely deallocate this string - */ -ZENOHC_API -struct z_owned_str_t zc_config_get(struct z_config_t config, - const char *key); -/** - * Inserts a JSON-serialized `value` at the `key` position of the configuration. - * - * Returns 0 if successful, a negative value otherwise. - */ -ZENOHC_API -int8_t zc_config_insert_json(struct z_config_t config, - const char *key, - const char *value); -/** - * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. - */ -ZENOHC_API -struct z_owned_str_t zc_config_to_string(struct z_config_t config); -/** - * Initialises the zenoh runtime logger. - * - * Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, - * this will be performed automatically by `z_open` and `z_scout`. - */ -ZENOHC_API void zc_init_logger(void); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * 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. - * - `name` MUST follow the Key Expression specification, ie: - * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. - * - any instance of ``**`` may only be lead or followed by ``/``. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -struct z_keyexpr_t zc_keyexpr_from_slice_unchecked(const char *start, - size_t len); -/** - * Returns `true` if the options are valid. - */ -ZENOHC_API -bool zc_liveliness_declaration_options_check(const struct zc_owned_liveliness_declaration_options_t *_opts); -/** - * Destroys the options. - */ -ZENOHC_API -void zc_liveliness_declaration_options_drop(struct zc_owned_liveliness_declaration_options_t *opts); -/** - * The gravestone value for `zc_owned_liveliness_declaration_options_t` - */ -ZENOHC_API -struct zc_owned_liveliness_declaration_options_t zc_liveliness_declaration_options_null(void); -/** - * Declares a subscriber on liveliness tokens that intersect `key`. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to subscribe. - * z_owned_closure_sample_t callback: The callback function that will be called each time a - * liveliness token status changed. - * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the subscriber is still valid, - * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -struct z_owned_subscriber_t zc_liveliness_declare_subscriber(struct z_session_t session, - struct z_keyexpr_t key, - struct z_owned_closure_sample_t *callback, - const struct zc_owned_liveliness_declare_subscriber_options_t *_options); -/** - * Constructs and declares a liveliness token on the network. - * - * Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity - * is achieved, and a DELETE sample if it's lost. - * - * Passing `NULL` as options is valid and equivalent to a pointer to the default options. - */ -ZENOHC_API -struct zc_owned_liveliness_token_t zc_liveliness_declare_token(struct z_session_t session, - struct z_keyexpr_t key, - const struct zc_owned_liveliness_declaration_options_t *_options); -/** - * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. - * - * Note that the same "value stealing" tricks apply as with a normal :c:func:`z_get` - * - * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. - */ -ZENOHC_API -int8_t zc_liveliness_get(struct z_session_t session, - struct z_keyexpr_t key, - struct z_owned_closure_reply_t *callback, - const struct zc_liveliness_get_options_t *options); -/** - * Returns `true` if the options are valid. - */ -ZENOHC_API bool zc_liveliness_get_options_check(const struct zc_liveliness_get_options_t *_opts); -/** - * The gravestone value for `zc_liveliness_get_options_t` - */ -ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); -/** - * Destroys the options. - */ -ZENOHC_API void zc_liveliness_get_options_drop(struct zc_liveliness_get_options_t *opts); -/** - * The gravestone value for `zc_liveliness_get_options_t` - */ -ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_null(void); -/** - * Returns `true` if the options are valid. - */ -ZENOHC_API -bool zc_liveliness_subscriber_options_check(const struct zc_owned_liveliness_declare_subscriber_options_t *_opts); -/** - * Destroys the options. - */ -ZENOHC_API -void zc_liveliness_subscriber_options_drop(struct zc_owned_liveliness_declare_subscriber_options_t *opts); -/** - * The gravestone value for `zc_owned_liveliness_declare_subscriber_options_t` - */ -ZENOHC_API -struct zc_owned_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_null(void); -/** - * Returns `true` unless the token is at its gravestone value. - */ -ZENOHC_API bool zc_liveliness_token_check(const struct zc_owned_liveliness_token_t *token); -/** - * The gravestone value for liveliness tokens. - */ -ZENOHC_API struct zc_owned_liveliness_token_t zc_liveliness_token_null(void); -/** - * Destroys a liveliness token, notifying subscribers of its destruction. - */ -ZENOHC_API void zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *token); -/** - * Returns `false` if `payload` is the gravestone value. - */ -ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); -/** - * Increments internal payload reference count, returning owned payload. - */ -ZENOHC_API zc_owned_payload_t zc_payload_clone(zc_payload_t payload); -/** - * Decodes payload into null-terminated string - */ -ZENOHC_API int8_t zc_payload_decode_into_bytes(zc_payload_t payload, struct z_owned_bytes_t *b); -/** - * Decodes payload into null-terminated string - */ -ZENOHC_API int8_t zc_payload_decode_into_string(zc_payload_t payload, struct z_owned_str_t *cstr); -/** - * Decrements `payload`'s backing refcount, releasing the memory if appropriate. - */ -ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); -/** - * Encodes byte sequence by aliasing. - */ -ZENOHC_API zc_owned_payload_t zc_payload_encode_from_bytes(struct z_bytes_t bytes); -/** - * Encodes a null-terminated string by aliasing. - */ -ZENOHC_API zc_owned_payload_t zc_payload_encode_from_string(const char *cstr); -/** - * Returns total number bytes in the payload. - */ -ZENOHC_API size_t zc_payload_len(zc_payload_t payload); -/** - * Returns a :c:type:`zc_payload_t` loaned from `payload`. - */ -ZENOHC_API zc_payload_t zc_payload_loan(const zc_owned_payload_t *payload); -/** - * Constructs `zc_owned_payload_t`'s gravestone value. - */ -ZENOHC_API zc_owned_payload_t zc_payload_null(void); -/** - * Clones the `payload` by incrementing its reference counter. - */ -ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); -/** - * Creates a reader for the specified `payload`. - * - * Returns 0 in case of success, -1 if `payload` is not valid. - */ -ZENOHC_API int8_t zc_payload_reader_init(zc_payload_t payload, struct zc_payload_reader *reader); -/** - * Reads data into specified destination. - * - * Will read at most `len` bytes. - * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. - */ -ZENOHC_API -size_t zc_payload_reader_read(struct zc_payload_reader *reader, - uint8_t *dest, - size_t len); -/** - * Returns number of the remaining bytes in the payload - * - */ -ZENOHC_API size_t zc_payload_reader_remaining(const struct zc_payload_reader *reader); -/** - * Creates a new blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, - * which it will then return; or until the `send` closure is dropped and all queries have been consumed, - * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); -/** - * Creates a new non-blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, - * which it will then return; or until the `send` closure is dropped and all queries have been consumed, - * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); -/** - * Creates a new blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, - * which it will then return; or until the `send` closure is dropped and all replies have been consumed, - * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); -/** - * Creates a new non-blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, - * which it will then return; or until the `send` closure is dropped and all replies have been consumed, - * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); -/** - * Returns `true` if `sample` is valid. - * - * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed - * unless the value has been dropped already. - */ -ZENOHC_API -bool zc_sample_check(const struct zc_owned_sample_t *sample); -/** - * Clone a sample in the cheapest way available. - */ -ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); -/** - * Destroy the sample. - */ -ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); -/** - * Borrow the sample, allowing calling its accessor methods. - * - * Calling this function using a dropped sample is undefined behaviour. - */ -ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); -ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); -/** - * Increments the session's reference count, returning a new owning handle. - */ -ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session); -/** - * Allocates a buffer of size `capacity` in the manager's memory. - * - * # Safety - * Calling this function concurrently with other shm functions on the same manager is UB. - */ -ZENOHC_API -struct zc_owned_shmbuf_t zc_shm_alloc(const struct zc_owned_shm_manager_t *manager, - size_t capacity); -/** - * Runs a defragmentation pass on the SHM manager. - * - * Note that this doesn't trigger a garbage collection pass, nor does it move currently allocated data. - * - * # Safety - * Calling this function concurrently with other shm functions on the same manager is UB. - */ -ZENOHC_API -size_t zc_shm_defrag(const struct zc_owned_shm_manager_t *manager); -/** - * Runs a garbage collection pass on the SHM manager. - * - * Returns the number of bytes that have been freed by the pass. - * - * # Safety - * Calling this function concurrently with other shm functions on the same manager is UB. - */ -ZENOHC_API size_t zc_shm_gc(const struct zc_owned_shm_manager_t *manager); -ZENOHC_API bool zc_shm_manager_check(const struct zc_owned_shm_manager_t *manager); -ZENOHC_API void zc_shm_manager_drop(struct zc_owned_shm_manager_t *manager); -ZENOHC_API -struct zc_owned_shm_manager_t zc_shm_manager_new(struct z_session_t session, - const char *id, - size_t size); -ZENOHC_API struct zc_owned_shm_manager_t zc_shm_manager_null(void); -/** - * Returns the capacity of the SHM buffer. - */ -ZENOHC_API size_t zc_shmbuf_capacity(const struct zc_owned_shmbuf_t *buf); -/** - * Returns `false` if `buf` is in its gravestone state. - */ -ZENOHC_API bool zc_shmbuf_check(const struct zc_owned_shmbuf_t *buf); -/** - * Drops the SHM buffer, decrementing its backing reference counter. - */ -ZENOHC_API void zc_shmbuf_drop(struct zc_owned_shmbuf_t *buf); -/** - * Constructs an owned payload from an owned SHM buffer. - */ -ZENOHC_API zc_owned_payload_t zc_shmbuf_into_payload(struct zc_owned_shmbuf_t *buf); -/** - * Returns the length of the SHM buffer. - * - * Note that when constructing an SHM buffer, length is defaulted to its capacity. - */ -ZENOHC_API size_t zc_shmbuf_length(const struct zc_owned_shmbuf_t *buf); -/** - * Constructs a null safe-to-drop value of type `zc_owned_shmbuf_t` - */ -ZENOHC_API struct zc_owned_shmbuf_t zc_shmbuf_null(void); -/** - * Returns the start of the SHM buffer. - */ -ZENOHC_API uint8_t *zc_shmbuf_ptr(const struct zc_owned_shmbuf_t *buf); -/** - * Sets the length of the SHM buffer. - * - * This lets Zenoh know how much of the data to write over the network when sending the value to non-SHM-compatible neighboors. - */ -ZENOHC_API -void zc_shmbuf_set_length(const struct zc_owned_shmbuf_t *buf, - size_t len); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void zcu_closure_matching_status_call(const struct zcu_owned_closure_matching_status_t *closure, - const struct zcu_matching_status_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API -void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t *closure); -/** - * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type - */ -ZENOHC_API struct zcu_owned_closure_matching_status_t zcu_closure_matching_status_null(void); -ZENOHC_API enum zcu_locality_t zcu_locality_default(void); -/** - * Register callback for notifying subscribers matching. - */ -ZENOHC_API -struct zcu_owned_matching_listener_t zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, - struct zcu_owned_closure_matching_status_t *callback); -ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); -/** - * Declares a Publication Cache. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to publish. - * ze_publication_cache_options_t options: Additional options for the publication_cache. - * - * Returns: - * :c:type:`ze_owned_publication_cache_t`. - * - * - * Example: - * Declaring a publication cache `NULL` for the options: - * - * .. code-block:: C - * - * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), NULL); - * - * is equivalent to initializing and passing the default publication cache options: - * - * .. code-block:: C - * - * ze_publication_cache_options_t opts = ze_publication_cache_options_default(); - * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); - */ -ZENOHC_API -struct ze_owned_publication_cache_t ze_declare_publication_cache(struct z_session_t session, - struct z_keyexpr_t keyexpr, - const struct ze_publication_cache_options_t *options); -/** - * Returns ``true`` if `pub_cache` is valid. - */ -ZENOHC_API bool ze_publication_cache_check(const struct ze_owned_publication_cache_t *pub_cache); -/** - * Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type - */ -ZENOHC_API struct ze_owned_publication_cache_t ze_publication_cache_null(void); -/** - * Constructs the default value for :c:type:`ze_publication_cache_options_t`. - */ -ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); -/** - * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -int8_t ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *pub_cache); diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 491551ee1..9ef5cb4e1 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -15,58 +15,3 @@ #define ALIGN(n) #define ZENOHC_API #endif -#include -#include -#include -#include -#include -#define DEFAULT_SCOUTING_TIMEOUT 1000 -/** - * An owned zenoh session. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_session_t { - size_t _0; -} z_owned_session_t; -typedef struct ALIGN(8) z_query_t { - uint8_t _0[8]; -} z_query_t; -/** - * A loaned zenoh session. - */ -typedef struct z_session_t { - size_t _0; -} z_session_t; -typedef struct ALIGN(8) z_owned_queryable_t { - uint8_t _0[32]; -} z_owned_queryable_t; -/** - * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_subscriber_t { - uint64_t _0[1]; -} z_owned_subscriber_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_subscriber_t { - uint32_t _0[1]; -} z_owned_subscriber_t; -#endif diff --git a/src/lib.rs b/src/lib.rs index 547d9178d..cc4b631f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,139 +14,56 @@ #![allow(non_camel_case_types)] -mod collections; -use std::cmp::min; -use std::slice; +// mod collections; +// use std::cmp::min; +// use std::slice; #[macro_use] mod transmute; -pub use crate::collections::*; -mod config; -pub use crate::config::*; -mod commons; -pub use crate::commons::*; -mod payload; -pub use crate::payload::*; -mod keyexpr; -pub use crate::keyexpr::*; -mod info; -pub use crate::info::*; -mod get; -pub use crate::get::*; -mod queryable; -pub use crate::queryable::*; -mod put; -pub use crate::put::*; -mod scouting; -pub use crate::scouting::*; -mod session; -pub use crate::session::*; -mod subscriber; -pub use crate::subscriber::*; -// mod pull_subscriber; -// pub use crate::pull_subscriber::*; -mod publisher; -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::*; -// Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. -// mod querying_subscriber; -// pub use querying_subscriber::*; -pub mod attachment; -pub use platform::*; -pub mod opaque_types; -pub mod platform; -#[cfg(feature = "shared-memory")] -mod shm; - -trait GuardedTransmute { - fn transmute(self) -> D; -} - -/// For internal use only. -/// -/// This macro is used to establish the equivalence between a Rust type (first parameter) and a C layout (second parameter). -/// -/// It automatically implements `From`, `Deref` and `DerefMut` to make writing code around these equivalent types. -/// -/// Because carrying around the proper semantics of lifetimes is hard, this macro fails to produce working code when lifetimes are -/// present in either parameter. You may then call it with the `noderefs` prefix to avoid the offending implementations being defined. -#[macro_export] -macro_rules! impl_guarded_transmute { - ($src_type:ty, $dst_type:ty) => { - impl_guarded_transmute!(noderefs $src_type, $dst_type); - impl From<$src_type> for $dst_type { - fn from(value: $src_type) -> $dst_type { - unsafe { core::mem::transmute(value) } - } - } - impl core::ops::Deref for $dst_type { - type Target = $src_type; - fn deref(&self) -> &$src_type { - unsafe { core::mem::transmute(self) } - } - } - impl core::ops::DerefMut for $dst_type { - fn deref_mut(&mut self) -> &mut $src_type { - unsafe { core::mem::transmute(self) } - } - } - - }; - (noderefs $src_type:ty, $dst_type:ty) => { - const _: () = { - let src = std::mem::align_of::<$src_type>(); - let dst = std::mem::align_of::<$dst_type>(); - if src != dst { - let mut msg: [u8; 20] = *b"src: , dst: "; - let mut i = 0; - while i < 4 { - msg[i as usize + 5] = b'0' + ((src / 10u32.pow(3 - i) as usize) % 10) as u8; - msg[i as usize + 16] = b'0' + ((dst / 10u32.pow(3 - i) as usize) % 10) as u8; - i += 1; - } - panic!("{}", unsafe { - std::str::from_utf8_unchecked(msg.as_slice()) - }); - } - }; - impl $crate::GuardedTransmute<$dst_type> for $src_type { - fn transmute(self) -> $dst_type { - unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } - } - } - }; - ($src_type:ty, $dst_type:ty, $($gen: tt)*) => { - impl<$($gen)*> $crate::GuardedTransmute<$dst_type> for $src_type { - fn transmute(self) -> $dst_type { - unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } - } - } - impl<$($gen)*> From<$src_type> for $dst_type { - fn from(value: $src_type) -> $dst_type { - unsafe { core::mem::transmute(value) } - } - } - impl<$($gen)*> core::ops::Deref for $dst_type { - type Target = $src_type; - fn deref(&self) -> &$src_type { - unsafe { core::mem::transmute(self) } - } - } - impl<$($gen)*> core::ops::DerefMut for $dst_type { - fn deref_mut(&mut self) -> &mut $src_type { - unsafe { core::mem::transmute(self) } - } - } - - }; -} +// pub use crate::collections::*; +// mod config; +// pub use crate::config::*; +// mod commons; +// pub use crate::commons::*; +// mod payload; +// pub use crate::payload::*; +// mod keyexpr; +// pub use crate::keyexpr::*; +// mod info; +// pub use crate::info::*; +// mod get; +// pub use crate::get::*; +// mod queryable; +// pub use crate::queryable::*; +// mod put; +// pub use crate::put::*; +// mod scouting; +// pub use crate::scouting::*; +// mod session; +// pub use crate::session::*; +// mod subscriber; +// pub use crate::subscriber::*; +// // mod pull_subscriber; +// // pub use crate::pull_subscriber::*; +// mod publisher; +// 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::*; +// // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. +// // mod querying_subscriber; +// // pub use querying_subscriber::*; +// pub mod attachment; +// pub use platform::*; +// pub mod opaque_types; +// pub mod platform; +// #[cfg(feature = "shared-memory")] +// mod shm; pub(crate) const LOG_INVALID_SESSION: &str = "Invalid session"; From 34c471b737c4b24101c83831fb236dae6dda0bfb Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 20:05:44 +0200 Subject: [PATCH 041/377] disabled header split, compiles --- build.rs | 4 +-- include/zenoh-gen.h | 60 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 8 +++--- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/build.rs b/build.rs index 89fffff0d..97a90078a 100644 --- a/build.rs +++ b/build.rs @@ -39,8 +39,8 @@ fn main() { configure(); let split_guide = SplitGuide::from_yaml(SPLITGUIDE_PATH); - split_bindings(&split_guide).unwrap(); - text_replace(split_guide.rules.iter().map(|(name, _)| name.as_str())); + // split_bindings(&split_guide).unwrap(); + // text_replace(split_guide.rules.iter().map(|(name, _)| name.as_str())); fs_extra::copy_items( &["include"], diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index 0e648f1e9..ee1325666 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,6 +5,66 @@ #include +typedef struct z_owned_bytes_t { + uint8_t *start; + size_t len; +} z_owned_bytes_t; + +/** + * A contiguous view of bytes owned by some other entity. + * + * `start` being `null` is considered a gravestone value, + * and empty slices are represented using a possibly dangling pointer for `start`. + */ +typedef struct z_bytes_t { + const uint8_t *start; + size_t len; +} z_bytes_t; + +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *b); + +ZENOHC_API struct z_owned_bytes_t z_bytes_clone(const struct z_bytes_t *b); + +/** + * Returns the gravestone value for `z_bytes_t` + */ +ZENOHC_API struct z_bytes_t z_bytes_empty(void); + +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_bytes_empty()` + */ +ZENOHC_API struct z_bytes_t z_bytes_from_str(const char *str); + +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_bytes_is_initialized(const struct z_bytes_t *b); + +ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *b); + +/** + * Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_bytes_empty()` + */ +ZENOHC_API +struct z_bytes_t z_bytes_new(const char *str); + +/** + * Returns the gravestone value for `z_owned_bytes_t` + */ +ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); + +/** + * Constructs a `len` bytes long view starting at `start`. + */ +ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); + /** * Initialises the zenoh runtime logger. * diff --git a/src/lib.rs b/src/lib.rs index cc4b631f8..ddae302f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,9 +14,10 @@ #![allow(non_camel_case_types)] -// mod collections; -// use std::cmp::min; -// use std::slice; +mod collections; +use libc::c_void; +use std::cmp::min; +use std::slice; #[macro_use] mod transmute; @@ -51,7 +52,6 @@ mod transmute; // mod closures; // pub use closures::*; // mod liveliness; -// use libc::c_void; // pub use liveliness::*; // mod publication_cache; // pub use publication_cache::*; From 8a6ef172cb6c3d3fe28e58c443cb234a004b7448 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 14 Apr 2024 13:40:37 +0200 Subject: [PATCH 042/377] session weak remove started --- build-resources/opaque-types/src/lib.rs | 14 + include/zenoh-gen.h | 419 ++++++++++++++++++++++++ src/keyexpr.rs | 166 ++++------ src/lib.rs | 10 +- src/session.rs | 69 +--- src/transmute.rs | 6 +- 6 files changed, 516 insertions(+), 168 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 698646271..df6b91701 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,9 +1,12 @@ +use std::sync::Arc; use zenoh::buffers::{ZBuf, ZBufReader}; use zenoh::encoding::Encoding; +use zenoh::key_expr::KeyExpr; use zenoh::query::Reply; use zenoh::queryable::Query; use zenoh::queryable::Queryable; use zenoh::sample::Sample; +use zenoh::session::Session; use zenoh::value::Value; // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. @@ -56,13 +59,18 @@ get_opaque_type_data!(ZBufReader, "zc_payload_reader"); get_opaque_type_data!(&'static Encoding, "z_encoding_t"); get_opaque_type_data!(Encoding, "z_owned_encoding_t"); + get_opaque_type_data!(Option, "z_owned_reply_t"); + get_opaque_type_data!(Value, "z_owned_value_t"); get_opaque_type_data!(&'static Value, "z_value_t"); + get_opaque_type_data!(Option, "z_owned_query_t"); get_opaque_type_data!(&'static Query, "z_query_t"); + get_opaque_type_data!(Option>, "z_owned_queryable_t"); get_opaque_type_data!(&'static Queryable<'static, ()>, "z_queryable_t"); + // get_opaque_type_data!( // Option>, // "ze_owned_querying_subscriber_t" @@ -71,3 +79,9 @@ get_opaque_type_data!(&'static Queryable<'static, ()>, "z_queryable_t"); // &'static FetchingSubscriberWrapper, // "ze_querying_subscriber_t" // ); + +get_opaque_type_data!(Option>, "z_owned_keyexpr_t"); +get_opaque_type_data!(&'static KeyExpr<'_>, "z_keyexpr_t"); + +get_opaque_type_data!(Option>, "z_owned_session_t"); +get_opaque_type_data!(&'static Session, "z_session_t"); diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index ee1325666..7ebf978cb 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,6 +5,21 @@ #include +/** + * A :c:type:`z_keyexpr_intersection_level_t`. + * + * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** + */ +typedef enum z_keyexpr_intersection_level_t { + Z_KEYEXPR_INTERSECTION_LEVEL_T_DISJOINT = 0, + Z_KEYEXPR_INTERSECTION_LEVEL_T_INTERSECTS = 1, + Z_KEYEXPR_INTERSECTION_LEVEL_T_INCLUDES = 2, + Z_KEYEXPR_INTERSECTION_LEVEL_T_EQUALS = 3, +} z_keyexpr_intersection_level_t; + typedef struct z_owned_bytes_t { uint8_t *start; size_t len; @@ -21,6 +36,73 @@ typedef struct z_bytes_t { size_t len; } z_bytes_t; +typedef struct ALIGN(8) z_owned_session_t { + uint8_t _0[8]; +} z_owned_session_t; + +/** + * An owned zenoh configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct z_owned_config_t { + void *_0; +} z_owned_config_t; + +/** + * A loaned zenoh configuration. + */ +typedef struct z_config_t { + const struct z_owned_config_t *_0; +} z_config_t; + +typedef struct ALIGN(8) z_owned_keyexpr_t { + uint8_t _0[32]; +} z_owned_keyexpr_t; + +typedef struct ALIGN(8) z_session_t { + uint8_t _0[8]; +} z_session_t; + +typedef struct ALIGN(8) z_keyexpr_t { + uint8_t _0[8]; +} z_keyexpr_t; + +extern const unsigned int Z_ROUTER; + +extern const unsigned int Z_PEER; + +extern const unsigned int Z_CLIENT; + +extern const char *Z_CONFIG_MODE_KEY; + +extern const char *Z_CONFIG_CONNECT_KEY; + +extern const char *Z_CONFIG_LISTEN_KEY; + +extern const char *Z_CONFIG_USER_KEY; + +extern const char *Z_CONFIG_PASSWORD_KEY; + +extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; + +extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; + +extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; + +extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; + +extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; + +extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; + /** * Returns ``true`` if `b` is initialized. */ @@ -65,6 +147,308 @@ ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); */ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); +/** + * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * + * Returns a negative value if an error occured while closing the session. + * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + */ +ZENOHC_API int8_t z_close(struct z_owned_session_t *session); + +/** + * Returns ``true`` if `config` is valid. + */ +ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); + +/** + * Constructs a default, zenoh-allocated, client mode configuration. + * If `peer` is not null, it is added to the configuration as remote peer. + */ +ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); + +/** + * Creates a default, zenoh-allocated, configuration. + */ +ZENOHC_API struct z_owned_config_t z_config_default(void); + +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); + +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); + +/** + * Return a new, zenoh-allocated, empty configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +struct z_owned_config_t z_config_new(void); + +/** + * Constructs a null safe-to-drop value of 'z_owned_config_t' type + */ +ZENOHC_API struct z_owned_config_t z_config_null(void); + +/** + * Constructs a default, zenoh-allocated, peer mode configuration. + */ +ZENOHC_API struct z_owned_config_t z_config_peer(void); + +/** + * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. + * + * This numerical id will be used on the network to save bandwidth and + * ease the retrieval of the concerned resource in the routing tables. + */ +ZENOHC_API +int8_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, + struct z_session_t session, + 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`. + */ +ZENOHC_API struct z_keyexpr_t z_keyexpr(const char *name); + +/** + * Returns the key expression's internal string by aliasing it. + * + * 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`. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +int8_t z_keyexpr_canonize(char *start, + size_t *len); + +/** + * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +int8_t z_keyexpr_canonize_null_terminated(char *start); + +/** + * Returns ``true`` if `keyexpr` is valid. + */ +ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); + +/** + * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + * + * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. + * + * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, + * as this would extremely likely cause bugs. + */ +ZENOHC_API +struct z_owned_keyexpr_t z_keyexpr_concat(struct z_keyexpr_t left, + const char *right_start, + size_t right_len); + +/** + * Frees `keyexpr` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); + +/** + * Returns ``0`` if both ``left`` and ``right`` are equal. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. + */ +ZENOHC_API +int8_t z_keyexpr_equals(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set + * defined by ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. + */ +ZENOHC_API +int8_t z_keyexpr_includes(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the + * sets defined by ``left`` and ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. + */ +ZENOHC_API +int8_t z_keyexpr_intersects(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if the passed string is a valid (and canon) key expression. + * Otherwise returns error value + */ +ZENOHC_API int8_t z_keyexpr_is_canon(const char *start, size_t len); + +/** + * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + */ +ZENOHC_API +struct z_owned_keyexpr_t z_keyexpr_join(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + */ +ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *keyexpr); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. + */ +ZENOHC_API int8_t z_keyexpr_new(struct z_owned_keyexpr_t *this_, 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 +int8_t z_keyexpr_new_autocanonize(struct z_owned_keyexpr_t *this_, + const char *name); + +/** + * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type + */ +ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); + +/** + * Returns the relation between `left` and `right` from `left`'s point of view. + * + * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. + */ +ZENOHC_API +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. + * The user is responsible of droping the returned string using `z_drop` + */ +ZENOHC_API z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t keyexpr); + +/** + * 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: + * + * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. + * - any instance of `**` may only be lead or followed by `/`. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +struct z_keyexpr_t z_keyexpr_unchecked(const char *name); + +/** + * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + */ +ZENOHC_API +struct z_owned_session_t z_open(struct z_owned_config_t *config); + +/** + * Returns ``true`` if `session` is valid. + */ +ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); + +/** + * Returns a :c:type:`z_session_t` loaned from `s`. + * + * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. + * + * # Safety + * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, + * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) + * have been destroyed is UB (likely SEGFAULT) + */ +ZENOHC_API +struct z_session_t z_session_loan(const struct z_owned_session_t *s); + +/** + * Constructs a null safe-to-drop value of 'z_owned_session_t' type + */ +ZENOHC_API void z_session_null(struct z_owned_session_t *s); + +/** + * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. + */ +ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); + +/** + * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. + */ +ZENOHC_API +struct z_owned_config_t zc_config_from_file(const char *path); + +/** + * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. + * + * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). + */ +ZENOHC_API +struct z_owned_config_t zc_config_from_str(const char *s); + +/** + * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. + * Use `z_drop` to safely deallocate this string + */ +ZENOHC_API +z_owned_str_t zc_config_get(struct z_config_t config, + const char *key); + +/** + * Inserts a JSON-serialized `value` at the `key` position of the configuration. + * + * Returns 0 if successful, a negative value otherwise. + */ +ZENOHC_API +int8_t zc_config_insert_json(struct z_config_t config, + const char *key, + const char *value); + +/** + * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. + */ +ZENOHC_API +z_owned_str_t zc_config_to_string(struct z_config_t config); + /** * Initialises the zenoh runtime logger. * @@ -72,3 +456,38 @@ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); * this will be performed automatically by `z_open` and `z_scout`. */ ZENOHC_API void zc_init_logger(void); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * 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. + * - `name` MUST follow the Key Expression specification, ie: + * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. + * - any instance of ``**`` may only be lead or followed by ``/``. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +struct z_keyexpr_t zc_keyexpr_from_slice_unchecked(const char *start, + size_t len); + +/** + * Increments the session's reference count, returning a new owning handle. + */ +ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session); diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 6b7adeacf..a97691ad7 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -13,17 +13,20 @@ // use std::convert::TryFrom; +use std::mem::MaybeUninit; use std::ops::Deref; use std::ops::DerefMut; -use crate::impl_guarded_transmute; -use crate::session::*; +use crate::transmute::unwrap_ref_unchecked; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteRef; use crate::z_bytes_t; use crate::z_owned_str_t; use crate::z_str_null; -use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use libc::c_char; +use zenoh::core::ErrNo; use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; @@ -53,52 +56,45 @@ use zenoh::prelude::KeyExpr; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_keyexpr_t([u64; 4]); -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_keyexpr_t([u32; 5]); - -impl_guarded_transmute!(Option>, z_owned_keyexpr_t); - -impl From> for z_owned_keyexpr_t { - fn from(val: KeyExpr<'static>) -> Self { - Some(val).into() - } -} -impl z_owned_keyexpr_t { - pub fn null() -> Self { - None::.into() - } -} +pub use crate::opaque_types::z_owned_keyexpr_t; +decl_transmute_owned!(default_inplace_init Option>, z_owned_keyexpr_t); /// Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_keyexpr_null() -> z_owned_keyexpr_t { - z_owned_keyexpr_t::null() +pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { + Inplace::empty(z_owned_keyexpr_t::transmute_uninit_ptr(this)); } /// Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_new(name: *const c_char) -> z_owned_keyexpr_t { +pub unsafe extern "C" fn z_keyexpr_new( + this: *mut MaybeUninit, + name: *const c_char, +) -> i8 { + let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); if name.is_null() { - return z_owned_keyexpr_t::null(); + Inplace::empty(this); + return -1; } let name = std::slice::from_raw_parts(name as _, libc::strlen(name)); match std::str::from_utf8(name) { Ok(name) => match KeyExpr::try_from(name) { - Ok(v) => v.into_owned().into(), + Ok(v) => { + Inplace::init(this, Some(v)); + 0 + } Err(e) => { log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + -1 } }, Err(e) => { log::error!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + -1 } } } @@ -106,25 +102,35 @@ 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 { +pub unsafe extern "C" fn z_keyexpr_new_autocanonize( + this: *mut MaybeUninit, + name: *const c_char, +) -> i8 { + let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); if name.is_null() { - return z_owned_keyexpr_t::null(); + Inplace::empty(this); + return -1; } 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(), + Ok(v) => { + Inplace::init(this, Some(v)); + 0 + } Err(e) => { log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + -1 } } } Err(e) => { log::error!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + -1 } } } @@ -132,21 +138,21 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize(name: *const c_char) -> z_ow /// 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 { - keyexpr.as_ref().map(|k| k.borrowing_clone()).into() + unwrap_ref_unchecked(keyexpr.transmute_ref()).transmute_copy() } /// Frees `keyexpr` and invalidates it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_drop(keyexpr: &mut z_owned_keyexpr_t) { - std::mem::drop(keyexpr.take()) + Inplace::drop(keyexpr.transmute_mut()); } /// Returns ``true`` if `keyexpr` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { - keyexpr.deref().is_some() + keyexpr.transmute_ref().is_some() } /// A loaned key expression. @@ -159,49 +165,9 @@ pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { /// /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_keyexpr_t([u64; 4]); -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_keyexpr_t([u32; 5]); - -impl_guarded_transmute!(noderefs Option>, z_keyexpr_t); -impl_guarded_transmute!(noderefs z_keyexpr_t, z_owned_keyexpr_t); - -impl<'a> From> for z_keyexpr_t { - fn from(val: KeyExpr<'a>) -> Self { - Some(val).into() - } -} - -impl From for z_owned_keyexpr_t { - fn from(oke: z_keyexpr_t) -> Self { - oke.transmute() - } -} +pub use crate::opaque_types::z_keyexpr_t; +decl_transmute_copy!(&'static KeyExpr<'static>, z_keyexpr_t); -impl<'a> From>> for z_keyexpr_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} -impl Deref for z_keyexpr_t { - type Target = Option>; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl DerefMut for z_keyexpr_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl z_keyexpr_t { - pub fn null() -> Self { - None.into() - } -} #[derive(Debug, Clone, Copy)] pub struct UninitializedKeyExprError; impl std::fmt::Display for UninitializedKeyExprError { @@ -210,24 +176,6 @@ impl std::fmt::Display for UninitializedKeyExprError { } } impl std::error::Error for UninitializedKeyExprError {} -impl<'a> TryFrom for KeyExpr<'a> { - type Error = UninitializedKeyExprError; - fn try_from(value: z_keyexpr_t) -> Result { - match value.as_ref() { - Some(ke) => { - Ok(unsafe { std::mem::transmute::>(ke.borrowing_clone()) }) - } - None => Err(UninitializedKeyExprError), - } - } -} - -/// Returns ``true`` if `keyexpr` is initialized. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_keyexpr_is_initialized(keyexpr: &z_keyexpr_t) -> bool { - keyexpr.deref().is_some() -} /// Returns ``0`` if the passed string is a valid (and canon) key expression. /// Otherwise returns error value @@ -448,27 +396,29 @@ impl<'a> From<&'a KeyExpr<'a>> for z_keyexpr_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_declare_keyexpr( + this: *mut MaybeUninit, session: z_session_t, keyexpr: z_keyexpr_t, -) -> z_owned_keyexpr_t { - let key_expr = match keyexpr.as_ref() { - Some(ke) => ke, - None => { - log::warn!("{}", UninitializedKeyExprError); - return z_owned_keyexpr_t::null(); - } - }; +) -> i8 { + let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); + let key_expr = keyexpr.transmute_copy(); + let session = session.transmute_ref(); match session.upgrade() { Some(s) => match s.declare_keyexpr(key_expr).res_sync() { - Ok(id) => id.into_owned().into(), + Ok(id) => { + id.into_owned().into(); + // TODO: store id to keyexpr + } Err(e) => { log::debug!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + i8::MIN } }, None => { log::debug!("{}", LOG_INVALID_SESSION); - z_owned_keyexpr_t::null() + Inplace::empty(this); + i8::MIN } } } diff --git a/src/lib.rs b/src/lib.rs index ddae302f6..705c08b6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,15 +21,16 @@ use std::slice; #[macro_use] mod transmute; +mod opaque_types; -// pub use crate::collections::*; -// mod config; +pub use crate::collections::*; +mod config; // pub use crate::config::*; // mod commons; // pub use crate::commons::*; // mod payload; // pub use crate::payload::*; -// mod keyexpr; +mod keyexpr; // pub use crate::keyexpr::*; // mod info; // pub use crate::info::*; @@ -41,7 +42,7 @@ mod transmute; // pub use crate::put::*; // mod scouting; // pub use crate::scouting::*; -// mod session; +mod session; // pub use crate::session::*; // mod subscriber; // pub use crate::subscriber::*; @@ -60,7 +61,6 @@ mod transmute; // // pub use querying_subscriber::*; // pub mod attachment; // pub use platform::*; -// pub mod opaque_types; // pub mod platform; // #[cfg(feature = "shared-memory")] // mod shm; diff --git a/src/session.rs b/src/session.rs index f710e1703..b369530cf 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,7 +12,10 @@ // ZettaScale Zenoh team, // +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; use crate::{config::*, impl_guarded_transmute, zc_init_logger}; +use std::mem::MaybeUninit; +use std::ops::Deref; use std::sync::{Arc, Weak}; use zenoh::prelude::sync::SyncResolve; use zenoh::session::Session; @@ -20,51 +23,20 @@ use zenoh_util::core::zresult::ErrNo; /// An owned zenoh session. /// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. /// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C)] -pub struct z_owned_session_t(usize); - -impl_guarded_transmute!(Option>, z_owned_session_t); - -impl AsRef>> for z_session_t { - fn as_ref(&self) -> &Option> { - unsafe { std::mem::transmute(self) } - } -} - -impl z_session_t { - pub fn upgrade(&self) -> Option> { - self.as_ref().as_ref().and_then(Weak::upgrade) - } -} - -impl From>> for z_session_t { - fn from(val: Option>) -> Self { - unsafe { std::mem::transmute(val) } - } -} - -impl z_owned_session_t { - pub fn new(session: Arc) -> Self { - Some(session).into() - } - pub fn null() -> Self { - None::>.into() - } -} +use crate::opaque_types::z_owned_session_t; +decl_transmute_owned!(Option>, z_owned_session_t); /// A loaned zenoh session. -#[allow(non_camel_case_types)] -#[derive(Clone, Copy)] -#[repr(C)] -pub struct z_session_t(usize); +use crate::opaque_types::z_session_t; +decl_transmute_copy!(&'static Session, z_session_t); /// Returns a :c:type:`z_session_t` loaned from `s`. /// @@ -76,22 +48,17 @@ pub struct z_session_t(usize); /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] pub extern "C" fn z_session_loan(s: &z_owned_session_t) -> z_session_t { - match s.as_ref() { - Some(s) => { - let mut weak = Arc::downgrade(s); - unsafe { std::ptr::drop_in_place(&mut weak) }; - Some(weak) - } - None => None, - } - .into() + let s = s.transmute_ref(); + let s = unwrap_ref_unchecked(s); + let s = s.as_ref(); + s.transmute_copy() } /// Constructs a null safe-to-drop value of 'z_owned_session_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_session_null() -> z_owned_session_t { - z_owned_session_t::null() +pub extern "C" fn z_session_null(s: *mut MaybeUninit) { + Inplace::empty(z_owned_session_t::transmute_uninit_ptr(s)); } /// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. diff --git a/src/transmute.rs b/src/transmute.rs index 70ec1d863..ddc38824a 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -31,7 +31,7 @@ pub(crate) trait TransmuteRef: Sized { } } -pub(crate) trait TransmuteCopy: TransmuteRef { +pub(crate) trait TransmuteCopy { fn transmute_copy(self) -> T; } @@ -101,7 +101,7 @@ macro_rules! validate_equivalence { #[macro_export] macro_rules! decl_transmute_owned { - (default_inplace_init $zenoh_type:ty, $c_type:ty) => { + ($zenoh_type:ty, $c_type:ty) => { impl $crate::transmute::InplaceDefault for $zenoh_type {} decl_transmute_owned!(custom_inplace_init $zenoh_type, $c_type); @@ -117,8 +117,6 @@ macro_rules! decl_transmute_owned { macro_rules! decl_transmute_copy { ($zenoh_type:ty, $c_type:ty) => { validate_equivalence!($zenoh_type, $c_type); - impl_transmute_ref!($zenoh_type, $c_type); - impl_transmute_ref!($c_type, $zenoh_type); impl_transmute_copy!($zenoh_type, $c_type); impl_transmute_copy!($c_type, $zenoh_type); }; From ae9d39b26ed3f114ea03f271adcadced72b2a786 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 14 Apr 2024 14:55:38 +0200 Subject: [PATCH 043/377] session updated --- build-resources/opaque-types/src/lib.rs | 4 + include/zenoh-gen.h | 376 +----------------------- src/lib.rs | 7 +- src/session.rs | 38 ++- 4 files changed, 43 insertions(+), 382 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index df6b91701..bdbc6eeb9 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,5 +1,6 @@ use std::sync::Arc; use zenoh::buffers::{ZBuf, ZBufReader}; +use zenoh::config::Config; use zenoh::encoding::Encoding; use zenoh::key_expr::KeyExpr; use zenoh::query::Reply; @@ -85,3 +86,6 @@ get_opaque_type_data!(&'static KeyExpr<'_>, "z_keyexpr_t"); get_opaque_type_data!(Option>, "z_owned_session_t"); get_opaque_type_data!(&'static Session, "z_session_t"); + +get_opaque_type_data!(Option>, "z_owned_config_t"); +get_opaque_type_data!(&'static Config, "z_config_t"); diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index 7ebf978cb..fdaac4c70 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,21 +5,6 @@ #include -/** - * A :c:type:`z_keyexpr_intersection_level_t`. - * - * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** - */ -typedef enum z_keyexpr_intersection_level_t { - Z_KEYEXPR_INTERSECTION_LEVEL_T_DISJOINT = 0, - Z_KEYEXPR_INTERSECTION_LEVEL_T_INTERSECTS = 1, - Z_KEYEXPR_INTERSECTION_LEVEL_T_INCLUDES = 2, - Z_KEYEXPR_INTERSECTION_LEVEL_T_EQUALS = 3, -} z_keyexpr_intersection_level_t; - typedef struct z_owned_bytes_t { uint8_t *start; size_t len; @@ -40,69 +25,14 @@ typedef struct ALIGN(8) z_owned_session_t { uint8_t _0[8]; } z_owned_session_t; -/** - * An owned zenoh configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_config_t { - void *_0; +typedef struct ALIGN(8) z_owned_config_t { + uint8_t _0[8]; } z_owned_config_t; -/** - * A loaned zenoh configuration. - */ -typedef struct z_config_t { - const struct z_owned_config_t *_0; -} z_config_t; - -typedef struct ALIGN(8) z_owned_keyexpr_t { - uint8_t _0[32]; -} z_owned_keyexpr_t; - typedef struct ALIGN(8) z_session_t { uint8_t _0[8]; } z_session_t; -typedef struct ALIGN(8) z_keyexpr_t { - uint8_t _0[8]; -} z_keyexpr_t; - -extern const unsigned int Z_ROUTER; - -extern const unsigned int Z_PEER; - -extern const unsigned int Z_CLIENT; - -extern const char *Z_CONFIG_MODE_KEY; - -extern const char *Z_CONFIG_CONNECT_KEY; - -extern const char *Z_CONFIG_LISTEN_KEY; - -extern const char *Z_CONFIG_USER_KEY; - -extern const char *Z_CONFIG_PASSWORD_KEY; - -extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; - -extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; - -extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; - -extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; - -extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; - -extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; - /** * Returns ``true`` if `b` is initialized. */ @@ -155,233 +85,12 @@ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); */ ZENOHC_API int8_t z_close(struct z_owned_session_t *session); -/** - * Returns ``true`` if `config` is valid. - */ -ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); - -/** - * Constructs a default, zenoh-allocated, client mode configuration. - * If `peer` is not null, it is added to the configuration as remote peer. - */ -ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); - -/** - * Creates a default, zenoh-allocated, configuration. - */ -ZENOHC_API struct z_owned_config_t z_config_default(void); - -/** - * Frees `config`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); - -/** - * Returns a :c:type:`z_config_t` loaned from `s`. - */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); - -/** - * Return a new, zenoh-allocated, empty configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -struct z_owned_config_t z_config_new(void); - -/** - * Constructs a null safe-to-drop value of 'z_owned_config_t' type - */ -ZENOHC_API struct z_owned_config_t z_config_null(void); - -/** - * Constructs a default, zenoh-allocated, peer mode configuration. - */ -ZENOHC_API struct z_owned_config_t z_config_peer(void); - -/** - * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. - * - * This numerical id will be used on the network to save bandwidth and - * ease the retrieval of the concerned resource in the routing tables. - */ -ZENOHC_API -int8_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - struct z_session_t session, - 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`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr(const char *name); - -/** - * Returns the key expression's internal string by aliasing it. - * - * 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`. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -int8_t z_keyexpr_canonize(char *start, - size_t *len); - -/** - * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -int8_t z_keyexpr_canonize_null_terminated(char *start); - -/** - * Returns ``true`` if `keyexpr` is valid. - */ -ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); - -/** - * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - * - * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. - * - * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, - * as this would extremely likely cause bugs. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_keyexpr_concat(struct z_keyexpr_t left, - const char *right_start, - size_t right_len); - -/** - * Frees `keyexpr` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); - -/** - * Returns ``0`` if both ``left`` and ``right`` are equal. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_equals(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set - * defined by ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_includes(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the - * sets defined by ``left`` and ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_intersects(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if the passed string is a valid (and canon) key expression. - * Otherwise returns error value - */ -ZENOHC_API int8_t z_keyexpr_is_canon(const char *start, size_t len); - -/** - * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *keyexpr); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. - */ -ZENOHC_API int8_t z_keyexpr_new(struct z_owned_keyexpr_t *this_, 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 -int8_t z_keyexpr_new_autocanonize(struct z_owned_keyexpr_t *this_, - const char *name); - -/** - * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type - */ -ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); - -/** - * Returns the relation between `left` and `right` from `left`'s point of view. - * - * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. - */ -ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. - * The user is responsible of droping the returned string using `z_drop` - */ -ZENOHC_API z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t keyexpr); - -/** - * 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: - * - * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. - * - any instance of `**` may only be lead or followed by `/`. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -struct z_keyexpr_t z_keyexpr_unchecked(const char *name); - /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. */ ZENOHC_API -struct z_owned_session_t z_open(struct z_owned_config_t *config); +int8_t z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); /** * Returns ``true`` if `session` is valid. @@ -406,49 +115,6 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); */ ZENOHC_API void z_session_null(struct z_owned_session_t *s); -/** - * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. - */ -ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); - -/** - * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. - */ -ZENOHC_API -struct z_owned_config_t zc_config_from_file(const char *path); - -/** - * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. - * - * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). - */ -ZENOHC_API -struct z_owned_config_t zc_config_from_str(const char *s); - -/** - * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. - * Use `z_drop` to safely deallocate this string - */ -ZENOHC_API -z_owned_str_t zc_config_get(struct z_config_t config, - const char *key); - -/** - * Inserts a JSON-serialized `value` at the `key` position of the configuration. - * - * Returns 0 if successful, a negative value otherwise. - */ -ZENOHC_API -int8_t zc_config_insert_json(struct z_config_t config, - const char *key, - const char *value); - -/** - * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. - */ -ZENOHC_API -z_owned_str_t zc_config_to_string(struct z_config_t config); - /** * Initialises the zenoh runtime logger. * @@ -457,37 +123,9 @@ z_owned_str_t zc_config_to_string(struct z_config_t config); */ ZENOHC_API void zc_init_logger(void); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * 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. - * - `name` MUST follow the Key Expression specification, ie: - * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. - * - any instance of ``**`` may only be lead or followed by ``/``. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -struct z_keyexpr_t zc_keyexpr_from_slice_unchecked(const char *start, - size_t len); - /** * Increments the session's reference count, returning a new owning handle. */ -ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session); +ZENOHC_API +int8_t zc_session_rcinc(struct z_owned_session_t *dst, + const struct z_owned_session_t *src); diff --git a/src/lib.rs b/src/lib.rs index 705c08b6e..df56e8ead 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,16 +21,17 @@ use std::slice; #[macro_use] mod transmute; -mod opaque_types; +pub mod opaque_types; +pub use crate::opaque_types::*; pub use crate::collections::*; -mod config; +// mod config; // pub use crate::config::*; // mod commons; // pub use crate::commons::*; // mod payload; // pub use crate::payload::*; -mod keyexpr; +// mod keyexpr; // pub use crate::keyexpr::*; // mod info; // pub use crate::info::*; diff --git a/src/session.rs b/src/session.rs index b369530cf..7f758d330 100644 --- a/src/session.rs +++ b/src/session.rs @@ -13,13 +13,13 @@ // use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; -use crate::{config::*, impl_guarded_transmute, zc_init_logger}; +use crate::{config::*, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; use std::ops::Deref; use std::sync::{Arc, Weak}; +use zenoh::core::ErrNo; use zenoh::prelude::sync::SyncResolve; use zenoh::session::Session; -use zenoh_util::core::zresult::ErrNo; /// An owned zenoh session. /// @@ -64,23 +64,31 @@ pub extern "C" fn z_session_null(s: *mut MaybeUninit) { /// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_open(config: &mut z_owned_config_t) -> z_owned_session_t { +pub extern "C" fn z_open( + this: *mut MaybeUninit, + config: &mut z_owned_config_t, +) -> i8 { + let this = z_owned_session_t::transmute_uninit_ptr(this); if cfg!(feature = "logger-autoinit") { zc_init_logger(); } - let config = match config.as_mut().take() { Some(c) => c, None => { log::error!("Config not provided"); - return z_owned_session_t::null(); + Inplace::empty(this); + return -1; } }; match zenoh::open(*config).res() { - Ok(s) => z_owned_session_t::new(Arc::new(s)), + Ok(s) => { + Inplace::init(this, Some(Arc::new(s))); + 0 + } Err(e) => { log::error!("Error opening session: {}", e); - z_owned_session_t::null() + Inplace::empty(this); + -1 } } } @@ -89,7 +97,7 @@ pub extern "C" fn z_open(config: &mut z_owned_config_t) -> z_owned_session_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_session_check(session: &z_owned_session_t) -> bool { - session.as_ref().is_some() + session.transmute_ref().is_some() } /// Closes a zenoh session. This drops and invalidates `session` for double-drop safety. @@ -99,6 +107,7 @@ pub extern "C" fn z_session_check(session: &z_owned_session_t) -> bool { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { + let session = session.transmute_mut(); let Some(s) = session.take() else { return 0; }; @@ -117,6 +126,15 @@ pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { /// Increments the session's reference count, returning a new owning handle. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_session_rcinc(session: z_session_t) -> z_owned_session_t { - session.as_ref().as_ref().and_then(|s| s.upgrade()).into() +pub extern "C" fn zc_session_rcinc( + dst: *mut MaybeUninit, + src: &z_owned_session_t, +) -> i8 { + // session.as_ref().as_ref().and_then(|s| s.upgrade()).into() + let dst = z_owned_session_t::transmute_uninit_ptr(dst); + let Some(src) = src.transmute_ref() else { + return -1; + }; + Inplace::init(dst, Some(src.clone())); + 0 } From 3e541d9017ac7e4e8730e77a38b36a5a9931c19a Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 14 Apr 2024 22:05:26 +0200 Subject: [PATCH 044/377] payload compiles --- build-resources/opaque-types/src/lib.rs | 4 +- include/zenoh-gen.h | 356 +++++++++++++++++++++--- src/commons.rs | 1 - src/config.rs | 52 ++-- src/lib.rs | 12 +- src/payload.rs | 176 +++++------- src/transmute.rs | 18 ++ 7 files changed, 436 insertions(+), 183 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index bdbc6eeb9..66a5fc44e 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -46,6 +46,7 @@ macro_rules! get_opaque_type_data { /// /// To minimize copies and reallocations, Zenoh may provide you data in split buffers. get_opaque_type_data!(Option, "z_owned_buffer_t"); +get_opaque_type_data!(&'static ZBuf, "z_buffer_t"); /// An owned sample. /// @@ -56,7 +57,8 @@ get_opaque_type_data!(Option, "zc_owned_sample_t"); get_opaque_type_data!(&'static Sample, "z_sample_t"); /// A reader for payload data. -get_opaque_type_data!(ZBufReader, "zc_payload_reader"); +get_opaque_type_data!(Option>, "zc_owned_payload_reader"); +get_opaque_type_data!(&'static ZBufReader, "zc_payload_reader"); get_opaque_type_data!(&'static Encoding, "z_encoding_t"); get_opaque_type_data!(Encoding, "z_owned_encoding_t"); diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index fdaac4c70..41fca39e9 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,10 +5,34 @@ #include -typedef struct z_owned_bytes_t { - uint8_t *start; - size_t len; -} z_owned_bytes_t; +typedef enum z_sample_kind_t { + Z_SAMPLE_KIND_T_PUT = 0, + Z_SAMPLE_KIND_T_DELETE = 1, +} z_sample_kind_t; + +typedef enum zcu_locality_t { + ZCU_LOCALITY_T_ANY = 0, + ZCU_LOCALITY_T_SESSION_LOCAL = 1, + ZCU_LOCALITY_T_REMOTE = 2, +} zcu_locality_t; + +typedef enum zcu_reply_keyexpr_t { + ZCU_REPLY_KEYEXPR_T_ANY = 0, + ZCU_REPLY_KEYEXPR_T_MATCHING_QUERY = 1, +} zcu_reply_keyexpr_t; + +/** + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + */ +typedef struct ALIGN(8) z_owned_buffer_t { + uint8_t _0[40]; +} z_owned_buffer_t; + +typedef struct ALIGN(8) z_buffer_t { + uint8_t _0[8]; +} z_buffer_t; /** * A contiguous view of bytes owned by some other entity. @@ -21,17 +45,116 @@ typedef struct z_bytes_t { size_t len; } z_bytes_t; -typedef struct ALIGN(8) z_owned_session_t { +typedef struct z_owned_bytes_t { + uint8_t *start; + size_t len; +} z_owned_bytes_t; + +typedef struct ALIGN(8) z_owned_encoding_t { + uint8_t _0[48]; +} z_owned_encoding_t; + +typedef struct ALIGN(8) z_encoding_t { uint8_t _0[8]; -} z_owned_session_t; +} z_encoding_t; -typedef struct ALIGN(8) z_owned_config_t { +typedef struct ALIGN(8) z_sample_t { uint8_t _0[8]; -} z_owned_config_t; +} z_sample_t; + +typedef struct ALIGN(8) z_keyexpr_t { + uint8_t _0[8]; +} z_keyexpr_t; + +/** + * An owned payload, backed by a reference counted owner. + * + * The `payload` field may be modified, and Zenoh will take the new values into account. + */ +typedef struct z_owned_buffer_t zc_owned_payload_t; + +typedef struct z_buffer_t zc_payload_t; + +typedef struct z_timestamp_t { + uint64_t time; + z_id_t id; +} z_timestamp_t; + +/** + * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` + * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with + * `z_check` and `z_str_check` correspondently + */ +typedef struct z_owned_str_t { + char *_cstr; +} z_owned_str_t; + +/** + * A reader for payload data. + */ +typedef struct ALIGN(8) zc_owned_payload_reader { + uint8_t _0[24]; +} zc_owned_payload_reader; -typedef struct ALIGN(8) z_session_t { +typedef struct ALIGN(8) zc_payload_reader { uint8_t _0[8]; -} z_session_t; +} zc_payload_reader; + +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[240]; +} zc_owned_sample_t; + +/** + * Returns `true` if the buffer is in a valid state. + */ +ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); + +/** + * Increments the buffer's reference count, returning an owned version of the buffer. + */ +ZENOHC_API void z_buffer_clone(struct z_owned_buffer_t *dst, const struct z_owned_buffer_t *buffer); + +/** + * Decrements the buffer's reference counter, destroying it if applicable. + * + * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ +ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); + +/** + * Returns total number bytes in the buffer. + */ +ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); + +/** + * Loans the buffer, allowing you to call functions that only need a loan of it. + */ +ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); + +/** + * The gravestone value for `z_owned_buffer_t`. + */ +ZENOHC_API void z_buffer_null(struct z_owned_buffer_t *this_); + +/** + * Returns the `index`th slice of the buffer, aliasing it. + * + * Out of bounds accesses will return `z_bytes_empty`. + */ +ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); + +/** + * Returns the number of slices in the buffer. + * + * If the return value is 0 or 1, then the buffer's data is contiguous in memory. + */ +ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. @@ -78,42 +201,105 @@ ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); /** - * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * Returns ``true`` if `encoding` is valid. + */ +ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); + +/** + * Constructs a default :c:type:`z_encoding_t`. + */ +ZENOHC_API struct z_encoding_t z_encoding_default(void); + +/** + * Frees `encoding`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); + +/** + * Constructs a specific :c:type:`z_encoding_t`. + */ +ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); + +/** + * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + */ +ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); + +/** + * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type + */ +ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); + +/** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) + * The sample's attachment. * - * Returns a negative value if an error occured while closing the session. - * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + * `sample` is aliased by the return value. */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); +ZENOHC_API z_attachment_t z_sample_attachment(const struct z_sample_t *sample); /** - * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + * The encoding of the payload. */ -ZENOHC_API -int8_t z_open(struct z_owned_session_t *this_, - struct z_owned_config_t *config); +ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); /** - * Returns ``true`` if `session` is valid. + * The Key Expression of the sample. + * + * `sample` is aliased by its return value. */ -ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); +ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); /** - * Returns a :c:type:`z_session_t` loaned from `s`. + * The sample's kind (put or delete). + */ +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); + +/** + * Returns the sample's payload after incrementing its internal reference count. * - * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. + * Note that other samples may have received the same buffer, meaning that mutating this buffer may + * affect the samples received by other subscribers. + */ +ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sample); + +/** + * The sample's data, the return value aliases the sample. * - * # Safety - * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, - * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) - * have been destroyed is UB (likely SEGFAULT) + * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ -ZENOHC_API -struct z_session_t z_session_loan(const struct z_owned_session_t *s); +ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); /** - * Constructs a null safe-to-drop value of 'z_owned_session_t' type + * The samples timestamp */ -ZENOHC_API void z_session_null(struct z_owned_session_t *s); +ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); + +/** + * Returns ``true`` if `s` is a valid string + */ +ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); + +/** + * Frees `z_owned_str_t`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_str_drop(struct z_owned_str_t *s); + +/** + * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. + */ +ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); + +/** + * Returns undefined `z_owned_str_t` + */ +ZENOHC_API struct z_owned_str_t z_str_null(void); + +/** + * Returns ``true`` if `ts` is a valid timestamp + */ +ZENOHC_API bool z_timestamp_check(struct z_timestamp_t ts); /** * Initialises the zenoh runtime logger. @@ -124,8 +310,112 @@ ZENOHC_API void z_session_null(struct z_owned_session_t *s); ZENOHC_API void zc_init_logger(void); /** - * Increments the session's reference count, returning a new owning handle. + * Returns `false` if `payload` is the gravestone value. + */ +ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); + +/** + * Increments internal payload reference count, returning owned payload. + */ +ZENOHC_API void zc_payload_clone(zc_owned_payload_t *dst, const zc_owned_payload_t *payload); + +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API int8_t zc_payload_decode_into_bytes(zc_payload_t payload, struct z_owned_bytes_t *b); + +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API int8_t zc_payload_decode_into_string(zc_payload_t payload, struct z_owned_str_t *cstr); + +/** + * Decrements `payload`'s backing refcount, releasing the memory if appropriate. + */ +ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); + +/** + * Encodes byte sequence by aliasing. + */ +ZENOHC_API void zc_payload_encode_from_bytes(zc_owned_payload_t *dst, struct z_bytes_t bytes); + +/** + * Encodes a null-terminated string by aliasing. + */ +ZENOHC_API void zc_payload_encode_from_string(zc_owned_payload_t *dst, const char *cstr); + +/** + * Returns total number bytes in the payload. + */ +ZENOHC_API size_t zc_payload_len(zc_payload_t payload); + +/** + * Returns a :c:type:`zc_payload_t` loaned from `payload`. + */ +ZENOHC_API zc_payload_t zc_payload_loan(const zc_owned_payload_t *payload); + +/** + * Constructs `zc_owned_payload_t`'s gravestone value. + */ +ZENOHC_API void zc_payload_null(zc_owned_payload_t *this_); + +/** + * Clones the `payload` by incrementing its reference counter. + */ +ZENOHC_API void zc_payload_rcinc(zc_owned_payload_t *dst, const zc_owned_payload_t *payload); + +/** + * Creates a reader for the specified `payload`. + * + * Returns 0 in case of success, -1 if `payload` is not valid. + */ +ZENOHC_API void zc_payload_reader_init(struct zc_owned_payload_reader *this_, zc_payload_t payload); + +/** + * Reads data into specified destination. + * + * Will read at most `len` bytes. + * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. */ ZENOHC_API -int8_t zc_session_rcinc(struct z_owned_session_t *dst, - const struct z_owned_session_t *src); +size_t zc_payload_reader_read(struct zc_payload_reader reader, + uint8_t *dest, + size_t len); + +/** + * Returns number of the remaining bytes in the payload + * + */ +ZENOHC_API size_t zc_payload_reader_remaining(struct zc_payload_reader reader); + +/** + * Returns `true` if `sample` is valid. + * + * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * unless the value has been dropped already. + */ +ZENOHC_API +bool zc_sample_check(const struct zc_owned_sample_t *sample); + +/** + * Clone a sample in the cheapest way available. + */ +ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); + +/** + * Destroy the sample. + */ +ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); + +/** + * Borrow the sample, allowing calling its accessor methods. + * + * Calling this function using a dropped sample is undefined behaviour. + */ +ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); + +ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); + +ZENOHC_API enum zcu_locality_t zcu_locality_default(void); + +ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); diff --git a/src/commons.rs b/src/commons.rs index 902a2361f..72739ebbd 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -17,7 +17,6 @@ use std::mem::MaybeUninit; use std::ops::Deref; use std::str::FromStr; -use crate::keyexpr::*; use crate::opaque_types::z_owned_buffer_t; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; diff --git a/src/config.rs b/src/config.rs index 80e3a38f1..70f4ba776 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,8 +13,10 @@ // use libc::{c_char, c_uint}; use std::ffi::CStr; +use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null}; #[no_mangle] @@ -58,9 +60,8 @@ pub static Z_CONFIG_ADD_TIMESTAMP_KEY: &c_char = unsafe { &*(b"timestamping/enabled\0".as_ptr() as *const c_char) }; /// A loaned zenoh configuration. -#[repr(C)] -#[allow(non_camel_case_types)] -pub struct z_config_t(*const z_owned_config_t); +pub use crate::opaque_types::z_config_t; +decl_transmute_copy!(&'static Config, z_config_t); /// An owned zenoh configuration. /// @@ -72,39 +73,16 @@ pub struct z_config_t(*const z_owned_config_t); /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C)] -pub struct z_owned_config_t(*mut ()); -impl_guarded_transmute!(Option>, z_owned_config_t); +pub use crate::opaque_types::z_owned_config_t; +decl_transmute_owned!(Option>, z_owned_config_t); /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t { - z_config_t(s) -} -impl AsRef>> for z_config_t { - fn as_ref(&self) -> &Option> { - unsafe { (*self.0).as_ref() } - } -} -impl AsMut>> for z_config_t { - fn as_mut(&mut self) -> &mut Option> { - unsafe { (*(self.0 as *mut z_owned_config_t)).as_mut() } - } -} -impl AsRef>> for z_owned_config_t { - fn as_ref(&self) -> &Option> { - unsafe { std::mem::transmute(self) } - } -} -impl AsMut>> for z_owned_config_t { - fn as_mut(&mut self) -> &mut Option> { - unsafe { std::mem::transmute(self) } - } -} -impl z_owned_config_t { - pub fn null() -> Self { - None.into() - } + let s = s.transmute_ref(); + let s = unwrap_ref_unchecked(s); + let s = s.as_ref(); + s.transmute_copy() } /// Return a new, zenoh-allocated, empty configuration. @@ -118,15 +96,17 @@ impl z_owned_config_t { /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[no_mangle] -pub extern "C" fn z_config_new() -> z_owned_config_t { +pub extern "C" fn z_config_new(this: *mut MaybeUninit) { + let this = z_owned_config_t::transmute_uninit_ptr(this); let config: Box = Box::default(); - unsafe { z_owned_config_t(std::mem::transmute(Some(config))) } + Inplace::init(this, Some(config)); } /// Constructs a null safe-to-drop value of 'z_owned_config_t' type #[no_mangle] -pub extern "C" fn z_config_null() -> z_owned_config_t { - z_owned_config_t::null() +pub extern "C" fn z_config_null(this: *mut MaybeUninit) { + let this = z_owned_config_t::transmute_uninit_ptr(this); + Inplace::empty(this); } /// Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. diff --git a/src/lib.rs b/src/lib.rs index df56e8ead..113d5182d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,6 @@ #![allow(non_camel_case_types)] -mod collections; use libc::c_void; use std::cmp::min; use std::slice; @@ -24,13 +23,14 @@ mod transmute; pub mod opaque_types; pub use crate::opaque_types::*; +mod collections; pub use crate::collections::*; // mod config; // pub use crate::config::*; -// mod commons; -// pub use crate::commons::*; -// mod payload; -// pub use crate::payload::*; +mod commons; +pub use crate::commons::*; +mod payload; +pub use crate::payload::*; // mod keyexpr; // pub use crate::keyexpr::*; // mod info; @@ -43,7 +43,7 @@ pub use crate::collections::*; // pub use crate::put::*; // mod scouting; // pub use crate::scouting::*; -mod session; +// mod session; // pub use crate::session::*; // mod subscriber; // pub use crate::subscriber::*; diff --git a/src/payload.rs b/src/payload.rs index b77b46dd7..6e723e329 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,36 +1,24 @@ +use crate::transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr, +}; +use crate::{z_bytes_empty, z_bytes_t, z_owned_bytes_t, z_owned_str_t}; use core::slice; +use std::any::Any; use std::mem::MaybeUninit; use std::slice::from_raw_parts_mut; -use std::{any::Any, ops::Deref, ptr::NonNull}; - use zenoh::buffers::HasReader; use zenoh::buffers::Reader; use zenoh::buffers::ZBufReader; use zenoh::buffers::{SplitBuffer, ZBuf, ZSliceBuffer}; -use crate::{ - impl_guarded_transmute, z_bytes_empty, z_bytes_null, z_bytes_t, z_owned_bytes_t, z_owned_str_t, - z_str_null, GuardedTransmute, -}; - pub use crate::opaque_types::z_owned_buffer_t; -impl_guarded_transmute!(Option, z_owned_buffer_t); - -impl Default for z_owned_buffer_t { - fn default() -> Self { - z_buffer_null() - } -} -impl From for z_owned_buffer_t { - fn from(value: ZBuf) -> Self { - Some(value).transmute() - } -} +decl_transmute_owned!(Option, z_owned_buffer_t); /// The gravestone value for `z_owned_buffer_t`. #[no_mangle] -extern "C" fn z_buffer_null() -> z_owned_buffer_t { - None::.transmute() +extern "C" fn z_buffer_null(this: *mut MaybeUninit) { + let this = z_owned_buffer_t::transmute_uninit_ptr(this); + Inplace::empty(this); } /// Decrements the buffer's reference counter, destroying it if applicable. @@ -38,52 +26,37 @@ extern "C" fn z_buffer_null() -> z_owned_buffer_t { /// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. #[no_mangle] extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { - core::mem::drop(buffer.take()) + let buffer = buffer.transmute_mut(); + Inplace::drop(buffer); } /// Returns `true` if the buffer is in a valid state. #[no_mangle] extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { - buffer.is_some() + buffer.transmute_ref().is_some() } /// Loans the buffer, allowing you to call functions that only need a loan of it. #[no_mangle] extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { - buffer.as_ref().into() + let buffer = buffer.transmute_ref(); + let buffer = unwrap_ref_unchecked(buffer); + buffer.transmute_copy() } /// A loan of a `z_owned_buffer_t`. /// /// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. -#[repr(C)] -#[derive(Clone, Copy, Default)] -pub struct z_buffer_t { - _inner: Option>, -} - -impl_guarded_transmute!(noderefs Option<&ZBuf>, z_buffer_t); -impl_guarded_transmute!(noderefs z_buffer_t, Option<&'static ZBuf>); - -impl From> for z_buffer_t { - fn from(value: Option<&ZBuf>) -> Self { - value.transmute() - } -} - -impl From for Option<&'static ZBuf> { - fn from(value: z_buffer_t) -> Self { - value.transmute() - } -} +pub use crate::opaque_types::z_buffer_t; +decl_transmute_copy!(&'static ZBuf, z_buffer_t); /// Increments the buffer's reference count, returning an owned version of the buffer. #[no_mangle] -extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { - match buffer._inner { - Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, - None => ZBuf::empty().into(), - } +extern "C" fn z_buffer_clone(dst: *mut MaybeUninit, buffer: &z_owned_buffer_t) { + let dst = dst.transmute_uninit_ptr(); + let buffer = buffer.transmute_ref(); + let buffer = buffer.as_ref().map(Clone::clone); + Inplace::init(dst, buffer); } /// Returns the number of slices in the buffer. @@ -91,19 +64,13 @@ extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { /// If the return value is 0 or 1, then the buffer's data is contiguous in memory. #[no_mangle] extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { - match buffer.into() { - None => 0, - Some(buf) => ZBuf::slices(buf).len(), - } + ZBuf::slices(buffer.transmute_copy()).len() } /// Returns total number bytes in the buffer. #[no_mangle] extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { - match buffer.into() { - None => 0, - Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), - } + ZBuf::slices(buffer.transmute_copy()).fold(0, |acc, s| acc + s.len()) } /// Returns the `index`th slice of the buffer, aliasing it. @@ -111,12 +78,10 @@ extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { /// Out of bounds accesses will return `z_bytes_empty`. #[no_mangle] extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { - match buffer.into() { - None => z_bytes_empty(), - Some(buf) => ZBuf::slices(buf) - .nth(index) - .map_or(z_bytes_empty(), |slice| slice.into()), - } + let buf = buffer.transmute_copy(); + ZBuf::slices(buf) + .nth(index) + .map_or(z_bytes_empty(), |slice| slice.into()) } /// An owned payload, backed by a reference counted owner. @@ -127,8 +92,11 @@ pub type zc_owned_payload_t = z_owned_buffer_t; /// Clones the `payload` by incrementing its reference counter. #[no_mangle] -pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { - z_buffer_clone(z_buffer_loan(payload)) +pub extern "C" fn zc_payload_rcinc( + dst: *mut MaybeUninit, + payload: &zc_owned_payload_t, +) { + z_buffer_clone(dst, payload) } /// Returns `false` if `payload` is the gravestone value. #[no_mangle] @@ -142,8 +110,8 @@ pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { } /// Constructs `zc_owned_payload_t`'s gravestone value. #[no_mangle] -pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { - z_buffer_null() +pub extern "C" fn zc_payload_null(this: *mut MaybeUninit) { + z_buffer_null(this); } /// Returns a :c:type:`zc_payload_t` loaned from `payload`. @@ -157,8 +125,11 @@ pub type zc_payload_t = z_buffer_t; /// Increments internal payload reference count, returning owned payload. #[no_mangle] -pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t { - z_buffer_clone(payload) +pub extern "C" fn zc_payload_clone( + dst: *mut MaybeUninit, + payload: &zc_owned_payload_t, +) { + z_buffer_clone(dst, payload) } /// Decodes payload into null-terminated string @@ -168,14 +139,8 @@ pub unsafe extern "C" fn zc_payload_decode_into_string( payload: zc_payload_t, cstr: &mut z_owned_str_t, ) -> i8 { - let payload: Option<&ZBuf> = payload.into(); - if payload.is_none() { - *cstr = z_str_null(); - return 0; - } - *cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); - let payload = payload.unwrap(); - + *cstr = z_owned_str_t::preallocate(zc_payload_len(payload)); + let payload = payload.transmute_copy(); let mut pos = 0; for s in payload.slices() { cstr.insert_unchecked(pos, s); @@ -191,14 +156,8 @@ pub unsafe extern "C" fn zc_payload_decode_into_bytes( payload: zc_payload_t, b: &mut z_owned_bytes_t, ) -> i8 { - let payload: Option<&ZBuf> = payload.into(); - if payload.is_none() { - *b = z_bytes_null(); - return 0; - } - *b = z_owned_bytes_t::preallocate(zc_payload_len(payload.into())); - let payload = payload.unwrap(); - + *b = z_owned_bytes_t::preallocate(zc_payload_len(payload)); + let payload = payload.transmute_copy(); let mut pos = 0; for s in payload.slices() { b.insert_unchecked(pos, s); @@ -225,21 +184,27 @@ impl ZSliceBuffer for z_bytes_t { /// Encodes byte sequence by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_bytes(bytes: z_bytes_t) -> zc_owned_payload_t { - ZBuf::from(bytes).into() +pub unsafe extern "C" fn zc_payload_encode_from_bytes( + dst: *mut MaybeUninit, + bytes: z_bytes_t, +) { + let dst = dst.transmute_uninit_ptr(); + let buf = ZBuf::from(bytes); + Inplace::init(dst, Some(buf)); } /// Encodes a null-terminated string by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_encode_from_string( + dst: *mut MaybeUninit, cstr: *const libc::c_char, -) -> zc_owned_payload_t { +) { let bytes = z_bytes_t { start: cstr as *const u8, len: libc::strlen(cstr), }; - zc_payload_encode_from_bytes(bytes) + zc_payload_encode_from_bytes(dst, bytes); } /// Returns total number bytes in the payload. @@ -248,8 +213,11 @@ pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { z_buffer_len(payload) } +pub use crate::opaque_types::zc_owned_payload_reader; +decl_transmute_owned!(Option>, zc_owned_payload_reader); + pub use crate::opaque_types::zc_payload_reader; -decl_transmute_copy!(ZBufReader<'static>, zc_payload_reader); +decl_transmute_copy!(&'static ZBufReader<'static>, zc_payload_reader); /// Creates a reader for the specified `payload`. /// @@ -257,14 +225,13 @@ decl_transmute_copy!(ZBufReader<'static>, zc_payload_reader); #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_reader_init( + this: *mut MaybeUninit, payload: zc_payload_t, - reader: *mut MaybeUninit, -) -> i8 { - if payload._inner.is_none() { - return -1; - } - *reader = payload.transmute().unwrap().reader().transmute(); - 0 +) { + let this = this.transmute_uninit_ptr(); + let payload = payload.transmute_copy(); + let reader = payload.reader(); + Inplace::init(this, Some(reader)); } /// Reads data into specified destination. @@ -274,23 +241,20 @@ pub unsafe extern "C" fn zc_payload_reader_init( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_reader_read( - reader: *mut zc_payload_reader, + reader: zc_payload_reader, dest: *mut u8, len: usize, ) -> usize { + let reader = reader.transmute_copy(); let buf = unsafe { from_raw_parts_mut(dest, len) }; - reader - .as_mut() - .unwrap() - .read(buf) - .map(|n| n.get()) - .unwrap_or(0) + reader.read(buf).map(|n| n.get()).unwrap_or(0) } /// Returns number of the remaining bytes in the payload /// #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_remaining(reader: *const zc_payload_reader) -> usize { - reader.as_ref().unwrap().remaining() +pub unsafe extern "C" fn zc_payload_reader_remaining(reader: zc_payload_reader) -> usize { + let reader = reader.transmute_copy(); + reader.remaining() } diff --git a/src/transmute.rs b/src/transmute.rs index ddc38824a..6a62a2b66 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -35,6 +35,10 @@ pub(crate) trait TransmuteCopy { fn transmute_copy(self) -> T; } +pub(crate) trait TransmuteUninitPtr: Sized { + fn transmute_uninit_ptr(self) -> *mut std::mem::MaybeUninit; +} + pub(crate) trait Inplace: Sized { // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized fn init(this: *mut std::mem::MaybeUninit, value: Self) { @@ -110,6 +114,8 @@ macro_rules! decl_transmute_owned { validate_equivalence!($zenoh_type, $c_type); impl_transmute_ref!($zenoh_type, $c_type); impl_transmute_ref!($c_type, $zenoh_type); + impl_transmute_uninit_ptr!($zenoh_type, $c_type); + impl_transmute_uninit_ptr!($c_type, $zenoh_type); } } @@ -119,6 +125,8 @@ macro_rules! decl_transmute_copy { validate_equivalence!($zenoh_type, $c_type); impl_transmute_copy!($zenoh_type, $c_type); impl_transmute_copy!($c_type, $zenoh_type); + impl_transmute_uninit_ptr!($zenoh_type, $c_type); + impl_transmute_uninit_ptr!($c_type, $zenoh_type); }; } @@ -144,3 +152,13 @@ macro_rules! impl_transmute_copy { } }; } + +macro_rules! impl_transmute_uninit_ptr { + ($src_type:ty, $dst_type:ty) => { + impl $crate::transmute::TransmuteUninitPtr<$dst_type> for *mut MaybeUninit<$src_type> { + fn transmute_uninit_ptr(self) -> *mut std::mem::MaybeUninit<$dst_type> { + self as *mut std::mem::MaybeUninit<$dst_type> + } + } + }; +} From 34bf5627a4537b0de306779a9fe5bfcb76e64524 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 15 Apr 2024 00:02:53 +0200 Subject: [PATCH 045/377] calling transmute_unitini_ptr as method --- src/commons.rs | 8 ++++---- src/payload.rs | 2 +- src/transmute.rs | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/commons.rs b/src/commons.rs index 72739ebbd..5bc998d49 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -183,7 +183,7 @@ decl_transmute_owned!(default_inplace_init Option, zc_owned_sample_t); pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { let src = src.transmute_copy(); let src = src.deref().clone(); - let dst = zc_owned_sample_t::transmute_uninit_ptr(dst); + let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); } @@ -213,7 +213,7 @@ pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { #[no_mangle] pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { - Inplace::empty(zc_owned_sample_t::transmute_uninit_ptr(sample)); + Inplace::empty(sample.transmute_uninit_ptr()); } /// The encoding of a payload, in a MIME-like format. @@ -236,7 +236,7 @@ decl_transmute_owned!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { - Inplace::empty(z_owned_encoding_t::transmute_uninit_ptr(encoding)); + Inplace::empty(encoding.transmute_uninit_ptr()); } /// Constructs a specific :c:type:`z_encoding_t`. @@ -246,7 +246,7 @@ pub unsafe extern "C" fn z_encoding_from_str( encoding: *mut MaybeUninit, s: *const c_char, ) -> i8 { - let encoding = z_owned_encoding_t::transmute_uninit_ptr(encoding); + let encoding = encoding.transmute_uninit_ptr(); if s.is_null() { Inplace::empty(encoding); 0 diff --git a/src/payload.rs b/src/payload.rs index 6e723e329..8959e8ac2 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -17,7 +17,7 @@ decl_transmute_owned!(Option, z_owned_buffer_t); /// The gravestone value for `z_owned_buffer_t`. #[no_mangle] extern "C" fn z_buffer_null(this: *mut MaybeUninit) { - let this = z_owned_buffer_t::transmute_uninit_ptr(this); + let this = this.transmute_uninit_ptr(); Inplace::empty(this); } diff --git a/src/transmute.rs b/src/transmute.rs index 6a62a2b66..3fe026532 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -24,11 +24,6 @@ pub fn unwrap_ref_unchecked(value: &Option) -> &T { pub(crate) trait TransmuteRef: Sized { fn transmute_ref(&self) -> &T; fn transmute_mut(&mut self) -> &mut T; - fn transmute_uninit_ptr( - this: *mut std::mem::MaybeUninit, - ) -> *mut std::mem::MaybeUninit { - this as *mut std::mem::MaybeUninit - } } pub(crate) trait TransmuteCopy { From fb8fa048338928c2cd844d93009b48856dd7dde3 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 15 Apr 2024 15:53:59 +0200 Subject: [PATCH 046/377] config partially updated --- build-resources/opaque-types/src/lib.rs | 3 + include/zenoh-gen.h | 184 +++++++++++++++++++++++- src/config.rs | 28 ++-- src/info.rs | 7 +- src/lib.rs | 8 +- 5 files changed, 206 insertions(+), 24 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 66a5fc44e..d2ad923ac 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use zenoh::buffers::{ZBuf, ZBufReader}; use zenoh::config::Config; +use zenoh::config::ZenohId; use zenoh::encoding::Encoding; use zenoh::key_expr::KeyExpr; use zenoh::query::Reply; @@ -91,3 +92,5 @@ get_opaque_type_data!(&'static Session, "z_session_t"); get_opaque_type_data!(Option>, "z_owned_config_t"); get_opaque_type_data!(&'static Config, "z_config_t"); + +get_opaque_type_data!(ZenohId, "z_id_t"); diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index 41fca39e9..a97ed1ddc 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -50,6 +50,18 @@ typedef struct z_owned_bytes_t { size_t len; } z_owned_bytes_t; +typedef struct ALIGN(8) z_owned_session_t { + uint8_t _0[8]; +} z_owned_session_t; + +typedef struct ALIGN(8) z_owned_config_t { + uint8_t _0[8]; +} z_owned_config_t; + +typedef struct ALIGN(8) z_config_t { + uint8_t _0[8]; +} z_config_t; + typedef struct ALIGN(8) z_owned_encoding_t { uint8_t _0[48]; } z_owned_encoding_t; @@ -75,11 +87,19 @@ typedef struct z_owned_buffer_t zc_owned_payload_t; typedef struct z_buffer_t zc_payload_t; +typedef struct ALIGN(1) z_id_t { + uint8_t _0[16]; +} z_id_t; + typedef struct z_timestamp_t { uint64_t time; - z_id_t id; + struct z_id_t id; } z_timestamp_t; +typedef struct ALIGN(8) z_session_t { + uint8_t _0[8]; +} z_session_t; + /** * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with @@ -110,6 +130,34 @@ typedef struct ALIGN(8) zc_owned_sample_t { uint8_t _0[240]; } zc_owned_sample_t; +extern const unsigned int Z_ROUTER; + +extern const unsigned int Z_PEER; + +extern const unsigned int Z_CLIENT; + +extern const char *Z_CONFIG_MODE_KEY; + +extern const char *Z_CONFIG_CONNECT_KEY; + +extern const char *Z_CONFIG_LISTEN_KEY; + +extern const char *Z_CONFIG_USER_KEY; + +extern const char *Z_CONFIG_PASSWORD_KEY; + +extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; + +extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; + +extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; + +extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; + +extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; + +extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; + /** * Returns `true` if the buffer is in a valid state. */ @@ -200,6 +248,65 @@ ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); */ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); +/** + * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * + * Returns a negative value if an error occured while closing the session. + * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + */ +ZENOHC_API int8_t z_close(struct z_owned_session_t *session); + +/** + * Returns ``true`` if `config` is valid. + */ +ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); + +/** + * Constructs a default, zenoh-allocated, client mode configuration. + * If `peer` is not null, it is added to the configuration as remote peer. + */ +ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); + +/** + * Creates a default, zenoh-allocated, configuration. + */ +ZENOHC_API struct z_owned_config_t z_config_default(void); + +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); + +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); + +/** + * Return a new, zenoh-allocated, empty configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +void z_config_new(struct z_owned_config_t *this_); + +/** + * Constructs a null safe-to-drop value of 'z_owned_config_t' type + */ +ZENOHC_API void z_config_null(struct z_owned_config_t *this_); + +/** + * Constructs a default, zenoh-allocated, peer mode configuration. + */ +ZENOHC_API struct z_owned_config_t z_config_peer(void); + /** * Returns ``true`` if `encoding` is valid. */ @@ -230,6 +337,13 @@ ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t * */ ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); +/** + * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + */ +ZENOHC_API +int8_t z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); + /** * The qos with which the sample was received. * TODO: split to methods (priority, congestion_control, express) @@ -276,6 +390,29 @@ ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); */ ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); +/** + * Returns ``true`` if `session` is valid. + */ +ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); + +/** + * Returns a :c:type:`z_session_t` loaned from `s`. + * + * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. + * + * # Safety + * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, + * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) + * have been destroyed is UB (likely SEGFAULT) + */ +ZENOHC_API +struct z_session_t z_session_loan(const struct z_owned_session_t *s); + +/** + * Constructs a null safe-to-drop value of 'z_owned_session_t' type + */ +ZENOHC_API void z_session_null(struct z_owned_session_t *s); + /** * Returns ``true`` if `s` is a valid string */ @@ -301,6 +438,44 @@ ZENOHC_API struct z_owned_str_t z_str_null(void); */ ZENOHC_API bool z_timestamp_check(struct z_timestamp_t ts); +/** + * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. + */ +ZENOHC_API +struct z_owned_config_t zc_config_from_file(const char *path); + +/** + * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. + * + * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). + */ +ZENOHC_API +struct z_owned_config_t zc_config_from_str(const char *s); + +/** + * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. + * Use `z_drop` to safely deallocate this string + */ +ZENOHC_API +struct z_owned_str_t zc_config_get(struct z_config_t config, + const char *key); + +/** + * Inserts a JSON-serialized `value` at the `key` position of the configuration. + * + * Returns 0 if successful, a negative value otherwise. + */ +ZENOHC_API +int8_t zc_config_insert_json(struct z_config_t config, + const char *key, + const char *value); + +/** + * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. + */ +ZENOHC_API +struct z_owned_str_t zc_config_to_string(struct z_config_t config); + /** * Initialises the zenoh runtime logger. * @@ -416,6 +591,13 @@ ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *samp ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); +/** + * Increments the session's reference count, returning a new owning handle. + */ +ZENOHC_API +int8_t zc_session_rcinc(struct z_owned_session_t *dst, + const struct z_owned_session_t *src); + ZENOHC_API enum zcu_locality_t zcu_locality_default(void); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); diff --git a/src/config.rs b/src/config.rs index 70f4ba776..824a45e37 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,8 +16,10 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; -use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null}; +use crate::transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr, +}; +use crate::{z_owned_str_t, z_str_null}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -97,7 +99,7 @@ pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t { /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[no_mangle] pub extern "C" fn z_config_new(this: *mut MaybeUninit) { - let this = z_owned_config_t::transmute_uninit_ptr(this); + let this = this.transmute_uninit_ptr(); let config: Box = Box::default(); Inplace::init(this, Some(config)); } @@ -105,7 +107,7 @@ pub extern "C" fn z_config_new(this: *mut MaybeUninit) { /// Constructs a null safe-to-drop value of 'z_owned_config_t' type #[no_mangle] pub extern "C" fn z_config_null(this: *mut MaybeUninit) { - let this = z_owned_config_t::transmute_uninit_ptr(this); + let this = this.transmute_uninit_ptr(); Inplace::empty(this); } @@ -114,12 +116,12 @@ pub extern "C" fn z_config_null(this: *mut MaybeUninit) { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) -> z_owned_str_t { + let config = config.transmute_copy(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, Err(_) => return z_str_null(), }; - - let val = config.as_ref().as_ref().and_then(|c| c.get_json(key).ok()); + let val = config.get_json(key).ok(); match val { Some(val) => val.as_bytes().into(), None => z_str_null(), @@ -132,18 +134,14 @@ pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) - #[no_mangle] #[allow(clippy::missing_safety_doc, unused_must_use)] pub unsafe extern "C" fn zc_config_insert_json( - mut config: z_config_t, + config: z_config_t, key: *const c_char, value: *const c_char, ) -> i8 { + let config = config.transmute_copy(); let key = CStr::from_ptr(key); let value = CStr::from_ptr(value); - match config - .as_mut() - .as_mut() - .expect("uninitialized config") - .insert_json5(&key.to_string_lossy(), &value.to_string_lossy()) - { + match config.insert_json5(&key.to_string_lossy(), &value.to_string_lossy()) { Ok(_) => 0, Err(_) => i8::MIN, } @@ -153,12 +151,14 @@ pub unsafe extern "C" fn zc_config_insert_json( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_config_drop(config: &mut z_owned_config_t) { - std::mem::drop(config.as_mut().take()) + let config = config.transmute_mut(); + Inplace::drop(config); } /// Returns ``true`` if `config` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_config_check(config: &z_owned_config_t) -> bool { + let config = config.transmute_ref(); config.as_ref().is_some() } diff --git a/src/info.rs b/src/info.rs index 2ee4d9384..b4e523d8a 100644 --- a/src/info.rs +++ b/src/info.rs @@ -19,11 +19,8 @@ use zenoh::session::SessionDeclarations; /// Represents a Zenoh ID. /// /// In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct z_id_t { - pub id: [u8; 16], -} +pub use crate::opaque_types::z_id_t; +decl_transmute_copy!(ZenohId, z_id_t); /// Returns the local Zenoh ID. /// diff --git a/src/lib.rs b/src/lib.rs index 113d5182d..dde332eaf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,8 +25,8 @@ pub use crate::opaque_types::*; mod collections; pub use crate::collections::*; -// mod config; -// pub use crate::config::*; +mod config; +pub use crate::config::*; mod commons; pub use crate::commons::*; mod payload; @@ -43,8 +43,8 @@ pub use crate::payload::*; // pub use crate::put::*; // mod scouting; // pub use crate::scouting::*; -// mod session; -// pub use crate::session::*; +mod session; +pub use crate::session::*; // mod subscriber; // pub use crate::subscriber::*; // // mod pull_subscriber; From e20e80b116a48bd5a65fb3f5ea2bb66e1da3079d Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 19 Apr 2024 20:37:13 +0200 Subject: [PATCH 047/377] some progress --- Cargo.lock | 244 +-- Cargo.toml | 2 + build-resources/opaque-types/Cargo.lock | 247 +-- build-resources/opaque-types/src/lib.rs | 243 ++- build.rs | 29 +- docs/api.rst | 32 +- examples/z_get.c | 4 +- examples/z_non_blocking_get.c | 2 +- examples/z_ping.c | 2 +- examples/z_pong.c | 4 +- examples/z_pub.c | 2 +- examples/z_pub_attachment.c | 10 +- examples/z_pub_cache.c | 2 +- examples/z_pub_shm.c | 2 +- examples/z_pub_thr.c | 2 +- examples/z_pull.c | 2 +- examples/z_put.c | 8 +- examples/z_query_sub.c | 2 +- examples/z_queryable.c | 10 +- examples/z_queryable_with_channels.c | 10 +- examples/z_sub.c | 2 +- examples/z_sub_attachment.c | 10 +- include/zenoh-gen.h | 2045 ++++++++++++++++++++--- include/zenoh_macros.h | 48 +- src/attachment.rs | 416 ----- src/closures/query_channel.rs | 129 +- src/closures/query_closure.rs | 10 +- src/closures/reply_closure.rs | 14 +- src/closures/response_channel.rs | 122 +- src/collections.rs | 322 +++- src/commons.rs | 378 +++-- src/config.rs | 103 +- src/errors.rs | 7 + src/get.rs | 276 +-- src/info.rs | 47 +- src/keyexpr.rs | 481 +++--- src/lib.rs | 30 +- src/payload.rs | 320 ++-- src/publisher.rs | 338 ++-- src/put.rs | 92 +- src/queryable.rs | 240 ++- src/scouting.rs | 59 +- src/session.rs | 36 +- src/shm.rs | 6 +- src/transmute.rs | 47 + tests/z_api_alignment_test.c | 8 +- tests/z_api_attachment_test.c | 44 +- tests/z_api_null_drop_test.c | 4 +- tests/z_api_payload_test.c | 18 +- tests/z_int_pub_cache_query_sub_test.c | 6 +- tests/z_int_pub_sub_attachment_test.c | 16 +- tests/z_int_pub_sub_test.c | 4 +- tests/z_int_queryable_attachment_test.c | 28 +- tests/z_int_queryable_test.c | 6 +- 54 files changed, 3991 insertions(+), 2580 deletions(-) delete mode 100644 src/attachment.rs create mode 100644 src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index 336fce624..c10ee7ae4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,6 +35,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -70,54 +71,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anstream" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" - -[[package]] -name = "anstyle-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - [[package]] name = "anyhow" version = "1.0.75" @@ -463,12 +416,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - [[package]] name = "concurrent-queue" version = "2.2.0" @@ -604,16 +551,6 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" -[[package]] -name = "env_filter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" -dependencies = [ - "log", - "regex", -] - [[package]] name = "env_logger" version = "0.10.2" @@ -627,19 +564,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1229,6 +1153,15 @@ dependencies = [ "twox-hash", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.6.3" @@ -1303,6 +1236,16 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -1414,6 +1357,12 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.1.0" @@ -1755,8 +1704,17 @@ checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1767,9 +1725,15 @@ checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.7.5" @@ -2186,6 +2150,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shared_memory" version = "0.12.4" @@ -2402,6 +2375,16 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2542,6 +2525,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", ] [[package]] @@ -2678,12 +2704,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "uuid" version = "1.4.1" @@ -2717,6 +2737,12 @@ dependencies = [ "unzip-n", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "value-bag" version = "1.8.1" @@ -3060,17 +3086,16 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" name = "zenoh" version = "0.11.0-dev" dependencies = [ + "ahash", "async-trait", "base64", "const_format", - "env_logger 0.11.3", "event-listener 4.0.0", "flume", "form_urlencoded", "futures", "git-version", "lazy_static", - "log", "ordered-float", "paste", "petgraph", @@ -3087,6 +3112,7 @@ dependencies = [ "stop-token", "tokio", "tokio-util", + "tracing", "uhlc", "unwrap-infallible", "uuid", @@ -3126,7 +3152,7 @@ dependencies = [ "async-trait", "cbindgen", "chrono", - "env_logger 0.10.2", + "env_logger", "fs2", "fs_extra", "futures", @@ -3141,14 +3167,16 @@ dependencies = [ "unwrap-infallible", "zenoh", "zenoh-ext", + "zenoh-protocol", + "zenoh-util", ] [[package]] name = "zenoh-codec" version = "0.11.0-dev" dependencies = [ - "log", "serde", + "tracing", "uhlc", "zenoh-buffers", "zenoh-protocol", @@ -3165,12 +3193,12 @@ version = "0.11.0-dev" dependencies = [ "flume", "json5", - "log", "num_cpus", "secrecy", "serde", "serde_json", "serde_yaml", + "tracing", "validated_struct", "zenoh-core", "zenoh-protocol", @@ -3206,16 +3234,16 @@ name = "zenoh-ext" version = "0.11.0-dev" dependencies = [ "bincode", - "env_logger 0.11.3", "flume", "futures", - "log", "phf", "serde", "serde_cbor", "serde_json", "tokio", + "tracing", "zenoh", + "zenoh-util", ] [[package]] @@ -3255,12 +3283,12 @@ dependencies = [ "async-trait", "flume", "futures", - "log", "rustls 0.22.3", "rustls-webpki 0.102.2", "serde", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-core", @@ -3277,7 +3305,6 @@ dependencies = [ "async-trait", "base64", "futures", - "log", "quinn", "rustls 0.21.7", "rustls-native-certs 0.7.0", @@ -3287,6 +3314,8 @@ dependencies = [ "tokio", "tokio-rustls 0.24.1", "tokio-util", + "tracing", + "zenoh-collections", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -3302,9 +3331,9 @@ name = "zenoh-link-tcp" version = "0.11.0-dev" dependencies = [ "async-trait", - "log", "tokio", "tokio-util", + "tracing", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", @@ -3321,7 +3350,6 @@ dependencies = [ "async-trait", "base64", "futures", - "log", "rustls 0.22.3", "rustls-pemfile 2.0.0", "rustls-pki-types", @@ -3330,7 +3358,9 @@ dependencies = [ "tokio", "tokio-rustls 0.25.0", "tokio-util", + "tracing", "webpki-roots", + "zenoh-collections", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -3346,10 +3376,10 @@ name = "zenoh-link-udp" version = "0.11.0-dev" dependencies = [ "async-trait", - "log", "socket2 0.5.6", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-collections", "zenoh-core", @@ -3367,10 +3397,10 @@ version = "0.11.0-dev" dependencies = [ "async-trait", "futures", - "log", "nix 0.27.1", "tokio", "tokio-util", + "tracing", "uuid", "zenoh-core", "zenoh-link-commons", @@ -3386,10 +3416,10 @@ version = "0.11.0-dev" dependencies = [ "async-trait", "futures-util", - "log", "tokio", "tokio-tungstenite", "tokio-util", + "tracing", "url", "zenoh-core", "zenoh-link-commons", @@ -3416,9 +3446,9 @@ version = "0.11.0-dev" dependencies = [ "const_format", "libloading", - "log", "serde", "serde_json", + "tracing", "zenoh-keyexpr", "zenoh-macros", "zenoh-result", @@ -3434,6 +3464,7 @@ dependencies = [ "serde", "uhlc", "zenoh-buffers", + "zenoh-collections", "zenoh-keyexpr", "zenoh-result", ] @@ -3452,7 +3483,7 @@ dependencies = [ "futures", "lazy_static", "tokio", - "zenoh-collections", + "zenoh-protocol", "zenoh-result", ] @@ -3460,9 +3491,9 @@ dependencies = [ name = "zenoh-shm" version = "0.11.0-dev" dependencies = [ - "log", "serde", "shared_memory", + "tracing", "zenoh-buffers", "zenoh-result", ] @@ -3485,9 +3516,9 @@ name = "zenoh-task" version = "0.11.0-dev" dependencies = [ "futures", - "log", "tokio", "tokio-util", + "tracing", "zenoh-core", "zenoh-runtime", ] @@ -3498,7 +3529,6 @@ version = "0.11.0-dev" dependencies = [ "async-trait", "flume", - "log", "lz4_flex", "paste", "rand", @@ -3508,6 +3538,7 @@ dependencies = [ "sha3", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-collections", @@ -3536,10 +3567,11 @@ dependencies = [ "lazy_static", "libc", "libloading", - "log", "pnet_datalink", "shellexpand", "tokio", + "tracing", + "tracing-subscriber", "winapi", "zenoh-core", "zenoh-result", diff --git a/Cargo.toml b/Cargo.toml index e3579e00e..767d9a3a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,6 +59,8 @@ unwrap-infallible = "0.1.5" zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} +zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } +zenoh-util = { path = "../zenoh/commons/zenoh-util" } [build-dependencies] cbindgen = "0.26.0" diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index 5ed408409..b3cd2f5b5 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -35,6 +35,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -55,54 +56,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" -[[package]] -name = "anstream" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" - -[[package]] -name = "anstyle-parse" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - [[package]] name = "anyhow" version = "1.0.81" @@ -432,12 +385,6 @@ dependencies = [ "inout", ] -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - [[package]] name = "concurrent-queue" version = "2.4.0" @@ -530,29 +477,6 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" -[[package]] -name = "env_filter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1083,6 +1007,15 @@ dependencies = [ "twox-hash", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.7.2" @@ -1146,6 +1079,16 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -1223,6 +1166,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.2.0" @@ -1506,8 +1455,17 @@ checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1518,9 +1476,15 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.3", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.3" @@ -1776,6 +1740,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shared_memory" version = "0.12.4" @@ -1822,6 +1795,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "socket2" version = "0.4.10" @@ -1917,6 +1896,16 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "token-cell" version = "1.5.0" @@ -1976,14 +1965,72 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "tracing-core" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] [[package]] name = "twox-hash" @@ -2062,12 +2109,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "uuid" version = "1.8.0" @@ -2101,6 +2142,12 @@ dependencies = [ "unzip-n", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "value-bag" version = "1.8.1" @@ -2417,17 +2464,16 @@ checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" name = "zenoh" version = "0.11.0-dev" dependencies = [ + "ahash", "async-trait", "base64", "const_format", - "env_logger", "event-listener 4.0.3", "flume", "form_urlencoded", "futures", "git-version", "lazy_static", - "log", "ordered-float", "paste", "petgraph", @@ -2444,6 +2490,7 @@ dependencies = [ "stop-token", "tokio", "tokio-util", + "tracing", "uhlc", "unwrap-infallible", "uuid", @@ -2479,8 +2526,8 @@ dependencies = [ name = "zenoh-codec" version = "0.11.0-dev" dependencies = [ - "log", "serde", + "tracing", "uhlc", "zenoh-buffers", "zenoh-protocol", @@ -2497,12 +2544,12 @@ version = "0.11.0-dev" dependencies = [ "flume", "json5", - "log", "num_cpus", "secrecy", "serde", "serde_json", "serde_yaml", + "tracing", "validated_struct", "zenoh-core", "zenoh-protocol", @@ -2538,16 +2585,16 @@ name = "zenoh-ext" version = "0.11.0-dev" dependencies = [ "bincode", - "env_logger", "flume", "futures", - "log", "phf", "serde", "serde_cbor", "serde_json", "tokio", + "tracing", "zenoh", + "zenoh-util", ] [[package]] @@ -2581,12 +2628,12 @@ dependencies = [ "async-trait", "flume", "futures", - "log", "rustls", "rustls-webpki", "serde", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-core", @@ -2612,9 +2659,9 @@ version = "0.11.0-dev" dependencies = [ "const_format", "libloading", - "log", "serde", "serde_json", + "tracing", "zenoh-keyexpr", "zenoh-macros", "zenoh-result", @@ -2630,6 +2677,7 @@ dependencies = [ "serde", "uhlc", "zenoh-buffers", + "zenoh-collections", "zenoh-keyexpr", "zenoh-result", ] @@ -2648,7 +2696,7 @@ dependencies = [ "futures", "lazy_static", "tokio", - "zenoh-collections", + "zenoh-protocol", "zenoh-result", ] @@ -2656,9 +2704,9 @@ dependencies = [ name = "zenoh-shm" version = "0.11.0-dev" dependencies = [ - "log", "serde", "shared_memory", + "tracing", "zenoh-buffers", "zenoh-result", ] @@ -2681,9 +2729,9 @@ name = "zenoh-task" version = "0.11.0-dev" dependencies = [ "futures", - "log", "tokio", "tokio-util", + "tracing", "zenoh-core", "zenoh-runtime", ] @@ -2694,7 +2742,6 @@ version = "0.11.0-dev" dependencies = [ "async-trait", "flume", - "log", "lz4_flex", "paste", "rand", @@ -2703,6 +2750,7 @@ dependencies = [ "sha3", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-collections", @@ -2731,10 +2779,11 @@ dependencies = [ "lazy_static", "libc", "libloading", - "log", "pnet_datalink", "shellexpand", "tokio", + "tracing", + "tracing-subscriber", "winapi", "zenoh-core", "zenoh-result", diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index d2ad923ac..dd5443d73 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,14 +1,20 @@ +use std::borrow::Cow; +use std::collections::HashMap; use std::sync::Arc; -use zenoh::buffers::{ZBuf, ZBufReader}; use zenoh::config::Config; use zenoh::config::ZenohId; use zenoh::encoding::Encoding; +use zenoh::handlers::DefaultHandler; use zenoh::key_expr::KeyExpr; +use zenoh::bytes::{ZBytes, ZBytesReader}; +use zenoh::publication::MatchingListener; +use zenoh::publication::Publisher; use zenoh::query::Reply; use zenoh::queryable::Query; use zenoh::queryable::Queryable; use zenoh::sample::Sample; use zenoh::session::Session; +use zenoh::time::Timestamp; use zenoh::value::Value; // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. @@ -19,78 +25,233 @@ use zenoh::value::Value; #[macro_export] macro_rules! get_opaque_type_data { - ($src_type:ty, $expr:expr) => { + ($src_type:ty, $name:ident) => { const _: () = { - let align = std::mem::align_of::<$src_type>(); - let size = std::mem::size_of::<$src_type>(); - let mut msg: [u8; 61] = - *b"type: , align: , size: "; - let mut i = 0; - while i < 4 { - msg[i as usize + 46] = b'0' + ((align / 10u32.pow(3 - i) as usize) % 10) as u8; - msg[i as usize + 57] = b'0' + ((size / 10u32.pow(3 - i) as usize) % 10) as u8; - i += 1; + const fn get_num_digits(n: usize) -> usize { + let mut out = 0; + let mut res = n; + while res > 0 { + out += 1; + res = res / 10; + } + if out == 0 { + out = 1; + } + out } - let mut i: usize = 0; - while i < $expr.len() { - msg[i as usize + 5] = $expr.as_bytes()[i]; - i += 1; + + const fn write_str(src: &[u8], mut dst: [u8; MSG_LEN], offset: usize) -> [u8; MSG_LEN] { + let mut i = 0; + while i < src.len() { + dst[i + offset] = src[i]; + i += 1; + } + dst + } + + const fn write_num(src: usize, mut dst: [u8; MSG_LEN], offset: usize) -> [u8; MSG_LEN] { + let mut i = 0; + let num_digits = get_num_digits(src) as u32; + while i < num_digits { + dst[i as usize + offset] = b'0' + ((src / 10u32.pow(num_digits - i - 1) as usize) % 10) as u8; + i += 1; + } + dst } + + const DST_NAME: &str = stringify!($name); + const ALIGN: usize = std::mem::align_of::<$src_type>(); + const SIZE: usize = std::mem::size_of::<$src_type>(); + const TYPE_TOKEN: [u8; 6] = *b"type: "; + const ALIGN_TOKEN: [u8; 9] = *b", align: "; + const SIZE_TOKEN: [u8; 8] = *b", size: "; + const SIZE_NUM_DIGITS: usize = get_num_digits(SIZE); + const ALIGN_NUM_DIGITS: usize = get_num_digits(ALIGN); + const MSG_LEN: usize = TYPE_TOKEN.len() + ALIGN_TOKEN.len() + SIZE_TOKEN.len() + SIZE_NUM_DIGITS + ALIGN_NUM_DIGITS + DST_NAME.len(); + const TYPE_OFFSET: usize = TYPE_TOKEN.len(); + const ALIGN_OFFSET: usize = TYPE_OFFSET + DST_NAME.len() + ALIGN_TOKEN.len(); + const SIZE_OFFSET: usize = ALIGN_OFFSET + ALIGN_NUM_DIGITS + SIZE_TOKEN.len(); + let mut msg: [u8; MSG_LEN] = [b' '; MSG_LEN]; + + msg = write_str(&TYPE_TOKEN, msg, 0); + msg = write_str(&DST_NAME.as_bytes(), msg, TYPE_OFFSET); + msg = write_str(&ALIGN_TOKEN, msg, ALIGN_OFFSET - ALIGN_TOKEN.len()); + msg = write_num(ALIGN, msg, ALIGN_OFFSET); + msg = write_str(&SIZE_TOKEN, msg, SIZE_OFFSET - SIZE_TOKEN.len()); + msg = write_num(SIZE, msg, SIZE_OFFSET); + panic!("{}", unsafe { std::str::from_utf8_unchecked(msg.as_slice()) }); }; - }; + } } /// A split buffer that owns all of its data. /// /// To minimize copies and reallocations, Zenoh may provide you data in split buffers. -get_opaque_type_data!(Option, "z_owned_buffer_t"); -get_opaque_type_data!(&'static ZBuf, "z_buffer_t"); +get_opaque_type_data!(Option, z_owned_bytes_t); +/// A loaned payload. +get_opaque_type_data!(&'static ZBytes, z_bytes_t); + +/// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. +/// +/// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher +get_opaque_type_data!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); +get_opaque_type_data!(&'static HashMap, Cow<'static, [u8]>>, z_slice_map_t); /// An owned sample. /// /// This is a read only type that can only be constructed by cloning a `z_sample_t`. /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -get_opaque_type_data!(Option, "zc_owned_sample_t"); - -get_opaque_type_data!(&'static Sample, "z_sample_t"); +get_opaque_type_data!(Option, zc_owned_sample_t); +get_opaque_type_data!(&'static Sample, z_sample_t); /// A reader for payload data. -get_opaque_type_data!(Option>, "zc_owned_payload_reader"); -get_opaque_type_data!(&'static ZBufReader, "zc_payload_reader"); +get_opaque_type_data!(Option>, z_owned_bytes_t_reader_t); +get_opaque_type_data!(&'static ZBytesReader<'static>, z_bytes_reader_t); -get_opaque_type_data!(&'static Encoding, "z_encoding_t"); -get_opaque_type_data!(Encoding, "z_owned_encoding_t"); +/// The encoding of a payload, in a MIME-like format. +/// +/// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. +get_opaque_type_data!(&'static Encoding, z_encoding_t); +get_opaque_type_data!(Encoding, z_owned_encoding_t); -get_opaque_type_data!(Option, "z_owned_reply_t"); +/// An owned reply to a :c:func:`z_get`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +get_opaque_type_data!(Option, z_owned_reply_t); +get_opaque_type_data!(&'static Reply, z_reply_t); -get_opaque_type_data!(Value, "z_owned_value_t"); -get_opaque_type_data!(&'static Value, "z_value_t"); +/// A zenoh value. +get_opaque_type_data!(Value, z_owned_value_t); +get_opaque_type_data!(&'static Value, z_value_t); -get_opaque_type_data!(Option, "z_owned_query_t"); -get_opaque_type_data!(&'static Query, "z_query_t"); +// Loaned variant of a Query received by a Queryable. +/// +/// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. +/// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. +get_opaque_type_data!(Option, z_owned_query_t); +get_opaque_type_data!(&'static Query, z_query_t); -get_opaque_type_data!(Option>, "z_owned_queryable_t"); -get_opaque_type_data!(&'static Queryable<'static, ()>, "z_queryable_t"); +/// An owned zenoh queryable. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_queryable_t); +get_opaque_type_data!(&'static Queryable<'static, ()>, z_queryable_t); // get_opaque_type_data!( // Option>, -// "ze_owned_querying_subscriber_t" +// ze_owned_querying_subscriber_t // ); // get_opaque_type_data!( // &'static FetchingSubscriberWrapper, -// "ze_querying_subscriber_t" +// ze_querying_subscriber_t // ); -get_opaque_type_data!(Option>, "z_owned_keyexpr_t"); -get_opaque_type_data!(&'static KeyExpr<'_>, "z_keyexpr_t"); +/// A zenoh-allocated key expression. +/// +/// Key expressions can identify a single key or a set of keys. +/// +/// Examples : +/// - ``"key/expression"``. +/// - ``"key/ex*"``. +/// +/// Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` +/// for wire and computation efficiency. +/// +/// A `key expression `_ can be either: +/// - A plain string expression. +/// - A pure numerical id. +/// - The combination of a numerical prefix and a string suffix. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_keyexpr_t); +/// A loaned key expression. +/// +/// Key expressions can identify a single key or a set of keys. +/// +/// Examples : +/// - ``"key/expression"``. +/// - ``"key/ex*"``. +/// +/// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, +/// both for local processing and network-wise. +get_opaque_type_data!(&'static KeyExpr<'_>, z_keyexpr_t); + +/// An owned zenoh session. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_session_t); +get_opaque_type_data!(&'static Session, z_session_t); -get_opaque_type_data!(Option>, "z_owned_session_t"); -get_opaque_type_data!(&'static Session, "z_session_t"); +/// An owned zenoh configuration. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_config_t); +/// A loaned zenoh configuration. +get_opaque_type_data!(&'static Config, z_config_t); + +/// Represents a Zenoh ID. +/// +/// In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. +get_opaque_type_data!(ZenohId, z_id_t); -get_opaque_type_data!(Option>, "z_owned_config_t"); -get_opaque_type_data!(&'static Config, "z_config_t"); +get_opaque_type_data!(Timestamp, z_timestamp_t); + +/// An owned zenoh publisher. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_publisher_t); +get_opaque_type_data!(&'static Publisher<'static>, z_publisher_t); -get_opaque_type_data!(ZenohId, "z_id_t"); +/// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, zcu_owned_matching_listener_t); diff --git a/build.rs b/build.rs index 97a90078a..120b308f7 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,5 @@ use fs2::FileExt; +use fs_extra::dir::remove; use regex::Regex; use std::env; use std::io::{Read, Write}; @@ -91,9 +92,12 @@ fn generate_opaque_types() { let data_in = std::fs::read_to_string(path_in).unwrap(); let mut data_out = String::new(); - let docs = get_opaque_type_docs(); + data_out += "#[rustfmt::skip] +#[allow(clippy::all)] +"; + let mut docs = get_opaque_type_docs(); - let re = Regex::new(r"type:(\w+) *, align:0*(\d+), size:0*(\d+)").unwrap(); + let re = Regex::new(r"type: (\w+), align: (\d+), size: (\d+)").unwrap(); for (_, [type_name, align, size]) in re.captures_iter(&data_in).map(|c| c.extract()) { let s = format!( "#[derive(Copy, Clone)] @@ -103,21 +107,25 @@ pub struct {type_name} {{ }} " ); - if let Some(doc) = docs.get(type_name) { - for d in doc { - data_out += d; - data_out += "\r\n"; - } + let doc = docs.remove(type_name).expect(&format!( + "Failed to extract docs for opaque type: {type_name}" + )); + for d in doc { + data_out += &d; + data_out += "\r\n"; } data_out += &s; } + for d in docs.keys() { + panic!("Failed to find type information for opaque type: {d}"); + } std::fs::write(path_out, data_out).unwrap(); } fn get_opaque_type_docs() -> HashMap> { let current_folder = get_build_rs_path(); let path_in = current_folder.join("./build-resources/opaque-types/src/lib.rs"); - let re = Regex::new(r#"get_opaque_type_data!\(.*, "(\w+)"\)"#).unwrap(); + let re = Regex::new(r#"(?m)^\s*get_opaque_type_data!\(\s*(.*)\s*,\s*(\w+)\)"#).unwrap(); let mut comments = std::vec::Vec::::new(); let mut res = HashMap::>::new(); @@ -126,11 +134,8 @@ fn get_opaque_type_docs() -> HashMap> { comments.push(line.to_string()); continue; } - if comments.is_empty() { - continue; - } if let Some(c) = re.captures(line) { - res.insert(c[1].to_string(), comments.clone()); + res.insert(c[2].to_string(), comments.clone()); } comments.clear(); } diff --git a/docs/api.rst b/docs/api.rst index 758c405b5..046ede892 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -22,29 +22,29 @@ Generic types Bytes ----- -.. autocstruct:: zenoh_commons.h::z_bytes_t +.. autocstruct:: zenoh_commons.h::z_slice_t -.. autocfunction:: zenoh_commons.h::z_bytes_new -.. autocfunction:: zenoh_commons.h::z_bytes_check -.. autocfunction:: zenoh_commons.h::z_bytes_null +.. autocfunction:: zenoh_commons.h::z_slice_new +.. autocfunction:: zenoh_commons.h::z_slice_check +.. autocfunction:: zenoh_commons.h::z_slice_null Bytes map --------- .. autocstruct:: zenoh_commons.h::z_owned_bytes_map_t -.. autocfunction:: zenoh_commons.h::z_bytes_map_new -.. autocfunction:: zenoh_commons.h::z_bytes_map_check -.. autocfunction:: zenoh_commons.h::z_bytes_map_null -.. autocfunction:: zenoh_commons.h::z_bytes_map_drop -.. autocfunction:: zenoh_commons.h::z_bytes_map_get -.. autocfunction:: zenoh_commons.h::z_bytes_map_len -.. autocfunction:: zenoh_commons.h::z_bytes_map_is_empty -.. autocfunction:: zenoh_commons.h::z_bytes_map_insert_by_alias -.. autocfunction:: zenoh_commons.h::z_bytes_map_insert_by_copy -.. autocfunction:: zenoh_commons.h::z_bytes_map_iter -.. autocfunction:: zenoh_commons.h::z_bytes_map_from_attachment -.. autocfunction:: zenoh_commons.h::z_bytes_map_from_attachment_aliasing +.. autocfunction:: zenoh_commons.h::z_slice_map_new +.. autocfunction:: zenoh_commons.h::z_slice_map_check +.. autocfunction:: zenoh_commons.h::z_slice_map_null +.. autocfunction:: zenoh_commons.h::z_slice_map_drop +.. autocfunction:: zenoh_commons.h::z_slice_map_get +.. autocfunction:: zenoh_commons.h::z_slice_map_len +.. autocfunction:: zenoh_commons.h::z_slice_map_is_empty +.. autocfunction:: zenoh_commons.h::z_slice_map_insert_by_alias +.. autocfunction:: zenoh_commons.h::z_slice_map_insert_by_copy +.. autocfunction:: zenoh_commons.h::z_slice_map_iter +.. autocfunction:: zenoh_commons.h::z_slice_map_from_attachment +.. autocfunction:: zenoh_commons.h::z_slice_map_from_attachment_aliasing .. Scouting .. ======== diff --git a/examples/z_get.c b/examples/z_get.c index 9866212f7..d8f90b35e 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -57,7 +57,7 @@ int main(int argc, char **argv) { z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get_options_t opts = z_get_options_default(); if (value != NULL) { - opts.payload = zc_payload_encode_from_string(value); + opts.payload = z_bytes_encode_from_string(value); } z_get(z_loan(s), keyexpr, "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate @@ -67,7 +67,7 @@ int main(int argc, char **argv) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); z_drop(z_move(keystr)); diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index 471f7e227..30df45daf 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -60,7 +60,7 @@ int main(int argc, char **argv) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); z_drop(z_move(keystr)); diff --git a/examples/z_ping.c b/examples/z_ping.c index a5c0954d0..8f8adb2f7 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -54,7 +54,7 @@ int main(int argc, char** argv) { for (int i = 0; i < args.size; i++) { data[i] = i % 10; } - zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = data, .len = args.size}); + z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_slice_t){.start = data, .len = args.size}); z_mutex_lock(&mutex); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); diff --git a/examples/z_pong.c b/examples/z_pong.c index 772280696..3da1150bb 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -5,8 +5,8 @@ void callback(const z_sample_t* sample, void* context) { z_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); -#ifdef ZENOH_C // The zc_owned_payload_t API is exclusive to zenoh-c, but allows avoiding some copies. - zc_owned_payload_t payload = z_sample_owned_payload(sample); +#ifdef ZENOH_C // The z_owned_bytes_t API is exclusive to zenoh-c, but allows avoiding some copies. + z_owned_bytes_t payload = z_sample_owned_payload(sample); z_publisher_put(pub, z_move(payload), NULL); #endif } diff --git a/examples/z_pub.c b/examples/z_pub.c index 9dd496153..29ccd5c8e 100644 --- a/examples/z_pub.c +++ b/examples/z_pub.c @@ -71,7 +71,7 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_owned_bytes_t payload = z_bytes_encode_from_string(buf); z_publisher_put(z_loan(pub), z_move(payload), &options); } diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index 530d9dc29..c45b25811 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -52,13 +52,13 @@ int main(int argc, char **argv) { options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); // allocate attachment map - z_owned_bytes_map_t map = z_bytes_map_new(); + z_owned_bytes_map_t map = z_slice_map_new(); // set it as an attachment - options.attachment = z_bytes_map_as_attachment(&map); + options.attachment = z_slice_map_as_attachment(&map); // add some value - z_bytes_map_insert_by_alias(&map, z_bytes_from_str("source"), z_bytes_from_str("C")); + z_slice_map_insert_by_alias(&map, z_slice_from_str("source"), z_slice_from_str("C")); char buf[256]; char buf_ind[16]; @@ -67,11 +67,11 @@ int main(int argc, char **argv) { // add some other attachment value sprintf(buf_ind, "%d", idx); - z_bytes_map_insert_by_alias(&map, z_bytes_from_str("index"), z_bytes_from_str(buf_ind)); + z_slice_map_insert_by_alias(&map, z_slice_from_str("index"), z_slice_from_str(buf_ind)); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_owned_bytes_t payload = z_bytes_encode_from_string(buf); z_publisher_put(z_loan(pub), z_move(payload), &options); } diff --git a/examples/z_pub_cache.c b/examples/z_pub_cache.c index 622896948..7594fee1f 100644 --- a/examples/z_pub_cache.c +++ b/examples/z_pub_cache.c @@ -63,7 +63,7 @@ int main(int argc, char **argv) { z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_owned_bytes_t payload = z_bytes_encode_from_string(buf); z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } diff --git a/examples/z_pub_shm.c b/examples/z_pub_shm.c index 3c032e02f..c7bb1684d 100644 --- a/examples/z_pub_shm.c +++ b/examples/z_pub_shm.c @@ -83,7 +83,7 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t payload = zc_shmbuf_into_payload(z_move(shmbuf)); + z_owned_bytes_t payload = zc_shmbuf_into_payload(z_move(shmbuf)); z_publisher_put(z_loan(pub), z_move(payload), &options); } diff --git a/examples/z_pub_thr.c b/examples/z_pub_thr.c index e0568973c..0298ceacf 100644 --- a/examples/z_pub_thr.c +++ b/examples/z_pub_thr.c @@ -54,7 +54,7 @@ int main(int argc, char **argv) { } while (1) { - zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = value, .len = len}); + z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_slice_t){.start = value, .len = len}); z_publisher_put(z_loan(pub), z_move(payload), NULL); } diff --git a/examples/z_pull.c b/examples/z_pull.c index 094dc0a6b..8016da577 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -19,7 +19,7 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); diff --git a/examples/z_put.c b/examples/z_put.c index 503fb5c36..c74f95672 100644 --- a/examples/z_put.c +++ b/examples/z_put.c @@ -23,8 +23,8 @@ int main(int argc, char **argv) { if (argc > 1) keyexpr = argv[1]; if (argc > 2) value = argv[2]; - z_owned_bytes_map_t attachment = z_bytes_map_new(); - z_bytes_map_insert_by_alias(&attachment, z_bytes_from_str("hello"), z_bytes_from_str("there")); + z_owned_bytes_map_t attachment = z_slice_map_new(); + z_slice_map_insert_by_alias(&attachment, z_slice_from_str("hello"), z_slice_from_str("there")); z_owned_config_t config = z_config_default(); if (argc > 3) { @@ -47,8 +47,8 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, value); z_put_options_t options = z_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - options.attachment = z_bytes_map_as_attachment(&attachment); - zc_owned_payload_t payload = zc_payload_encode_from_string(value); + options.attachment = z_slice_map_as_attachment(&attachment); + z_owned_bytes_t payload = z_bytes_encode_from_string(value); int res = z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), &options); if (res < 0) { printf("Put failed...\n"); diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index 620dd9594..a2f878019 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -19,7 +19,7 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 577ef146e..4342c6746 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -21,11 +21,11 @@ z_keyexpr_t keyexpr; void query_handler(const z_query_t *query, void *context) { z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_bytes_t pred = z_query_parameters(query); - zc_payload_t payload = z_query_value(query).payload; - if (zc_payload_len(payload) > 0) { + z_slice_t pred = z_query_parameters(query); + z_bytes_t payload = z_query_value(query).payload; + if (z_bytes_len(payload) > 0) { z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(payload, &payload_value); + z_bytes_decode_into_string(payload, &payload_value); printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, pred.start, z_loan(payload_value)); z_drop(z_move(payload_value)); @@ -35,7 +35,7 @@ void query_handler(const z_query_t *query, void *context) { z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_owned_bytes_t reply_payload = z_bytes_encode_from_string(value); z_query_reply(query, z_keyexpr((const char *)context), z_move(reply_payload), &options); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 6c3ca0df1..422ad3971 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -67,11 +67,11 @@ int main(int argc, char **argv) { for (z_call(channel.recv, &oquery); z_check(oquery); z_call(channel.recv, &oquery)) { z_query_t query = z_loan(oquery); z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(&query)); - z_bytes_t pred = z_query_parameters(&query); - zc_payload_t payload = z_query_value(&query).payload; - if (zc_payload_len(payload) > 0) { + z_slice_t pred = z_query_parameters(&query); + z_bytes_t payload = z_query_value(&query).payload; + if (z_bytes_len(payload) > 0) { z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(payload, &payload_value); + z_bytes_decode_into_string(payload, &payload_value); printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, pred.start, z_loan(payload_value)); z_drop(z_move(payload_value)); @@ -80,7 +80,7 @@ int main(int argc, char **argv) { } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_owned_bytes_t reply_payload = z_bytes_encode_from_string(value); z_query_reply(&query, keyexpr, z_move(reply_payload), &options); z_drop(z_move(keystr)); z_drop(z_move(oquery)); diff --git a/examples/z_sub.c b/examples/z_sub.c index ffa63703b..f549d1561 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -19,7 +19,7 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index b703e6ad6..6c1ea68be 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -17,7 +17,7 @@ const char *kind_to_str(z_sample_kind_t kind); -int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { +int8_t attachment_reader(z_slice_t key, z_slice_t val, void *ctx) { printf(" attachment: %.*s: '%.*s'\n", (int)key.len, key.start, (int)val.len, val.start); return 0; } @@ -25,19 +25,19 @@ int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); - z_attachment_t attachment = z_sample_attachment(sample); + z_bytes_t attachment = z_sample_attachment(sample); // checks if attachment exists if (z_check(attachment)) { // reads full attachment z_attachment_iterate(attachment, attachment_reader, NULL); // reads particular attachment item - z_bytes_t index = z_attachment_get(attachment, z_bytes_from_str("index")); - if (z_bytes_is_initialized(&index)) { + z_slice_t index = z_attachment_get(attachment, z_slice_from_str("index")); + if (z_slice_is_initialized(&index)) { printf(" message number: %.*s\n", (int)index.len, index.start); } } diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index a97ed1ddc..1761f69b2 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,6 +5,91 @@ #include + + +#define DEFAULT_SCOUTING_TIMEOUT 1000 + +/** + * The kind of congestion control. + * + * - **BLOCK** + * - **DROP** + */ +typedef enum z_congestion_control_t { + Z_CONGESTION_CONTROL_T_BLOCK, + Z_CONGESTION_CONTROL_T_DROP, +} z_congestion_control_t; + +/** + * Consolidation mode values. + * + * - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector + * If the selector contains time range properties, consolidation mode `NONE` is used. + * Otherwise the `LATEST` consolidation mode is used. + * - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. + * - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time + * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple + * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp + * ts2 > ts1. It optimizes latency. + * - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. + * It optimizes bandwidth. + */ +typedef enum z_consolidation_mode_t { + Z_CONSOLIDATION_MODE_T_AUTO = -1, + Z_CONSOLIDATION_MODE_T_NONE = 0, + Z_CONSOLIDATION_MODE_T_MONOTONIC = 1, + Z_CONSOLIDATION_MODE_T_LATEST = 2, +} z_consolidation_mode_t; + +/** + * A :c:type:`z_keyexpr_intersection_level_t`. + * + * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** + */ +typedef enum z_keyexpr_intersection_level_t { + Z_KEYEXPR_INTERSECTION_LEVEL_T_DISJOINT = 0, + Z_KEYEXPR_INTERSECTION_LEVEL_T_INTERSECTS = 1, + Z_KEYEXPR_INTERSECTION_LEVEL_T_INCLUDES = 2, + Z_KEYEXPR_INTERSECTION_LEVEL_T_EQUALS = 3, +} z_keyexpr_intersection_level_t; + +/** + * The priority of zenoh messages. + * + * - **REAL_TIME** + * - **INTERACTIVE_HIGH** + * - **INTERACTIVE_LOW** + * - **DATA_HIGH** + * - **DATA** + * - **DATA_LOW** + * - **BACKGROUND** + */ +typedef enum z_priority_t { + Z_PRIORITY_T_REAL_TIME = 1, + Z_PRIORITY_T_INTERACTIVE_HIGH = 2, + Z_PRIORITY_T_INTERACTIVE_LOW = 3, + Z_PRIORITY_T_DATA_HIGH = 4, + Z_PRIORITY_T_DATA = 5, + Z_PRIORITY_T_DATA_LOW = 6, + Z_PRIORITY_T_BACKGROUND = 7, +} z_priority_t; + +/** + * The Queryables that should be target of a :c:func:`z_get`. + * + * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. + * - **ALL_COMPLETE**: All complete queryables. + * - **ALL**: All matching queryables. + */ +typedef enum z_query_target_t { + Z_QUERY_TARGET_T_BEST_MATCHING, + Z_QUERY_TARGET_T_ALL, + Z_QUERY_TARGET_T_ALL_COMPLETE, +} z_query_target_t; + typedef enum z_sample_kind_t { Z_SAMPLE_KIND_T_PUT = 0, Z_SAMPLE_KIND_T_DELETE = 1, @@ -26,13 +111,41 @@ typedef enum zcu_reply_keyexpr_t { * * To minimize copies and reallocations, Zenoh may provide you data in split buffers. */ -typedef struct ALIGN(8) z_owned_buffer_t { +typedef struct ALIGN(8) z_owned_bytes_t { uint8_t _0[40]; -} z_owned_buffer_t; +} z_owned_bytes_t; -typedef struct ALIGN(8) z_buffer_t { +typedef int8_t ZCError; + +/** + * A loaned payload. + */ +typedef struct ALIGN(8) z_bytes_t { uint8_t _0[8]; -} z_buffer_t; +} z_bytes_t; + +typedef struct z_owned_slice_t { + uint8_t *start; + size_t len; +} z_owned_slice_t; + +/** + * A map of maybe-owned vector of bytes to maybe-owned vector of bytes. + * + * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher + */ +typedef struct ALIGN(8) z_owned_slice_map_t { + uint8_t _0[48]; +} z_owned_slice_map_t; + +/** + * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` + * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with + * `z_check` and `z_str_check` correspondently + */ +typedef struct z_owned_str_t { + char *_cstr; +} z_owned_str_t; /** * A contiguous view of bytes owned by some other entity. @@ -40,111 +153,645 @@ typedef struct ALIGN(8) z_buffer_t { * `start` being `null` is considered a gravestone value, * and empty slices are represented using a possibly dangling pointer for `start`. */ -typedef struct z_bytes_t { +typedef struct z_slice_t { const uint8_t *start; size_t len; -} z_bytes_t; +} z_slice_t; -typedef struct z_owned_bytes_t { - uint8_t *start; - size_t len; -} z_owned_bytes_t; +typedef struct ALIGN(8) z_slice_map_t { + uint8_t _0[8]; +} z_slice_map_t; + +/** + * A reader for payload data. + */ +typedef struct ALIGN(8) z_owned_bytes_t_reader_t { + uint8_t _0[24]; +} z_owned_bytes_t_reader_t; + +typedef struct ALIGN(8) z_bytes_reader_t { + uint8_t _0[8]; +} z_bytes_reader_t; +/** + * An owned zenoh session. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ typedef struct ALIGN(8) z_owned_session_t { uint8_t _0[8]; } z_owned_session_t; -typedef struct ALIGN(8) z_owned_config_t { - uint8_t _0[8]; -} z_owned_config_t; +/** + * Represents a Zenoh ID. + * + * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. + */ +typedef struct ALIGN(1) z_id_t { + uint8_t _0[16]; +} z_id_t; -typedef struct ALIGN(8) z_config_t { +/** + * An owned array of owned, zenoh allocated, NULL terminated strings. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct z_owned_str_array_t { + char **val; + size_t len; +} z_owned_str_array_t; + +/** + * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. + * + * Members: + * unsigned int whatami: The kind of zenoh entity. + * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). + * z_owned_str_array_t locators: The locators of the scouted entity. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct z_owned_hello_t { + unsigned int _whatami; + struct z_id_t _pid; + struct z_owned_str_array_t _locators; +} z_owned_hello_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_hello_t { + void *context; + void (*call)(struct z_owned_hello_t*, void*); + void (*drop)(void*); +} z_owned_closure_hello_t; + +/** + * + * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. + * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. + */ +typedef struct ALIGN(8) z_owned_query_t { + uint8_t _0[16]; +} z_owned_query_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_owned_query_t { + void *context; + void (*call)(struct z_owned_query_t*, void *context); + void (*drop)(void*); +} z_owned_closure_owned_query_t; + +typedef struct ALIGN(8) z_query_t { uint8_t _0[8]; -} z_config_t; +} z_query_t; -typedef struct ALIGN(8) z_owned_encoding_t { - uint8_t _0[48]; -} z_owned_encoding_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_query_t { + void *context; + void (*call)(struct z_query_t, void *context); + void (*drop)(void*); +} z_owned_closure_query_t; -typedef struct ALIGN(8) z_encoding_t { +typedef struct ALIGN(8) z_reply_t { uint8_t _0[8]; -} z_encoding_t; +} z_reply_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_reply_t { + void *context; + void (*call)(struct z_reply_t, void*); + void (*drop)(void*); +} z_owned_closure_reply_t; typedef struct ALIGN(8) z_sample_t { uint8_t _0[8]; } z_sample_t; -typedef struct ALIGN(8) z_keyexpr_t { - uint8_t _0[8]; -} z_keyexpr_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_sample_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_sample_t { + void *context; + void (*call)(const struct z_sample_t*, void *context); + void (*drop)(void*); +} z_owned_closure_sample_t; /** - * An owned payload, backed by a reference counted owner. + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. * - * The `payload` field may be modified, and Zenoh will take the new values into account. + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. */ -typedef struct z_owned_buffer_t zc_owned_payload_t; +typedef struct z_owned_closure_zid_t { + void *context; + void (*call)(const struct z_id_t*, void*); + void (*drop)(void*); +} z_owned_closure_zid_t; -typedef struct z_buffer_t zc_payload_t; +/** + * An owned zenoh configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_config_t { + uint8_t _0[8]; +} z_owned_config_t; -typedef struct ALIGN(1) z_id_t { - uint8_t _0[16]; -} z_id_t; +/** + * A loaned zenoh configuration. + */ +typedef struct ALIGN(8) z_config_t { + uint8_t _0[8]; +} z_config_t; -typedef struct z_timestamp_t { - uint64_t time; - struct z_id_t id; -} z_timestamp_t; +/** + * A zenoh-allocated key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` + * for wire and computation efficiency. + * + * A `key expression `_ can be either: + * - A plain string expression. + * - A pure numerical id. + * - The combination of a numerical prefix and a string suffix. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_keyexpr_t { + uint8_t _0[32]; +} z_owned_keyexpr_t; typedef struct ALIGN(8) z_session_t { uint8_t _0[8]; } z_session_t; /** - * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` - * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with - * `z_check` and `z_str_check` correspondently + * A loaned key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, + * both for local processing and network-wise. */ -typedef struct z_owned_str_t { - char *_cstr; -} z_owned_str_t; +typedef struct ALIGN(8) z_keyexpr_t { + uint8_t _0[8]; +} z_keyexpr_t; /** - * A reader for payload data. + * Options passed to the :c:func:`z_declare_publisher` function. + * + * Members: + * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. + * z_priority_t priority: The priority of messages from this publisher. */ -typedef struct ALIGN(8) zc_owned_payload_reader { - uint8_t _0[24]; -} zc_owned_payload_reader; +typedef struct z_publisher_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_publisher_options_t; -typedef struct ALIGN(8) zc_payload_reader { - uint8_t _0[8]; -} zc_payload_reader; +/** + * An owned zenoh publisher. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_publisher_t { + uint8_t _0[56]; +} z_owned_publisher_t; /** - * An owned sample. + * Options passed to the :c:func:`z_declare_queryable` function. * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + * Members: + * bool complete: The completeness of the Queryable. */ -typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[240]; -} zc_owned_sample_t; +typedef struct z_queryable_options_t { + bool complete; +} z_queryable_options_t; -extern const unsigned int Z_ROUTER; +/** + * An owned zenoh queryable. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_queryable_t { + uint8_t _0[32]; +} z_owned_queryable_t; -extern const unsigned int Z_PEER; +typedef struct ALIGN(8) z_owned_encoding_t { + uint8_t _0[48]; +} z_owned_encoding_t; -extern const unsigned int Z_CLIENT; +/** + * The encoding of a payload, in a MIME-like format. + * + * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + */ +typedef struct ALIGN(8) z_encoding_t { + uint8_t _0[8]; +} z_encoding_t; -extern const char *Z_CONFIG_MODE_KEY; +/** + * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. + */ +typedef struct z_query_consolidation_t { + enum z_consolidation_mode_t mode; +} z_query_consolidation_t; -extern const char *Z_CONFIG_CONNECT_KEY; +/** + * Options passed to the :c:func:`z_get` function. + * + * Members: + * z_query_target_t target: The Queryables that should be target of the query. + * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. + * z_value_t value: An optional value to attach to the query. + * z_bytes_t attachment: The attachment to attach to the query. + * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. + */ +typedef struct z_get_options_t { + enum z_query_target_t target; + struct z_query_consolidation_t consolidation; + struct z_owned_bytes_t *payload; + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; + uint64_t timeout_ms; +} z_get_options_t; + +/** + * An borrowed array of borrowed, zenoh allocated, NULL terminated strings. + */ +typedef struct z_str_array_t { + size_t len; + const char *const *val; +} z_str_array_t; -extern const char *Z_CONFIG_LISTEN_KEY; +/** + * A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. + * + * Members: + * unsigned int whatami: The kind of zenoh entity. + * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). + * z_owned_str_array_t locators: The locators of the scouted entity. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct z_hello_t { + unsigned int whatami; + struct z_id_t pid; + struct z_str_array_t locators; +} z_hello_t; -extern const char *Z_CONFIG_USER_KEY; +typedef struct ALIGN(8) z_publisher_t { + uint8_t _0[8]; +} z_publisher_t; -extern const char *Z_CONFIG_PASSWORD_KEY; +/** + * Represents the set of options that can be applied to the delete operation by a previously declared publisher, + * whenever issued via :c:func:`z_publisher_delete`. + */ +typedef struct z_publisher_delete_options_t { + uint8_t __dummy; +} z_publisher_delete_options_t; + +/** + * Options passed to the :c:func:`z_publisher_put` function. + * + * Members: + * z_owned_encoding_t encoding: The encoding of the payload. + * z_owned_bytes_t attachment: The attachment to attach to the publication. + */ +typedef struct z_publisher_put_options_t { + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; +} z_publisher_put_options_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * - `this` is a pointer to an arbitrary state. + * - `call` is the typical callback function. `this` will be passed as its last argument. + * - `drop` allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * We guarantee that: + * - `call` will never be called once `drop` has started. + * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_query_channel_closure_t { + void *context; + bool (*call)(struct z_owned_query_t*, void*); + void (*drop)(void*); +} z_owned_query_channel_closure_t; + +/** + * A pair of closures + */ +typedef struct z_owned_query_channel_t { + struct z_owned_closure_query_t send; + struct z_owned_query_channel_closure_t recv; +} z_owned_query_channel_t; + +/** + * Represents the set of options that can be applied to a query reply, + * sent via :c:func:`z_query_reply`. + * + * Members: + * z_owned_encoding_t encoding: The encoding of the payload. + * z_owned_bytes_t attachment: The attachment to this reply. + */ +typedef struct z_query_reply_options_t { + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; +} z_query_reply_options_t; + +typedef struct ALIGN(8) z_value_t { + uint8_t _0[8]; +} z_value_t; + +/** + * An owned reply to a :c:func:`z_get`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_reply_t { + uint8_t _0[256]; +} z_owned_reply_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * - `this` is a pointer to an arbitrary state. + * - `call` is the typical callback function. `this` will be passed as its last argument. + * - `drop` allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * We guarantee that: + * - `call` will never be called once `drop` has started. + * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_reply_channel_closure_t { + void *context; + bool (*call)(struct z_owned_reply_t*, void*); + void (*drop)(void*); +} z_owned_reply_channel_closure_t; + +/** + * A pair of closures, the `send` one accepting + */ +typedef struct z_owned_reply_channel_t { + struct z_owned_closure_reply_t send; + struct z_owned_reply_channel_closure_t recv; +} z_owned_reply_channel_t; + +typedef struct ALIGN(8) z_timestamp_t { + uint8_t _0[24]; +} z_timestamp_t; + +typedef struct z_owned_scouting_config_t { + struct z_owned_config_t _config; + unsigned long zc_timeout_ms; + uint8_t zc_what; +} z_owned_scouting_config_t; + +/** + * The body of a loop over a z_slice_map's key-value pairs. + * + * `key` and `value` are loaned to the body for the duration of a single call. + * `context` is passed transparently through the iteration driver. + * + * Returning `true` is treated as `continue`. + */ +typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); + +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[240]; +} zc_owned_sample_t; + +/** + * A struct that indicates if there exist Subscribers matching the Publisher's key expression. + * + * Members: + * bool matching: true if there exist Subscribers matching the Publisher's key expression. + */ +typedef struct zcu_matching_status_t { + bool matching; +} zcu_matching_status_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct zcu_owned_closure_matching_status_t { + void *context; + void (*call)(const struct zcu_matching_status_t*, void*); + void (*drop)(void*); +} zcu_owned_closure_matching_status_t; + +/** + * An owned zenoh matching listener. Destroying the matching listener cancels the subscription. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) zcu_owned_matching_listener_t { + uint8_t _0[40]; +} zcu_owned_matching_listener_t; + +#define Z_OK 0 + +#define Z_EINVAL -1 + +#define Z_EPARSE -2 + +#define Z_EIO -3 + +#define Z_ENETWORK -4 + +#define Z_EGENERIC INT8_MIN + +extern const unsigned int Z_ROUTER; + +extern const unsigned int Z_PEER; + +extern const unsigned int Z_CLIENT; + +extern const char *Z_CONFIG_MODE_KEY; + +extern const char *Z_CONFIG_CONNECT_KEY; + +extern const char *Z_CONFIG_LISTEN_KEY; + +extern const char *Z_CONFIG_USER_KEY; + +extern const char *Z_CONFIG_PASSWORD_KEY; extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; @@ -159,205 +806,956 @@ extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; /** - * Returns `true` if the buffer is in a valid state. + * Returns `true` if the payload is in a valid state. + */ +ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); + +/** + * Increments the payload's reference count, returning an owned version of it. + */ +ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_bytes_t *dst); + +/** + * Decodes payload into owned bytes + */ +ZENOHC_API ZCError z_bytes_decode_into_bytes(struct z_bytes_t payload, struct z_owned_slice_t *dst); + +/** + * Decodes payload into bytes map. + */ +ZENOHC_API +ZCError z_bytes_decode_into_bytes_map(struct z_bytes_t payload, + struct z_owned_slice_map_t *dst); + +/** + * Decodes payload into null-terminated string. + */ +ZENOHC_API ZCError z_bytes_decode_into_string(struct z_bytes_t payload, struct z_owned_str_t *dst); + +/** + * Decrements the payload's reference counter, destroying it if applicable. + * + * `this` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ +ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); + +/** + * Encodes byte sequence by aliasing. + */ +ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, struct z_slice_t bytes); + +/** + * Encodes bytes map by copying. + */ +ZENOHC_API +void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, + struct z_slice_map_t bytes_map); + +/** + * Encodes a null-terminated string by aliasing. + */ +ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const char *cstr); + +/** + * Returns total number bytes in the payload. + */ +ZENOHC_API size_t z_bytes_len(struct z_bytes_t payload); + +/** + * Loans the payload, allowing you to call functions that only need a loan of it. + */ +ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); + +/** + * The gravestone value for `z_owned_bytes_t`. + */ +ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); + +ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_t_reader_t *reader); + +ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_t_reader_t *this_); + +ZENOHC_API +struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_t_reader_t *reader); + +/** + * Creates a reader for the specified `payload`. + * + * Returns 0 in case of success, -1 if `payload` is not valid. + */ +ZENOHC_API +void z_bytes_reader_new(struct z_bytes_t payload, + struct z_owned_bytes_t_reader_t *this_); + +ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_t_reader_t *this_); + +/** + * Reads data into specified destination. + * + * Will read at most `len` bytes. + * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. + */ +ZENOHC_API +size_t z_bytes_reader_read(struct z_bytes_reader_t reader, + uint8_t *dest, + size_t len); + +/** + * Sets the `reader` position indicator for the payload to the value pointed to by offset. + * The new position is exactly offset bytes measured from the beginning of the payload if origin is SEEK_SET, + * from the current reader position if origin is SEEK_CUR, and from the end of the payload if origin is SEEK_END. + * Return ​0​ upon success, negative error code otherwise. + */ +ZENOHC_API +ZCError z_bytes_reader_seek(struct z_bytes_reader_t reader, + int64_t offset, + int origin); + +/** + * Returns the read position indicator. + * Returns read position indicator on success or -1L if failure occurs. + */ +ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t reader); + +/** + * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * + * Returns a negative value if an error occured while closing the session. + * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + */ +ZENOHC_API int8_t z_close(struct z_owned_session_t *session); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_hello_call(const struct z_owned_closure_hello_t *closure, + struct z_owned_hello_t *hello); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_hello_drop(struct z_owned_closure_hello_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type + */ +ZENOHC_API struct z_owned_closure_hello_t z_closure_hello_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_owned_query_call(const struct z_owned_closure_owned_query_t *closure, + struct z_owned_query_t *query); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_owned_query_drop(struct z_owned_closure_owned_query_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type + */ +ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_query_call(const struct z_owned_closure_query_t *closure, + struct z_query_t query); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_query_drop(struct z_owned_closure_query_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type + */ +ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, + struct z_reply_t reply); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_reply_drop(struct z_owned_closure_reply_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type + */ +ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, + const struct z_sample_t *sample); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_sample_drop(struct z_owned_closure_sample_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type + */ +ZENOHC_API struct z_owned_closure_sample_t z_closure_sample_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_zid_call(const struct z_owned_closure_zid_t *closure, + const struct z_id_t *sample); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type + */ +ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); + +/** + * Returns ``true`` if `config` is valid. + */ +ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); + +/** + * Constructs a default, zenoh-allocated, client mode configuration. + * If `peer` is not null, it is added to the configuration as remote peer. + */ +ZENOHC_API +ZCError z_config_client(const char *const *peers, + size_t n_peers, + struct z_owned_config_t *this_); + +/** + * Clones the config. + */ +ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); + +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); + +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); + +/** + * Return a new, zenoh-allocated, empty configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +void z_config_new(struct z_owned_config_t *this_); + +/** + * Constructs a null safe-to-drop value of 'z_owned_config_t' type + */ +ZENOHC_API void z_config_null(struct z_owned_config_t *this_); + +/** + * Constructs a default, zenoh-allocated, peer mode configuration. + */ +ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); + +/** + * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. + * + * This numerical id will be used on the network to save bandwidth and + * ease the retrieval of the concerned resource in the routing tables. + */ +ZENOHC_API +ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr); + +/** + * Declares a publisher for the given key expression. + * + * Data can be put and deleted with this publisher with the help of the + * :c:func:`z_publisher_put` and :c:func:`z_publisher_delete` functions. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to publish. + * options: additional options for the publisher. + * + * Returns: + * A :c:type:`z_owned_publisherr_t`. + * + * To check if the publisher decalration succeeded and if the publisher is still valid, + * you may use `z_publisher_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a publisher passing `NULL` for the options: + * + * .. code-block:: C + * + * z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(expr), NULL); + * + * is equivalent to initializing and passing the default publisher options: + * + * .. code-block:: C + * + * z_publisher_options_t opts = z_publisher_options_default(); + * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); + */ +ZENOHC_API +ZCError z_declare_publisher(struct z_session_t session, + struct z_keyexpr_t key_expr, + const struct z_publisher_options_t *options, + struct z_owned_publisher_t *this_); + +/** + * Creates a Queryable for the given key expression. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression the Queryable will reply to. + * callback: The callback function that will be called each time a matching query is received. + * options: Options for the queryable. + * + * Returns: + * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. + */ +ZENOHC_API +ZCError z_declare_queryable(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_query_t *callback, + const struct z_queryable_options_t *options, + struct z_owned_queryable_t *this_); + +/** + * Returns ``true`` if `encoding` is valid. + */ +ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); + +/** + * Constructs a default :c:type:`z_encoding_t`. + */ +ZENOHC_API struct z_encoding_t z_encoding_default(void); + +/** + * Frees `encoding`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); + +/** + * Constructs a specific :c:type:`z_encoding_t`. + */ +ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); + +/** + * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + */ +ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); + +/** + * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type + */ +ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); + +/** + * Query data from the matching queryables in the system. + * Replies are provided through a callback function. + * + * Returns a negative value upon failure. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression matching resources to query. + * parameters: The query's parameters, similar to a url's query segment. + * callback: The callback function that will be called on reception of replies for this query. + * Note that the `reply` parameter of the callback is passed by mutable reference, + * but **will** be dropped once your callback exits to help you avoid memory leaks. + * If you'd rather take ownership, please refer to the documentation of :c:func:`z_reply_null` + * options: additional options for the get. + */ +ZENOHC_API +ZCError z_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + const char *parameters, + struct z_owned_closure_reply_t *callback, + struct z_get_options_t options); + +ZENOHC_API struct z_get_options_t z_get_options_default(void); + +/** + * Returns ``true`` if `hello` is valid. + */ +ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *hello); + +/** + * Frees `hello`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); + +/** + * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. + */ +ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); + +/** + * Constructs a gravestone value for hello, useful to steal one from a callback + */ +ZENOHC_API struct z_owned_hello_t z_hello_null(void); + +/** + * Fetches the Zenoh IDs of all connected peers. + * + * `callback` will be called once for each ID, is guaranteed to never be called concurrently, + * and is guaranteed to be dropped before this function exits. + * + * Retuns 0 on success, negative values on failure + */ +ZENOHC_API +ZCError z_info_peers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); + +/** + * Fetches the Zenoh IDs of all connected routers. + * + * `callback` will be called once for each ID, is guaranteed to never be called concurrently, + * and is guaranteed to be dropped before this function exits. + * + * Retuns 0 on success, negative values on failure. + */ +ZENOHC_API +ZCError z_info_routers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); + +/** + * Returns the local Zenoh ID. + * + * Unless the `session` is invalid, that ID is guaranteed to be non-zero. + * In other words, this function returning an array of 16 zeros means you failed + * to pass it a valid session. + */ +ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API ZCError z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); + +/** + * Returns the key expression's internal string by aliasing it. + * + * Currently exclusive to zenoh-c + */ +ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); + +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * 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 +ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, + char *name); + +/** + * Canonizes the passed string in place, possibly shortening it by modifying `len`. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_canonize(char *start, + size_t *len); + +/** + * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_canonize_null_terminated(char *start); + +/** + * Returns ``true`` if `keyexpr` is valid. + */ +ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); + +/** + * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + * + * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. + * + * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, + * as this would extremely likely cause bugs. + */ +ZENOHC_API +ZCError z_keyexpr_concat(struct z_keyexpr_t left, + const char *right_start, + size_t right_len, + struct z_owned_keyexpr_t *this_); + +/** + * Frees `keyexpr` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); + +/** + * Returns ``0`` if both ``left`` and ``right`` are equal. + */ +ZENOHC_API bool z_keyexpr_equals(struct z_keyexpr_t left, struct z_keyexpr_t right); + +/** + * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set + * defined by ``right``. + */ +ZENOHC_API +bool z_keyexpr_includes(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the + * sets defined by ``left`` and ``right``. + */ +ZENOHC_API +bool z_keyexpr_intersects(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if the passed string is a valid (and canon) key expression. + * Otherwise returns error value + */ +ZENOHC_API ZCError z_keyexpr_is_canon(const char *start, size_t len); + +/** + * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + */ +ZENOHC_API +ZCError z_keyexpr_join(struct z_keyexpr_t left, + struct z_keyexpr_t right, + struct z_owned_keyexpr_t *this_); + +/** + * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + */ +ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); + +/** + * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. + */ +ZENOHC_API ZCError z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); + +/** + * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. + */ +ZENOHC_API +ZCError z_keyexpr_new_autocanonize(const char *name, + struct z_owned_keyexpr_t *this_); + +/** + * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type + */ +ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); + +/** + * Returns the relation between `left` and `right` from `left`'s point of view. + * + * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. + */ +ZENOHC_API +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. + * The user is responsible of droping the returned string using `z_drop` + */ +ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); + +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * + * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. + * - any instance of `**` may only be lead or followed by `/`. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, + const char *name); + +/** + * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + * Config value is always consumed upon function return. + */ +ZENOHC_API +ZCError z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); + +/** + * Returns ``true`` if `pub` is valid. + */ +ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); + +/** + * Sends a `DELETE` message onto the publisher's key expression. + * + * Returns: + * ``0`` in case of success, ``1`` in case of failure. + */ +ZENOHC_API +ZCError z_publisher_delete(struct z_publisher_t publisher, + struct z_publisher_delete_options_t _options); + +/** + * Constructs the default values for the delete operation via a publisher entity. + * + * Returns: + * Returns the constructed :c:type:`z_publisher_delete_options_t`. + */ +ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); + +/** + * Returns the key expression of the publisher + */ +ZENOHC_API struct z_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); + +/** + * Returns a :c:type:`z_publisher_t` loaned from `p`. + */ +ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); + +/** + * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type + */ +ZENOHC_API void z_publisher_null(struct z_owned_publisher_t *this_); + +/** + * Constructs the default value for :c:type:`z_publisher_options_t`. + */ +ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); + +/** + * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` + * + * The payload and all owned options fields are consumed upon function return. + * + * Parameters: + * session: The zenoh session. + * payload: The value to put. + * options: The publisher put options. + * Returns: + * ``0`` in case of success, negative values in case of failure. */ -ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); +ZENOHC_API +ZCError z_publisher_put(struct z_publisher_t publisher, + struct z_owned_bytes_t *payload, + struct z_publisher_put_options_t options); /** - * Increments the buffer's reference count, returning an owned version of the buffer. + * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ -ZENOHC_API void z_buffer_clone(struct z_owned_buffer_t *dst, const struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); /** - * Decrements the buffer's reference counter, destroying it if applicable. + * Gets the attachment to the query by aliasing. * - * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. + * Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. */ -ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_bytes_t z_query_attachment(struct z_query_t query); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +bool z_query_channel_closure_call(const struct z_owned_query_channel_closure_t *closure, + struct z_owned_query_t *query); /** - * Returns total number bytes in the buffer. + * Drops the closure. Droping an uninitialized closure is a no-op. */ -ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); +ZENOHC_API void z_query_channel_closure_drop(struct z_owned_query_channel_closure_t *closure); /** - * Loans the buffer, allowing you to call functions that only need a loan of it. + * Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type */ -ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_owned_query_channel_closure_t z_query_channel_closure_null(void); + +ZENOHC_API void z_query_channel_drop(struct z_owned_query_channel_t *channel); /** - * The gravestone value for `z_owned_buffer_t`. + * Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type */ -ZENOHC_API void z_buffer_null(struct z_owned_buffer_t *this_); +ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); /** - * Returns the `index`th slice of the buffer, aliasing it. + * Returns `false` if `this` is in a gravestone state, `true` otherwise. * - * Out of bounds accesses will return `z_bytes_empty`. + * This function may not be called with the null pointer, but can be called with the gravestone value. */ -ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); +ZENOHC_API +bool z_query_check(const struct z_owned_query_t *query); /** - * Returns the number of slices in the buffer. + * Clones the query, allowing to keep it in an "open" state past the callback's return. * - * If the return value is 0 or 1, then the buffer's data is contiguous in memory. + * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). */ -ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); +ZENOHC_API +void z_query_clone(struct z_owned_query_t *this_, + struct z_query_t query); /** - * Returns ``true`` if `b` is initialized. + * Automatic query consolidation strategy selection. + * + * A query consolidation strategy will automatically be selected depending the query selector. + * If the selector contains time range properties, no consolidation is performed. + * Otherwise the :c:func:`z_query_consolidation_latest` strategy is used. + * + * Returns: + * Returns the constructed :c:type:`z_query_consolidation_t`. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_auto(void); + +/** + * Creates a default :c:type:`z_query_consolidation_t` (consolidation mode AUTO). */ -ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *b); +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_default(void); -ZENOHC_API struct z_owned_bytes_t z_bytes_clone(const struct z_bytes_t *b); +/** + * Latest value consolidation. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_latest(void); /** - * Returns the gravestone value for `z_bytes_t` + * Monotonic consolidation. */ -ZENOHC_API struct z_bytes_t z_bytes_empty(void); +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_monotonic(void); /** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_bytes_empty()` + * Disable consolidation. */ -ZENOHC_API struct z_bytes_t z_bytes_from_str(const char *str); +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); /** - * Returns ``true`` if `b` is initialized. + * Destroys the query, setting `this` to its gravestone value to prevent double-frees. + * + * This function may not be called with the null pointer, but can be called with the gravestone value. */ -ZENOHC_API bool z_bytes_is_initialized(const struct z_bytes_t *b); +ZENOHC_API +void z_query_drop(struct z_owned_query_t *this_); -ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *b); +/** + * Get a query's key by aliasing it. + */ +ZENOHC_API struct z_keyexpr_t z_query_keyexpr(struct z_query_t query); /** - * Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * Aliases the query. * - * `str == NULL` will cause this to return `z_bytes_empty()` + * This function may not be called with the null pointer, but can be called with the gravestone value. */ ZENOHC_API -struct z_bytes_t z_bytes_new(const char *str); +struct z_query_t z_query_loan(const struct z_owned_query_t *this_); /** - * Returns the gravestone value for `z_owned_bytes_t` + * The gravestone value of `z_owned_query_t`. */ -ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); +ZENOHC_API void z_query_null(struct z_owned_query_t *this_); /** - * Constructs a `len` bytes long view starting at `start`. + * Get a query's `value selector `_ by aliasing it. */ -ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); +ZENOHC_API +struct z_slice_t z_query_parameters(struct z_query_t query); /** - * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * Send a reply to a query. * - * Returns a negative value if an error occured while closing the session. - * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + * This function must be called inside of a Queryable callback passing the + * query received as parameters of the callback function. This function can + * be called multiple times to send multiple replies to a query. The reply + * will be considered complete when the Queryable callback returns. + * + * Parameters: + * query: The query to reply to. + * key_expr: The key of this reply. + * payload: The value of this reply. + * options: The options of this reply. + * + * The payload and all owned options fields are consumed upon function return. */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); +ZENOHC_API +ZCError z_query_reply(struct z_query_t query, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_query_reply_options_t options); /** - * Returns ``true`` if `config` is valid. + * Constructs the default value for :c:type:`z_query_reply_options_t`. */ -ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); +ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); /** - * Constructs a default, zenoh-allocated, client mode configuration. - * If `peer` is not null, it is added to the configuration as remote peer. + * Create a default :c:type:`z_query_target_t`. */ -ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); +ZENOHC_API enum z_query_target_t z_query_target_default(void); /** - * Creates a default, zenoh-allocated, configuration. + * Gets a query's `payload value `_ by aliasing it. + * + * **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** + * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. */ -ZENOHC_API struct z_owned_config_t z_config_default(void); +ZENOHC_API +struct z_value_t z_query_value(struct z_query_t query); /** - * Frees `config`, invalidating it for double-drop safety. + * Returns ``true`` if `qable` is valid. */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); +ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); /** - * Returns a :c:type:`z_config_t` loaned from `s`. + * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); +ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); /** - * Return a new, zenoh-allocated, empty configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * Constructs the default value for :c:type:`z_query_reply_options_t`. + */ +ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. */ ZENOHC_API -void z_config_new(struct z_owned_config_t *this_); +bool z_reply_channel_closure_call(const struct z_owned_reply_channel_closure_t *closure, + struct z_owned_reply_t *reply); /** - * Constructs a null safe-to-drop value of 'z_owned_config_t' type + * Drops the closure. Droping an uninitialized closure is a no-op. */ -ZENOHC_API void z_config_null(struct z_owned_config_t *this_); +ZENOHC_API void z_reply_channel_closure_drop(struct z_owned_reply_channel_closure_t *closure); /** - * Constructs a default, zenoh-allocated, peer mode configuration. + * Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type */ -ZENOHC_API struct z_owned_config_t z_config_peer(void); +ZENOHC_API struct z_owned_reply_channel_closure_t z_reply_channel_closure_null(void); + +ZENOHC_API void z_reply_channel_drop(struct z_owned_reply_channel_t *channel); /** - * Returns ``true`` if `encoding` is valid. + * Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type */ -ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); +ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); /** - * Constructs a default :c:type:`z_encoding_t`. + * Returns ``true`` if `reply` is valid. */ -ZENOHC_API struct z_encoding_t z_encoding_default(void); +ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); + +ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, struct z_reply_t reply); /** - * Frees `encoding`, invalidating it for double-drop safety. + * Frees `reply`, invalidating it for double-drop safety. */ -ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); +ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); /** - * Constructs a specific :c:type:`z_encoding_t`. + * Yields the contents of the reply by asserting it indicates a failure. + * + * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. */ -ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); +ZENOHC_API +struct z_value_t z_reply_err(struct z_reply_t reply); /** - * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. + * + * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. */ -ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); +ZENOHC_API +bool z_reply_is_ok(struct z_reply_t reply); /** - * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type + * Returns an invalidated :c:type:`z_owned_reply_t`. + * + * This is useful when you wish to take ownership of a value from a callback to :c:func:`z_get`: + * + * - copy the value of the callback's argument's pointee, + * - overwrite the pointee with this function's return value, + * - you are now responsible for dropping your copy of the reply. */ -ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); +ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); /** - * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + * Yields the contents of the reply by asserting it indicates a success. + * + * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. */ ZENOHC_API -int8_t z_open(struct z_owned_session_t *this_, - struct z_owned_config_t *config); +struct z_sample_t z_reply_ok(struct z_reply_t reply); /** - * The qos with which the sample was received. - * TODO: split to methods (priority, congestion_control, express) - * The sample's attachment. + * Gets sample's attachment. * - * `sample` is aliased by the return value. + * Before calling this function, ensure that `zc_sample_has_attachment` returns true */ -ZENOHC_API z_attachment_t z_sample_attachment(const struct z_sample_t *sample); +ZENOHC_API struct z_bytes_t z_sample_attachment(struct z_sample_t sample); /** * The encoding of the payload. */ ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); +/** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) + * Checks if sample contains an attachment. + */ +ZENOHC_API bool z_sample_has_attachment(struct z_sample_t sample); + /** * The Key Expression of the sample. * @@ -371,24 +1769,45 @@ ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); /** - * Returns the sample's payload after incrementing its internal reference count. + * The sample's data, the return value aliases the sample. * - * Note that other samples may have received the same buffer, meaning that mutating this buffer may - * affect the samples received by other subscribers. */ -ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sample); +ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); /** - * The sample's data, the return value aliases the sample. + * The samples timestamp * - * If you need ownership of the buffer, you may use `z_sample_owned_payload`. + * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. */ -ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API +bool z_sample_timestamp(const struct z_sample_t *sample, + struct z_timestamp_t *timestamp_out); /** - * The samples timestamp + * Scout for routers and/or peers. + * + * Parameters: + * what: A whatami bitmask of zenoh entities kind to scout for. + * config: A set of properties to configure the scouting. + * timeout: The time (in milliseconds) that should be spent scouting. + * + * Returns 0 if successful, negative values upon failure. */ -ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); +ZENOHC_API +ZCError z_scout(struct z_owned_scouting_config_t *config, + struct z_owned_closure_hello_t *callback); + +ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); + +ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); + +ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); + +ZENOHC_API +void z_scouting_config_from(struct z_config_t config, + struct z_owned_scouting_config_t *this_); + +ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); /** * Returns ``true`` if `session` is valid. @@ -413,6 +1832,130 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); */ ZENOHC_API void z_session_null(struct z_owned_session_t *s); +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); + +ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); + +/** + * Returns the gravestone value for `z_slice_t` + */ +ZENOHC_API struct z_slice_t z_slice_empty(void); + +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_slice_empty()` + */ +ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); + +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *b); + +ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); + +/** + * Returns `true` if the map is not in its gravestone state + */ +ZENOHC_API bool z_slice_map_check(const struct z_owned_slice_map_t *map); + +/** + * Destroys the map, resetting `this` to its gravestone value. + * + * This function is double-free safe, passing a pointer to the gravestone value will have no effect. + */ +ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); + +/** + * Returns the value associated with `key`, returning a gravestone value if: + * - `key` is in gravestone state. + */ +ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z_slice_t key); + +/** + * Associates `value` to `key` in the map, aliasing them. + * + * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. + * + * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + */ +ZENOHC_API +ZCError z_slice_map_insert_by_alias(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); + +/** + * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. + * + * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + */ +ZENOHC_API +ZCError z_slice_map_insert_by_copy(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); + +/** + * Returns true if the map is empty, false otherwise. + */ +ZENOHC_API bool z_slice_map_is_empty(struct z_slice_map_t this_); + +ZENOHC_API +void z_slice_map_iterate(const struct z_slice_map_t *this_, + z_slice_map_iter_body_t body, + void *context); + +/** + * Returns number of key-value pairs in the map. + */ +ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); + +/** + * Constructs a new empty map. + */ +ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); + +/** + * Constructs the gravestone value for `z_owned_slice_map_t` + */ +ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); + +/** + * Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_slice_empty()` + */ +ZENOHC_API +struct z_slice_t z_slice_new(const char *str); + +/** + * Returns the gravestone value for `z_owned_slice_t` + */ +ZENOHC_API struct z_owned_slice_t z_slice_null(void); + +/** + * Constructs a `len` bytes long view starting at `start`. + */ +ZENOHC_API struct z_slice_t z_slice_wrap(const uint8_t *start, size_t len); + +/** + * Returns ``true`` if `strs` is valid. + */ +ZENOHC_API bool z_str_array_check(const struct z_owned_str_array_t *strs); + +/** + * Frees `strs` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); + +/** + * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. + */ +ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); + /** * Returns ``true`` if `s` is a valid string */ @@ -433,16 +1976,49 @@ ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); */ ZENOHC_API struct z_owned_str_t z_str_null(void); +ZENOHC_API struct z_id_t z_timestamp_get_id(const struct z_timestamp_t *timestamp); + +ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); + +/** + * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. + * The keyxpr is consumed. + */ +ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); + +/** + * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); + +/** + * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. + * + * Parameters: + * qable: The :c:type:`z_owned_queryable_t` to undeclare. + */ +ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); + /** - * Returns ``true`` if `ts` is a valid timestamp + * 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 bool z_timestamp_check(struct z_timestamp_t ts); +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. */ ZENOHC_API -struct z_owned_config_t zc_config_from_file(const char *path); +ZCError zc_config_from_file(const char *path, + struct z_owned_config_t *this_); /** * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. @@ -450,7 +2026,8 @@ struct z_owned_config_t zc_config_from_file(const char *path); * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). */ ZENOHC_API -struct z_owned_config_t zc_config_from_str(const char *s); +ZCError zc_config_from_str(const char *s, + struct z_owned_config_t *this_); /** * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. @@ -485,83 +2062,93 @@ struct z_owned_str_t zc_config_to_string(struct z_config_t config); ZENOHC_API void zc_init_logger(void); /** - * Returns `false` if `payload` is the gravestone value. - */ -ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); - -/** - * Increments internal payload reference count, returning owned payload. - */ -ZENOHC_API void zc_payload_clone(zc_owned_payload_t *dst, const zc_owned_payload_t *payload); - -/** - * Decodes payload into null-terminated string - */ -ZENOHC_API int8_t zc_payload_decode_into_bytes(zc_payload_t payload, struct z_owned_bytes_t *b); - -/** - * Decodes payload into null-terminated string - */ -ZENOHC_API int8_t zc_payload_decode_into_string(zc_payload_t payload, struct z_owned_str_t *cstr); - -/** - * Decrements `payload`'s backing refcount, releasing the memory if appropriate. - */ -ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); - -/** - * Encodes byte sequence by aliasing. - */ -ZENOHC_API void zc_payload_encode_from_bytes(zc_owned_payload_t *dst, struct z_bytes_t bytes); - -/** - * Encodes a null-terminated string by aliasing. - */ -ZENOHC_API void zc_payload_encode_from_string(zc_owned_payload_t *dst, const char *cstr); - -/** - * Returns total number bytes in the payload. + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. */ -ZENOHC_API size_t zc_payload_len(zc_payload_t payload); +ZENOHC_API +ZCError zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, + const char *name, + size_t len); /** - * Returns a :c:type:`zc_payload_t` loaned from `payload`. + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * 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 zc_payload_t zc_payload_loan(const zc_owned_payload_t *payload); +ZENOHC_API +ZCError zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, + char *name, + size_t *len); /** - * Constructs `zc_owned_payload_t`'s gravestone value. + * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. + * - any instance of ``**`` may only be lead or followed by ``/``. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. */ -ZENOHC_API void zc_payload_null(zc_owned_payload_t *this_); +ZENOHC_API +void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, + const char *start, + size_t len); /** - * Clones the `payload` by incrementing its reference counter. + * Creates a new blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, + * which it will then return; or until the `send` closure is dropped and all queries have been consumed, + * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. */ -ZENOHC_API void zc_payload_rcinc(zc_owned_payload_t *dst, const zc_owned_payload_t *payload); +ZENOHC_API +struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); /** - * Creates a reader for the specified `payload`. + * Creates a new non-blocking fifo channel, returned as a pair of closures. * - * Returns 0 in case of success, -1 if `payload` is not valid. + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, + * which it will then return; or until the `send` closure is dropped and all queries have been consumed, + * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. */ -ZENOHC_API void zc_payload_reader_init(struct zc_owned_payload_reader *this_, zc_payload_t payload); +ZENOHC_API +struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); /** - * Reads data into specified destination. + * Creates a new blocking fifo channel, returned as a pair of closures. * - * Will read at most `len` bytes. - * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, + * which it will then return; or until the `send` closure is dropped and all replies have been consumed, + * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. */ ZENOHC_API -size_t zc_payload_reader_read(struct zc_payload_reader reader, - uint8_t *dest, - size_t len); +struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); /** - * Returns number of the remaining bytes in the payload + * Creates a new non-blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. * + * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, + * which it will then return; or until the `send` closure is dropped and all replies have been consumed, + * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. */ -ZENOHC_API size_t zc_payload_reader_remaining(struct zc_payload_reader reader); +ZENOHC_API +struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); /** * Returns `true` if `sample` is valid. @@ -598,6 +2185,32 @@ ZENOHC_API int8_t zc_session_rcinc(struct z_owned_session_t *dst, const struct z_owned_session_t *src); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void zcu_closure_matching_status_call(const struct zcu_owned_closure_matching_status_t *closure, + const struct zcu_matching_status_t *sample); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API +void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t *closure); + +/** + * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type + */ +ZENOHC_API struct zcu_owned_closure_matching_status_t zcu_closure_matching_status_null(void); + ZENOHC_API enum zcu_locality_t zcu_locality_default(void); +/** + * Register callback for notifying subscribers matching. + */ +ZENOHC_API +ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, + struct zcu_owned_closure_matching_status_t *callback, + struct zcu_owned_matching_listener_t *this_); + ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 815b2df85..a2d0582b1 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -14,7 +14,7 @@ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ - zc_owned_payload_t : zc_payload_loan, \ + z_owned_bytes_t : z_bytes_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ )(&x) @@ -42,8 +42,8 @@ z_owned_query_channel_closure_t * : z_query_channel_closure_drop, \ z_owned_reply_channel_t * : z_reply_channel_drop, \ z_owned_query_channel_t * : z_query_channel_drop, \ - z_owned_bytes_map_t * : z_bytes_map_drop, \ - zc_owned_payload_t * : zc_payload_drop, \ + z_owned_bytes_map_t * : z_slice_map_drop, \ + z_owned_bytes_t * : z_bytes_drop, \ zc_owned_shmbuf_t * : zc_shmbuf_drop, \ zc_owned_shm_manager_t * : zc_shm_manager_drop, \ zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ @@ -73,9 +73,9 @@ zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ z_owned_reply_channel_t * : z_reply_channel_null, \ - z_owned_bytes_map_t * : z_bytes_map_null, \ - zc_owned_payload_t * : zc_payload_null, \ - z_attachment_t * : z_attachment_null, \ + z_owned_bytes_map_t * : z_slice_map_null, \ + z_owned_bytes_t * : z_bytes_null, \ + z_bytes_t * : z_attachment_null, \ zc_owned_shmbuf_t * : zc_shmbuf_null, \ zc_owned_shm_manager_t * : zc_shm_manager_null, \ ze_owned_publication_cache_t * : ze_publication_cache_null, \ @@ -89,7 +89,7 @@ z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ - z_owned_bytes_t : z_bytes_check, \ + z_owned_bytes_t : z_slice_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -98,9 +98,9 @@ z_owned_hello_t : z_hello_check, \ z_owned_query_t : z_query_check, \ z_owned_str_t : z_str_check, \ - z_owned_bytes_map_t : z_bytes_map_check, \ - zc_owned_payload_t: zc_payload_check, \ - z_attachment_t : z_attachment_check, \ + z_owned_bytes_map_t : z_slice_map_check, \ + z_owned_bytes_t: z_bytes_check, \ + z_bytes_t : z_attachment_check, \ zc_owned_shmbuf_t : zc_shmbuf_check, \ zc_owned_shm_manager_t : zc_shm_manager_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ @@ -142,7 +142,7 @@ template<> struct zenoh_loan_type{ typedef z_pull_sub template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; -template<> struct zenoh_loan_type{ typedef zc_payload_t type; }; +template<> struct zenoh_loan_type{ typedef z_bytes_t type; }; template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } @@ -155,7 +155,7 @@ template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_en template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } -template<> inline zc_payload_t z_loan(const zc_owned_payload& x) { return zc_payload_loan(&x); } +template<> inline z_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } template struct zenoh_drop_type { typedef T type; }; @@ -174,8 +174,8 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -204,8 +204,8 @@ template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } -template<> inline void z_drop(zc_owned_payload* v) { zc_payload_drop(v); } -template<> inline void z_drop(zc_owned_payload_t* v) { zc_payload_drop(v); } +template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } +template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } template<> inline void z_drop(z_owned_closure_sample_t* v) { z_closure_sample_drop(v); } @@ -216,7 +216,7 @@ template<> inline void z_drop(z_owned_closure_zid_t* v) { z_closure_zid_drop(v); template<> inline void z_drop(zcu_owned_closure_matching_status_t* v) { zcu_closure_matching_status_drop(v); } template<> inline void z_drop(z_owned_reply_channel_closure_t* v) { z_reply_channel_closure_drop(v); } template<> inline void z_drop(z_owned_reply_channel_t* v) { z_reply_channel_drop(v); } -template<> inline void z_drop(z_owned_bytes_map_t* v) { z_bytes_map_drop(v); } +template<> inline void z_drop(z_owned_bytes_map_t* v) { z_slice_map_drop(v); } template<> inline void z_drop(zc_owned_liveliness_token_t* v) { zc_liveliness_undeclare_token(v); } template<> inline int8_t z_drop(ze_owned_publication_cache_t* v) { return ze_undeclare_publication_cache(v); } template<> inline int8_t z_drop(ze_owned_querying_subscriber_t* v) { return ze_undeclare_querying_subscriber(v); } @@ -234,8 +234,8 @@ inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } -inline void z_null(zc_owned_payload& v) { v = zc_payload_null(); } -inline void z_null(zc_owned_payload_t& v) { v = zc_payload_null(); } +inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } +inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } inline void z_null(z_owned_closure_sample_t& v) { v = z_closure_sample_null(); } @@ -246,7 +246,7 @@ inline void z_null(z_owned_closure_zid_t& v) { v = z_closure_zid_null(); } inline void z_null(zcu_owned_closure_matching_status_t& v) { v = zcu_closure_matching_status_null(); } inline void z_null(z_owned_reply_channel_closure_t& v) { v = z_reply_channel_closure_null(); } inline void z_null(z_owned_reply_channel_t& v) { v = z_reply_channel_null(); } -inline void z_null(z_owned_bytes_map_t& v) { v = z_bytes_map_null(); } +inline void z_null(z_owned_bytes_map_t& v) { v = z_slice_map_null(); } inline void z_null(zc_owned_liveliness_token_t& v) { v = zc_liveliness_token_null(); } inline void z_null(ze_owned_publication_cache_t& v) { v = ze_publication_cache_null(); } inline void z_null(ze_owned_querying_subscriber_t& v) { v = ze_querying_subscriber_null(); } @@ -257,8 +257,8 @@ inline bool z_check(const z_owned_keyexpr_t& v) { return z_keyexpr_check(&v); } inline bool z_check(const z_keyexpr_t& v) { return z_keyexpr_is_initialized(&v); } inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } +inline bool z_check(const z_owned_bytes_t& v) { return z_slice_check(&v); } inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } -inline bool z_check(const zc_owned_payload_t& v) { return zc_payload_check(&v); } inline bool z_check(const zc_owned_shmbuf_t& v) { return zc_shmbuf_check(&v); } inline bool z_check(const zc_owned_shm_manager_t& v) { return zc_shm_manager_check(&v); } inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } @@ -269,9 +269,9 @@ inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } -inline bool z_check(const zc_owned_payload& v) { return zc_payload_check(&v); } -inline bool z_check(const z_owned_bytes_map_t& v) { return z_bytes_map_check(&v); } -inline bool z_check(const z_attachment_t& v) { return z_attachment_check(&v); } +inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } +inline bool z_check(const z_owned_bytes_map_t& v) { return z_slice_map_check(&v); } +inline bool z_check(constz_bytes_t& v) { return z_attachment_check(&v); } inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } inline bool z_check(const ze_owned_publication_cache_t& v) { return ze_publication_cache_check(&v); } inline bool z_check(const ze_owned_querying_subscriber_t& v) { return ze_querying_subscriber_check(&v); } diff --git a/src/attachment.rs b/src/attachment.rs deleted file mode 100644 index 045596c47..000000000 --- a/src/attachment.rs +++ /dev/null @@ -1,416 +0,0 @@ -use std::{borrow::Cow, cell::UnsafeCell, collections::HashMap}; - -use libc::c_void; - -use crate::{impl_guarded_transmute, z_bytes_empty, z_bytes_t}; - -use zenoh::sample::{Attachment, AttachmentBuilder}; - -/// The body of a loop over an attachment's key-value pairs. -/// -/// `key` and `value` are loaned to the body for the duration of a single call. -/// `context` is passed transparently through the iteration driver. -/// -/// Returning `0` is treated as `continue`. -/// Returning any other value is treated as `break`. -#[allow(non_camel_case_types)] -pub type z_attachment_iter_body_t = - extern "C" fn(key: z_bytes_t, value: z_bytes_t, context: *mut c_void) -> i8; - -/// The driver of a loop over an attachment's key-value pairs. -/// -/// This function is expected to call `loop_body` once for each key-value pair -/// within `iterator`, passing `context`, and returning any non-zero value immediately (breaking iteration). -#[allow(non_camel_case_types)] -pub type z_attachment_iter_driver_t = Option< - extern "C" fn( - iterator: *const c_void, - loop_body: z_attachment_iter_body_t, - context: *mut c_void, - ) -> i8, ->; - -/// A iteration based map of byte slice to byte slice. -/// -/// `iteration_driver == NULL` marks the gravestone value, as this type is often optional. -/// Users are encouraged to use `z_attachment_null` and `z_attachment_check` to interact. -#[repr(C)] -#[derive(Clone, Copy)] -pub struct z_attachment_t { - pub data: *const c_void, - pub iteration_driver: z_attachment_iter_driver_t, -} - -/// Returns the gravestone value for `z_attachment_t`. -#[no_mangle] -pub extern "C" fn z_attachment_check(this: &z_attachment_t) -> bool { - this.iteration_driver.is_some() -} - -/// Returns the gravestone value for `z_attachment_t`. -#[no_mangle] -pub extern "C" fn z_attachment_null() -> z_attachment_t { - z_attachment_t { - data: core::ptr::null_mut(), - iteration_driver: None, - } -} - -/// Iterate over `this`'s key-value pairs, breaking if `body` returns a non-zero -/// value for a key-value pair, and returning the latest return value. -/// -/// `context` is passed to `body` to allow stateful closures. -/// -/// This function takes no ownership whatsoever. -#[no_mangle] -pub extern "C" fn z_attachment_iterate( - this: z_attachment_t, - body: z_attachment_iter_body_t, - context: *mut c_void, -) -> i8 { - if let Some(driver) = this.iteration_driver { - return driver(this.data, body, context); - } - log::error!("Invalid iteration_driver"); - i8::MIN -} - -/// Returns the value associated with the key. -#[no_mangle] -pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_bytes_t { - struct attachment_get_iterator_context { - key: z_bytes_t, - value: z_bytes_t, - } - - extern "C" fn attachment_get_iterator( - key: z_bytes_t, - value: z_bytes_t, - context: *mut c_void, - ) -> i8 { - unsafe { - let context = &mut *(context as *mut attachment_get_iterator_context); - if context.key.as_slice() == key.as_slice() { - context.value = value; - 1 - } else { - 0 - } - } - } - - let mut context = attachment_get_iterator_context { - key, - value: z_bytes_empty(), - }; - - if this.iteration_driver.map_or(false, |iteration_driver| { - (iteration_driver)( - this.data, - attachment_get_iterator, - &mut context as *mut _ as *mut c_void, - ) != 0 - }) { - context.value - } else { - z_bytes_empty() - } -} - -fn _z_attachment_len(this: z_attachment_t, check_if_non_empty: bool) -> usize { - match this.iteration_driver.as_ref() { - None => 0, - Some(iteration_driver) => { - struct count_context_t { - count: usize, - stop_if_not_empty: bool, - } - - extern "C" fn attachment_count_iterator( - _key: z_bytes_t, - _value: z_bytes_t, - context: *mut c_void, - ) -> i8 { - unsafe { - let context = &mut *(context as *mut count_context_t); - context.count += 1; - if context.stop_if_not_empty { - 1 - } else { - 0 - } - } - } - let mut count_context = count_context_t { - count: 0, - stop_if_not_empty: check_if_non_empty, - }; - (iteration_driver)( - this.data, - attachment_count_iterator, - &mut count_context as *mut _ as *mut c_void, - ); - count_context.count - } - } -} - -/// Returns number of key-value pairs for `z_attachment_t`. -/// -/// Does so by iterating over all existing key-value pairs. -#[no_mangle] -pub extern "C" fn z_attachment_len(this: z_attachment_t) -> usize { - _z_attachment_len(this, false) -} - -/// Returns true if `z_attachment_t` contains no key-value pairs, false otherwise. -#[no_mangle] -pub extern "C" fn z_attachment_is_empty(this: z_attachment_t) -> bool { - _z_attachment_len(this, true) == 0 -} - -/// A map of maybe-owned vector of bytes to owned vector of bytes. -/// -/// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher -#[repr(C)] -pub struct z_owned_bytes_map_t { - _0: [u64; 2], - _1: [usize; 4], -} - -impl_guarded_transmute!(noderefs - Option, Cow<'static, [u8]>>>, - z_owned_bytes_map_t -); - -impl core::ops::Deref for z_owned_bytes_map_t { - type Target = UnsafeCell, Cow<'static, [u8]>>>>; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} - -/// Constructs a new map. -#[no_mangle] -pub extern "C" fn z_bytes_map_new() -> z_owned_bytes_map_t { - unsafe { core::mem::transmute(Some(HashMap::, Cow<[u8]>>::new())) } -} - -/// Constructs the gravestone value for `z_owned_bytes_map_t` -#[no_mangle] -pub extern "C" fn z_bytes_map_null() -> z_owned_bytes_map_t { - unsafe { core::mem::transmute(None::, Cow<[u8]>>>) } -} - -/// Returns `true` if the map is not in its gravestone state -#[no_mangle] -pub extern "C" fn z_bytes_map_check(this: &z_owned_bytes_map_t) -> bool { - unsafe { &*this.get() }.is_some() -} -/// Destroys the map, resetting `this` to its gravestone value. -/// -/// This function is double-free safe, passing a pointer to the gravestone value will have no effect. -#[no_mangle] -pub extern "C" fn z_bytes_map_drop(this: &mut z_owned_bytes_map_t) { - let this = unsafe { &mut *this.get() }; - this.take(); -} - -/// Returns number of key-value pairs in the map. -#[no_mangle] -pub extern "C" fn z_bytes_map_len(this: &mut z_owned_bytes_map_t) -> usize { - let this = unsafe { &*this.get() }; - this.as_ref().map(|m| m.len()).unwrap_or(0) -} - -/// Returns true if the map is empty, false otherwise. -#[no_mangle] -pub extern "C" fn z_bytes_map_is_empty(this: &mut z_owned_bytes_map_t) -> bool { - let this = unsafe { &*this.get() }; - this.as_ref().map(|m| m.is_empty()).unwrap_or(true) -} - -/// Returns the value associated with `key`, returning a gravestone value if: -/// - `this` or `key` is in gravestone state. -/// - `this` has no value associated to `key` -#[no_mangle] -pub extern "C" fn z_bytes_map_get(this: &z_owned_bytes_map_t, key: z_bytes_t) -> z_bytes_t { - let this = unsafe { &*this.get() }; - let (Some(this), Some(key)) = (this.as_ref(), key.as_slice()) else { - return z_bytes_empty(); - }; - if let Some(value) = this.get(key) { - value.as_ref().into() - } else { - z_bytes_empty() - } -} - -/// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. -/// -/// Calling this with `NULL` or the gravestone value is undefined behaviour. -#[no_mangle] -pub extern "C" fn z_bytes_map_insert_by_copy( - this: &z_owned_bytes_map_t, - key: z_bytes_t, - value: z_bytes_t, -) { - let this = unsafe { &mut *this.get() }; - if let (Some(this), Some(key), Some(value)) = (this.as_mut(), key.as_slice(), value.as_slice()) - { - this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); - } -} - -/// Associates `value` to `key` in the map, aliasing them. -/// -/// Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. -/// -/// Calling this with `NULL` or the gravestone value is undefined behaviour. -#[no_mangle] -pub extern "C" fn z_bytes_map_insert_by_alias( - this: &z_owned_bytes_map_t, - key: z_bytes_t, - value: z_bytes_t, -) { - let this = unsafe { &mut *this.get() }; - if let (Some(this), Some(key), Some(value)) = (this.as_mut(), key.as_slice(), value.as_slice()) - { - unsafe { - this.insert( - Cow::Borrowed(core::mem::transmute(key)), - Cow::Borrowed(core::mem::transmute(value)), - ) - }; - } -} - -/// Iterates over the key-value pairs in the map. -/// -/// `body` will be called once per pair, with `ctx` as its last argument. -/// If `body` returns a non-zero value, the iteration will stop immediately and the value will be returned. -/// Otherwise, this will return 0 once all pairs have been visited. -/// `body` is not given ownership of the key nor value, which alias the pairs in the map. -/// It is safe to keep these aliases until existing keys are modified/removed, or the map is destroyed. -/// Note that this map is unordered. -/// -/// Calling this with `NULL` or the gravestone value is undefined behaviour. -#[no_mangle] -pub extern "C" fn z_bytes_map_iter( - this: &z_owned_bytes_map_t, - body: z_attachment_iter_body_t, - ctx: *mut c_void, -) -> i8 { - let this = unsafe { &*this.get() }; - if let Some(this) = this.as_ref() { - for (key, value) in this.iter() { - let result = body(key.as_ref().into(), value.as_ref().into(), ctx); - if result != 0 { - return result; - } - } - } - 0 -} - -const Z_BYTES_MAP_ITERATION_DRIVER: z_attachment_iter_driver_t = - Some(unsafe { core::mem::transmute(z_bytes_map_iter as extern "C" fn(_, _, _) -> i8) }); - -pub(crate) extern "C" fn insert_in_attachment_builder( - key: z_bytes_t, - value: z_bytes_t, - ctx: *mut c_void, -) -> i8 { - let attachment_builder_ref: &mut AttachmentBuilder = - unsafe { &mut *(ctx as *mut AttachmentBuilder) }; - attachment_builder_ref.insert(key.as_slice().unwrap(), value.as_slice().unwrap()); - 0 -} - -pub(crate) extern "C" fn attachment_iteration_driver( - this: *const c_void, - body: z_attachment_iter_body_t, - ctx: *mut c_void, -) -> i8 { - let attachments_ref: &Attachment = unsafe { &*(this as *mut Attachment) }; - for (key, value) in attachments_ref.iter() { - let result = body(key.as_ref().into(), value.as_ref().into(), ctx); - if result != 0 { - return result; - } - } - 0 -} - -/// Aliases `this` into a generic `z_attachment_t`, allowing it to be passed to corresponding APIs. -#[no_mangle] -pub extern "C" fn z_bytes_map_as_attachment(this: &z_owned_bytes_map_t) -> z_attachment_t { - if z_bytes_map_check(this) { - z_attachment_t { - data: this as *const z_owned_bytes_map_t as *mut _, - iteration_driver: Z_BYTES_MAP_ITERATION_DRIVER, - } - } else { - z_attachment_t { - data: core::ptr::null_mut(), - iteration_driver: None, - } - } -} - -extern "C" fn bytes_map_from_attachment_iterator( - key: z_bytes_t, - value: z_bytes_t, - ctx: *mut c_void, -) -> i8 { - let map = unsafe { &*ctx.cast::() }; - z_bytes_map_insert_by_copy(map, key, value); - 0 -} -extern "C" fn bytes_map_from_attachment_iterator_by_alias( - key: z_bytes_t, - value: z_bytes_t, - ctx: *mut c_void, -) -> i8 { - let map = unsafe { &*ctx.cast::() }; - z_bytes_map_insert_by_alias(map, key, value); - 0 -} - -/// Constructs a map from the provided attachment, copying keys and values. -/// -/// If `this` is at gravestone value, the returned value will also be at gravestone value. -#[no_mangle] -pub extern "C" fn z_bytes_map_from_attachment(this: z_attachment_t) -> z_owned_bytes_map_t { - if z_attachment_check(&this) { - let mut map = z_bytes_map_new(); - z_attachment_iterate( - this, - bytes_map_from_attachment_iterator, - &mut map as *mut _ as *mut _, - ); - map - } else { - z_bytes_map_null() - } -} - -/// Constructs a map from the provided attachment, aliasing the attachment's keys and values. -/// -/// If `this` is at gravestone value, the returned value will also be at gravestone value. -#[no_mangle] -pub extern "C" fn z_bytes_map_from_attachment_aliasing( - this: z_attachment_t, -) -> z_owned_bytes_map_t { - if z_attachment_check(&this) { - let mut map = z_bytes_map_new(); - z_attachment_iterate( - this, - bytes_map_from_attachment_iterator_by_alias, - &mut map as *mut _ as *mut _, - ); - map - } else { - z_bytes_map_null() - } -} diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index b964add61..9860e926d 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -1,6 +1,6 @@ -use crate::{z_closure_owned_query_drop, z_owned_closure_owned_query_t, z_owned_query_t}; +use crate::{z_closure_query_drop, z_owned_closure_query_t, z_owned_query_t, z_query_clone, z_query_null, z_query_t}; use libc::c_void; -use std::sync::mpsc::TryRecvError; +use std::{mem::MaybeUninit, sync::mpsc::{Receiver, TryRecvError}}; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// - `this` is a pointer to an arbitrary state. @@ -16,49 +16,40 @@ use std::sync::mpsc::TryRecvError; #[repr(C)] pub struct z_owned_query_channel_closure_t { context: *mut c_void, - call: Option bool>, + call: Option, *mut c_void) -> bool>, drop: Option, } /// A pair of closures #[repr(C)] pub struct z_owned_query_channel_t { - pub send: z_owned_closure_owned_query_t, + pub send: z_owned_closure_query_t, pub recv: z_owned_query_channel_closure_t, } #[no_mangle] pub extern "C" fn z_query_channel_drop(channel: &mut z_owned_query_channel_t) { - z_closure_owned_query_drop(&mut channel.send); + z_closure_query_drop(&mut channel.send); z_query_channel_closure_drop(&mut channel.recv); } /// Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type #[no_mangle] pub extern "C" fn z_query_channel_null() -> z_owned_query_channel_t { z_owned_query_channel_t { - send: z_owned_closure_owned_query_t::empty(), + send: z_owned_closure_query_t::empty(), recv: z_owned_query_channel_closure_t::empty(), } } -/// Creates a new blocking fifo channel, returned as a pair of closures. -/// -/// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. -/// -/// The `send` end should be passed as callback to a `z_get` call. -/// -/// The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, -/// which it will then return; or until the `send` closure is dropped and all queries have been consumed, -/// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. -#[no_mangle] -pub extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { - let (send, rx) = if bound == 0 { +unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver) { + if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |query: &mut z_owned_query_t| { - if let Some(query) = query.take() { - if let Err(e) = tx.send(query) { - log::error!("Attempted to push onto a closed query_fifo: {}", e) - } + From::from(move |query: z_query_t| { + let mut this = MaybeUninit::::uninit(); + z_query_clone(&mut this as *mut MaybeUninit, query); + let this = this.assume_init(); + if let Err(e) = tx.send(this) { + log::error!("Attempted to push onto a closed reply_fifo: {}", e); } }), rx, @@ -66,23 +57,40 @@ pub extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |query: &mut z_owned_query_t| { - if let Some(query) = query.take() { - if let Err(e) = tx.send(query) { - log::error!("Attempted to push onto a closed query_fifo: {}", e) - } + From::from(move |query: z_query_t| { + let mut this = MaybeUninit::::uninit(); + z_query_clone(&mut this as *mut MaybeUninit, query); + let this = this.assume_init(); + if let Err(e) = tx.send(this) { + log::error!("Attempted to push onto a closed reply_fifo: {}", e); } }), rx, ) - }; + } +} + + +/// Creates a new blocking fifo channel, returned as a pair of closures. +/// +/// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. +/// +/// The `send` end should be passed as callback to a `z_get` call. +/// +/// The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, +/// which it will then return; or until the `send` closure is dropped and all queries have been consumed, +/// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. +#[no_mangle] +pub unsafe extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { + let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { send, - recv: From::from(move |receptacle: &mut z_owned_query_t| { - *receptacle = match rx.recv() { - Ok(val) => Some(val).into(), - Err(_) => None.into(), - }; + recv: From::from(move |this: *mut MaybeUninit| { + if let Ok(val) = rx.recv() { + (*this).write(val); + } else { + z_query_null(this); + } true }), } @@ -98,51 +106,26 @@ pub extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { /// which it will then return; or until the `send` closure is dropped and all queries have been consumed, /// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. #[no_mangle] -pub extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned_query_channel_t { - let (send, rx) = if bound == 0 { - let (tx, rx) = std::sync::mpsc::channel(); - ( - From::from(move |query: &mut z_owned_query_t| { - if let Some(query) = query.take() { - if let Err(e) = tx.send(query) { - log::error!("Attempted to push onto a closed query_fifo: {}", e) - } - } - }), - rx, - ) - } else { - let (tx, rx) = std::sync::mpsc::sync_channel(bound); - ( - From::from(move |query: &mut z_owned_query_t| { - if let Some(query) = query.take() { - if let Err(e) = tx.send(query) { - log::error!("Attempted to push onto a closed query_fifo: {}", e) - } - } - }), - rx, - ) - }; +pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned_query_channel_t { + let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { send, - recv: From::from( - move |receptacle: &mut z_owned_query_t| match rx.try_recv() { + recv: From::from(move |this: *mut MaybeUninit| { + match rx.try_recv() { Ok(val) => { - let mut tmp = z_owned_query_t::from(Some(val)); - std::mem::swap(&mut tmp, receptacle); + (*this).write(val); true } Err(TryRecvError::Disconnected) => { - receptacle.take(); + z_query_null(this); true } Err(TryRecvError::Empty) => { - receptacle.take(); + z_query_null(this); false } - }, - ), + } + }), } } @@ -175,10 +158,10 @@ pub extern "C" fn z_query_channel_closure_null() -> z_owned_query_channel_closur #[no_mangle] pub extern "C" fn z_query_channel_closure_call( closure: &z_owned_query_channel_closure_t, - sample: &mut z_owned_query_t, + query: *mut MaybeUninit, ) -> bool { match closure.call { - Some(call) => call(sample, closure.context), + Some(call) => call(query, closure.context), None => { log::error!("Attempted to call an uninitialized closure!"); true @@ -191,11 +174,11 @@ pub extern "C" fn z_query_channel_closure_drop(closure: &mut z_owned_query_chann let mut empty_closure = z_owned_query_channel_closure_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl bool> From for z_owned_query_channel_closure_t { +impl) -> bool> From for z_owned_query_channel_closure_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call bool>( - query: &mut z_owned_query_t, + extern "C" fn call) -> bool>( + query: *mut MaybeUninit, this: *mut c_void, ) -> bool { let this = unsafe { &*(this as *const F) }; diff --git a/src/closures/query_closure.rs b/src/closures/query_closure.rs index 22ad4bc28..f0387bc45 100644 --- a/src/closures/query_closure.rs +++ b/src/closures/query_closure.rs @@ -4,7 +4,7 @@ use libc::c_void; /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_query_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_query_t { @@ -45,7 +45,7 @@ pub extern "C" fn z_closure_query_null() -> z_owned_closure_query_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: &z_query_t) { +pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: z_query_t) { match closure.call { Some(call) => call(query, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -57,10 +57,10 @@ pub extern "C" fn z_closure_query_drop(closure: &mut z_owned_closure_query_t) { let mut empty_closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_query_t { +impl From for z_owned_closure_query_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: &z_query_t, this: *mut c_void) { + extern "C" fn call(sample: z_query_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; this(sample) } diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index 1aa8a9b44..e7fdc721f 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -1,4 +1,4 @@ -use crate::z_owned_reply_t; +use crate::z_reply_t; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_reply_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } @@ -48,10 +48,10 @@ pub extern "C" fn z_closure_reply_null() -> z_owned_closure_reply_t { #[no_mangle] pub extern "C" fn z_closure_reply_call( closure: &z_owned_closure_reply_t, - sample: &mut z_owned_reply_t, + reply: z_reply_t, ) { match closure.call { - Some(call) => call(sample, closure.context), + Some(call) => call(reply, closure.context), None => { log::error!("Attempted to call an uninitialized closure!"); } @@ -63,11 +63,11 @@ pub extern "C" fn z_closure_reply_drop(closure: &mut z_owned_closure_reply_t) { let mut empty_closure = z_owned_closure_reply_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_reply_t { +impl From for z_owned_closure_reply_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call( - response: &mut z_owned_reply_t, + extern "C" fn call( + response: z_reply_t, this: *mut c_void, ) { let this = unsafe { &*(this as *const F) }; diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 0ea046d5d..8375a7e5e 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -1,6 +1,6 @@ -use crate::{z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t}; +use crate::{ z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t, z_reply_clone, z_reply_null, z_reply_t}; use libc::c_void; -use std::sync::mpsc::TryRecvError; +use std::{mem::MaybeUninit, sync::mpsc::{Receiver, TryRecvError}}; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// - `this` is a pointer to an arbitrary state. /// - `call` is the typical callback function. `this` will be passed as its last argument. @@ -15,7 +15,7 @@ use std::sync::mpsc::TryRecvError; #[repr(C)] pub struct z_owned_reply_channel_closure_t { context: *mut c_void, - call: Option bool>, + call: Option, *mut c_void) -> bool>, drop: Option, } @@ -39,25 +39,16 @@ pub extern "C" fn z_reply_channel_null() -> z_owned_reply_channel_t { } } -/// Creates a new blocking fifo channel, returned as a pair of closures. -/// -/// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. -/// -/// The `send` end should be passed as callback to a `z_get` call. -/// -/// The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, -/// which it will then return; or until the `send` closure is dropped and all replies have been consumed, -/// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. -#[no_mangle] -pub extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { - let (send, rx) = if bound == 0 { +unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver) { + if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |reply: &mut z_owned_reply_t| { - if let Some(reply) = reply.take() { - if let Err(e) = tx.send(reply) { - log::error!("Attempted to push onto a closed reply_fifo: {}", e) - } + From::from(move |reply: z_reply_t| { + let mut this = MaybeUninit::::uninit(); + z_reply_clone(&mut this as *mut MaybeUninit, reply); + let this = this.assume_init(); + if let Err(e) = tx.send(this) { + log::error!("Attempted to push onto a closed reply_fifo: {}", e); } }), rx, @@ -65,23 +56,38 @@ pub extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |reply: &mut z_owned_reply_t| { - if let Some(reply) = reply.take() { - if let Err(e) = tx.send(reply) { - log::error!("Attempted to push onto a closed reply_fifo: {}", e) - } + From::from(move |reply: z_reply_t| { + let mut this = MaybeUninit::::uninit(); + z_reply_clone(&mut this as *mut MaybeUninit, reply); + let this = this.assume_init(); + if let Err(e) = tx.send(this) { + log::error!("Attempted to push onto a closed reply_fifo: {}", e); } }), rx, ) - }; + } +} +/// Creates a new blocking fifo channel, returned as a pair of closures. +/// +/// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. +/// +/// The `send` end should be passed as callback to a `z_get` call. +/// +/// The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, +/// which it will then return; or until the `send` closure is dropped and all replies have been consumed, +/// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. +#[no_mangle] +pub unsafe extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { + let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { send, - recv: From::from(move |receptacle: &mut z_owned_reply_t| { - *receptacle = match rx.recv() { - Ok(val) => val.into(), - Err(_) => None.into(), - }; + recv: From::from(move |this: *mut MaybeUninit| { + if let Ok(val) = rx.recv() { + (*this).write(val); + } else { + z_reply_null(this); + } true }), } @@ -97,52 +103,26 @@ pub extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { /// which it will then return; or until the `send` closure is dropped and all replies have been consumed, /// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. #[no_mangle] -pub extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned_reply_channel_t { - let (send, rx) = if bound == 0 { - let (tx, rx) = std::sync::mpsc::channel(); - ( - From::from(move |reply: &mut z_owned_reply_t| { - if let Some(reply) = reply.take() { - if let Err(e) = tx.send(reply) { - log::error!("Attempted to push onto a closed reply_fifo: {}", e) - } - } - }), - rx, - ) - } else { - let (tx, rx) = std::sync::mpsc::sync_channel(bound); - ( - From::from(move |reply: &mut z_owned_reply_t| { - if let Some(reply) = reply.take() { - if let Err(e) = tx.send(reply) { - log::error!("Attempted to push onto a closed reply_fifo: {}", e) - } - } - }), - rx, - ) - }; - +pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned_reply_channel_t { + let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { send, - recv: From::from( - move |receptacle: &mut z_owned_reply_t| match rx.try_recv() { + recv: From::from(move |this: *mut MaybeUninit| { + match rx.try_recv() { Ok(val) => { - let mut tmp = z_owned_reply_t::from(val); - std::mem::swap(&mut tmp, receptacle); + (*this).write(val); true } Err(TryRecvError::Disconnected) => { - receptacle.take(); + z_reply_null(this); true } Err(TryRecvError::Empty) => { - receptacle.take(); + z_reply_null(this); false } - }, - ), + } + }), } } @@ -175,10 +155,10 @@ pub extern "C" fn z_reply_channel_closure_null() -> z_owned_reply_channel_closur #[no_mangle] pub extern "C" fn z_reply_channel_closure_call( closure: &z_owned_reply_channel_closure_t, - sample: &mut z_owned_reply_t, + reply: *mut MaybeUninit, ) -> bool { match closure.call { - Some(call) => call(sample, closure.context), + Some(call) => call(reply, closure.context), None => { log::error!("Attempted to call an uninitialized closure!"); true @@ -191,11 +171,11 @@ pub extern "C" fn z_reply_channel_closure_drop(closure: &mut z_owned_reply_chann let mut empty_closure = z_owned_reply_channel_closure_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl bool> From for z_owned_reply_channel_closure_t { +impl) -> bool> From for z_owned_reply_channel_closure_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call bool>( - response: &mut z_owned_reply_t, + extern "C" fn call) -> bool>( + response: *mut MaybeUninit, this: *mut c_void, ) -> bool { let this = unsafe { &*(this as *const F) }; diff --git a/src/collections.rs b/src/collections.rs index d55a9fa1b..b75ca2d63 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -12,36 +12,43 @@ // ZettaScale Zenoh team, // -use libc::{c_char, size_t}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::mem::MaybeUninit; + +use libc::{c_char, c_void, size_t}; use zenoh::prelude::ZenohId; +use crate::errors; +use crate::transmute::{Inplace, InplaceDefault, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; + /// A contiguous view of bytes owned by some other entity. /// /// `start` being `null` is considered a gravestone value, /// and empty slices are represented using a possibly dangling pointer for `start`. #[repr(C)] #[derive(Clone, Copy, Debug)] -pub struct z_bytes_t { +pub struct z_slice_t { pub start: *const u8, pub len: size_t, } -impl z_bytes_t { - pub fn as_slice(&self) -> Option<&[u8]> { +impl z_slice_t { + pub fn as_slice(&self) -> Option<&'static [u8]> { if self.start.is_null() { return None; } Some(unsafe { core::slice::from_raw_parts(self.start, self.len) }) } pub fn empty() -> Self { - z_bytes_t { + z_slice_t { start: std::ptr::null(), len: 0, } } } -impl Default for z_bytes_t { +impl Default for z_slice_t { fn default() -> Self { Self::empty() } @@ -49,32 +56,32 @@ impl Default for z_bytes_t { #[repr(C)] #[derive(Clone, Debug)] -pub struct z_owned_bytes_t { +pub struct z_owned_slice_t { pub start: *mut u8, pub len: size_t, } -impl Drop for z_owned_bytes_t { +impl Drop for z_owned_slice_t { fn drop(&mut self) { - unsafe { z_bytes_drop(self) } + unsafe { z_slice_drop(self) } } } -impl z_owned_bytes_t { - pub fn new(data: &[u8]) -> z_owned_bytes_t { +impl z_owned_slice_t { + pub fn new(data: &[u8]) -> z_owned_slice_t { if data.is_empty() { - return z_bytes_null(); + return z_slice_null(); } let data = data.to_vec().into_boxed_slice(); - z_owned_bytes_t { + z_owned_slice_t { len: data.len(), start: Box::leak(data).as_mut_ptr(), } } - pub fn preallocate(len: usize) -> z_owned_bytes_t { + pub fn preallocate(len: usize) -> z_owned_slice_t { let data = vec![0u8; len].into_boxed_slice(); - z_owned_bytes_t { + z_owned_slice_t { len, start: Box::leak(data).as_mut_ptr(), } @@ -86,16 +93,22 @@ impl z_owned_bytes_t { } } +impl Default for z_owned_slice_t { + fn default() -> Self { + z_slice_null() + } +} + /// Returns ``true`` if `b` is initialized. #[no_mangle] -pub extern "C" fn z_bytes_is_initialized(b: &z_bytes_t) -> bool { +pub extern "C" fn z_slice_is_initialized(b: &z_slice_t) -> bool { !b.start.is_null() } -/// Returns the gravestone value for `z_bytes_t` +/// Returns the gravestone value for `z_slice_t` #[no_mangle] -pub const extern "C" fn z_bytes_empty() -> z_bytes_t { - z_bytes_t { +pub const extern "C" fn z_slice_empty() -> z_slice_t { + z_slice_t { len: 0, start: core::ptr::null(), } @@ -103,45 +116,45 @@ pub const extern "C" fn z_bytes_empty() -> z_bytes_t { /// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_empty()` +/// `str == NULL` will cause this to return `z_slice_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_from_str(str: *const c_char) -> z_bytes_t { +pub unsafe extern "C" fn z_slice_from_str(str: *const c_char) -> z_slice_t { if str.is_null() { - z_bytes_empty() + z_slice_empty() } else { let len = unsafe { libc::strlen(str) }; - z_bytes_t { + z_slice_t { len, start: str.cast(), } } } -#[deprecated = "Renamed to z_bytes_from_str"] -/// Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +#[deprecated = "Renamed to z_slice_from_str"] +/// Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_empty()` +/// `str == NULL` will cause this to return `z_slice_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_new(str: *const c_char) -> z_bytes_t { - z_bytes_from_str(str) +pub unsafe extern "C" fn z_slice_new(str: *const c_char) -> z_slice_t { + z_slice_from_str(str) } /// Constructs a `len` bytes long view starting at `start`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_wrap(start: *const u8, len: usize) -> z_bytes_t { +pub unsafe extern "C" fn z_slice_wrap(start: *const u8, len: usize) -> z_slice_t { if start.is_null() { - z_bytes_empty() + z_slice_empty() } else { - z_bytes_t { len, start } + z_slice_t { len, start } } } /// Frees `b` and invalidates it for double-drop safety. #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_drop(b: &mut z_owned_bytes_t) { +pub unsafe extern "C" fn z_slice_drop(b: &mut z_owned_slice_t) { if !b.start.is_null() { std::mem::drop(Box::from_raw( core::ptr::slice_from_raw_parts(b.start, b.len).cast_mut(), @@ -151,43 +164,43 @@ pub unsafe extern "C" fn z_bytes_drop(b: &mut z_owned_bytes_t) { } } -/// Returns the gravestone value for `z_owned_bytes_t` +/// Returns the gravestone value for `z_owned_slice_t` #[no_mangle] -pub const extern "C" fn z_bytes_null() -> z_owned_bytes_t { - z_owned_bytes_t { +pub const extern "C" fn z_slice_null() -> z_owned_slice_t { + z_owned_slice_t { len: 0, start: core::ptr::null_mut(), } } #[no_mangle] -pub const extern "C" fn z_bytes_loan(b: &z_owned_bytes_t) -> z_bytes_t { - z_bytes_t { +pub const extern "C" fn z_slice_loan(b: &z_owned_slice_t) -> z_slice_t { + z_slice_t { len: b.len, start: b.start, } } #[no_mangle] -pub extern "C" fn z_bytes_clone(b: &z_bytes_t) -> z_owned_bytes_t { - if !z_bytes_is_initialized(b) { - z_bytes_null() +pub extern "C" fn z_slice_clone(b: &z_slice_t, ) -> z_owned_slice_t { + if !z_slice_is_initialized(b) { + z_slice_null() } else { - z_owned_bytes_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) }) + z_owned_slice_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) }) } } /// Returns ``true`` if `b` is initialized. #[no_mangle] -pub extern "C" fn z_bytes_check(b: &z_owned_bytes_t) -> bool { +pub extern "C" fn z_slice_check(b: &z_owned_slice_t) -> bool { !b.start.is_null() } -impl From for z_bytes_t { +impl From for z_slice_t { #[inline] fn from(pid: ZenohId) -> Self { let pid = pid.to_le_bytes().to_vec().into_boxed_slice(); - let res = z_bytes_t { + let res = z_slice_t { start: pid.as_ptr(), len: pid.len() as size_t, }; @@ -196,12 +209,12 @@ impl From for z_bytes_t { } } -impl From> for z_bytes_t { +impl From> for z_slice_t { #[inline] fn from(pid: Option) -> Self { match pid { Some(pid) => pid.into(), - None => z_bytes_t { + None => z_slice_t { start: std::ptr::null(), len: 0, }, @@ -209,8 +222,8 @@ impl From> for z_bytes_t { } } -impl From for String { - fn from(s: z_bytes_t) -> Self { +impl From for String { + fn from(s: z_slice_t) -> Self { unsafe { String::from_utf8( Box::from_raw(std::slice::from_raw_parts_mut(s.start as *mut u8, s.len)).into(), @@ -220,11 +233,220 @@ impl From for String { } } -impl From<&[u8]> for z_bytes_t { +impl From<&[u8]> for z_slice_t { fn from(s: &[u8]) -> Self { - z_bytes_t { + z_slice_t { start: s.as_ptr(), len: s.len(), } } } + +impl InplaceDefault for z_owned_slice_t {} + + +/// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` +/// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with +/// `z_check` and `z_str_check` correspondently +#[repr(C)] +pub struct z_owned_str_t { + pub _cstr: *mut libc::c_char, +} + +impl z_owned_str_t { + #[allow(clippy::missing_safety_doc)] + pub unsafe fn preallocate(len: usize) -> z_owned_str_t { + let cstr = libc::malloc(len + 1) as *mut libc::c_char; + *cstr.add(len) = 0; + z_owned_str_t { _cstr: cstr } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { + std::ptr::copy_nonoverlapping( + value.as_ptr(), + (self._cstr as *mut u8).add(start), + value.len(), + ); + } +} + +impl From<&[u8]> for z_owned_str_t { + fn from(value: &[u8]) -> Self { + unsafe { + let mut cstr = Self::preallocate(value.len()); + cstr.insert_unchecked(0, value); + cstr + } + } +} + +impl Drop for z_owned_str_t { + fn drop(&mut self) { + unsafe { z_str_drop(self) } + } +} + +impl Default for z_owned_str_t { + fn default() -> Self { + z_str_null() + } +} + +/// Frees `z_owned_str_t`, invalidating it for double-drop safety. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_str_drop(s: &mut z_owned_str_t) { + if s._cstr.is_null() { + return; + } + libc::free(std::mem::transmute(s._cstr)); + s._cstr = std::ptr::null_mut(); +} + +/// Returns ``true`` if `s` is a valid string +#[no_mangle] +pub extern "C" fn z_str_check(s: &z_owned_str_t) -> bool { + !s._cstr.is_null() +} + +/// Returns undefined `z_owned_str_t` +#[no_mangle] +pub extern "C" fn z_str_null() -> z_owned_str_t { + z_owned_str_t { + _cstr: std::ptr::null_mut(), + } +} + +/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. +#[no_mangle] +pub extern "C" fn z_str_loan(s: &z_owned_str_t) -> *const libc::c_char { + s._cstr +} + +impl InplaceDefault for z_owned_str_t {} + +pub use crate::opaque_types::z_owned_slice_map_t; +pub use crate::opaque_types::z_slice_map_t; + +pub type ZHashMap = HashMap, Cow<'static, [u8]>>; +pub use crate::opaque_types::z_config_t; +decl_transmute_handle!(HashMap, Cow<'static, [u8]>>, z_slice_map_t); + +pub use crate::opaque_types::z_owned_config_t; +decl_transmute_owned!(Option, z_owned_slice_map_t); + +/// Constructs a new empty map. +#[no_mangle] +pub extern "C" fn z_slice_map_new(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + let map = ZHashMap::new(); + Inplace::init(this, Some(map)); +} + +/// Constructs the gravestone value for `z_owned_slice_map_t` +#[no_mangle] +pub extern "C" fn z_slice_map_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); +} + +/// Returns `true` if the map is not in its gravestone state +#[no_mangle] +pub extern "C" fn z_slice_map_check(map: &z_owned_slice_map_t) -> bool { + let map = map.transmute_ref(); + map.as_ref().is_some() +} + +/// Destroys the map, resetting `this` to its gravestone value. +/// +/// This function is double-free safe, passing a pointer to the gravestone value will have no effect. +#[no_mangle] +pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { + let this = this.transmute_mut(); + Inplace::drop(this); +} + +/// Returns number of key-value pairs in the map. +#[no_mangle] +pub extern "C" fn z_slice_map_len(this: z_slice_map_t) -> usize { + this.transmute_ref().len() +} + +/// Returns true if the map is empty, false otherwise. +#[no_mangle] +pub extern "C" fn z_slice_map_is_empty(this: z_slice_map_t) -> bool { + z_slice_map_len(this) == 0 +} + +/// The body of a loop over a z_slice_map's key-value pairs. +/// +/// `key` and `value` are loaned to the body for the duration of a single call. +/// `context` is passed transparently through the iteration driver. +/// +/// Returning `true` is treated as `continue`. +#[allow(non_camel_case_types)] +pub type z_slice_map_iter_body_t = + extern "C" fn(key: z_slice_t, value: z_slice_t, context: *mut c_void) -> bool; + +#[no_mangle] +pub extern "C" fn z_slice_map_iterate(this: &z_slice_map_t, body: z_slice_map_iter_body_t, context: *mut c_void) { + let this = this.transmute_ref(); + for (key, value) in this { + if !body(key.as_ref().into(), value.as_ref().into(), context) { + break; + } + } +} + +/// Returns the value associated with `key`, returning a gravestone value if: +/// - `key` is in gravestone state. +#[no_mangle] +pub extern "C" fn z_slice_map_get(this: z_slice_map_t, key: z_slice_t) -> z_slice_t { + if !z_slice_is_initialized(&key) { + return z_slice_empty(); + } + let m = this.transmute_mut(); + let key = key.as_slice().unwrap(); + m.get(key).map(|s| s.as_ref().into()).unwrap_or( z_slice_empty()) +} + +/// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. +/// +/// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. +#[no_mangle] +pub extern "C" fn z_slice_map_insert_by_copy( + this: z_slice_map_t, + key: z_slice_t, + value: z_slice_t, +) -> errors::ZCError { + let this = this.transmute_mut(); + if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) + { + this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); + errors::Z_OK + } else { + errors::Z_EINVAL + } +} + +/// Associates `value` to `key` in the map, aliasing them. +/// +/// Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. +/// +/// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. +#[no_mangle] +pub extern "C" fn z_slice_map_insert_by_alias( + this: z_slice_map_t, + key: z_slice_t, + value: z_slice_t, +) -> errors::ZCError { + let this = this.transmute_mut(); + if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) + { + this.insert(Cow::Borrowed(key), Cow::Borrowed(value)); + errors::Z_OK + } else { + errors::Z_EINVAL + } +} \ No newline at end of file diff --git a/src/commons.rs b/src/commons.rs index 5bc998d49..ba29657be 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -14,32 +14,31 @@ use std::ffi::CStr; use std::mem::MaybeUninit; -use std::ops::Deref; use std::str::FromStr; -use crate::opaque_types::z_owned_buffer_t; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::InplaceDefault; use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteUninitPtr; use crate::z_id_t; -use crate::zc_owned_payload_t; -use crate::zc_payload_t; -use libc::c_void; +use crate::z_bytes_t; +use crate::z_keyexpr_t; use libc::{c_char, c_ulong}; use unwrap_infallible::UnwrapInfallible; -use zenoh::buffers::ZBuf; use zenoh::encoding::Encoding; -use zenoh::payload::Deserialize; -use zenoh::payload::ZSerde; use zenoh::prelude::SampleKind; +use zenoh::publication::CongestionControl; +use zenoh::publication::Priority; +use zenoh::query::ConsolidationMode; +use zenoh::query::Mode; +use zenoh::query::QueryTarget; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::Sample; use zenoh::time::Timestamp; - -use crate::attachment::{attachment_iteration_driver, z_attachment_null, z_attachment_t}; +use zenoh::value::Value; /// A zenoh unsigned integer #[allow(non_camel_case_types)] @@ -70,36 +69,20 @@ impl From for SampleKind { } } } +use crate::opaque_types::z_timestamp_t; +decl_transmute_copy!(Timestamp, z_timestamp_t); -#[repr(C)] -pub struct z_timestamp_t { - time: u64, - id: z_id_t, +#[no_mangle] +pub extern "C" fn z_timestamp_npt64_time(timestamp: &z_timestamp_t) -> u64 { + timestamp.transmute_copy().get_time().0 } -/// Returns ``true`` if `ts` is a valid timestamp #[no_mangle] -pub extern "C" fn z_timestamp_check(ts: z_timestamp_t) -> bool { - ts.id.id.iter().any(|byte| *byte != 0) -} -impl From> for z_timestamp_t { - fn from(ts: Option<&Timestamp>) -> Self { - if let Some(ts) = ts { - z_timestamp_t { - time: ts.get_time().as_u64(), - id: z_id_t { - id: ts.get_id().to_le_bytes(), - }, - } - } else { - z_timestamp_t { - time: 0, - id: z_id_t { id: [0u8; 16] }, - } - } - } +pub unsafe extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t { + timestamp.transmute_copy().get_id().to_le_bytes().into() } + /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. @@ -122,29 +105,12 @@ pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { } /// The sample's data, the return value aliases the sample. /// -/// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { - // TODO: here returning reference not to sample's payload, but to temporary copy - // THIS WILL CRASH FOR SURE, MADE IT ONLY TO MAKE IT COMPILE - // Need a way to get reference to sample's payload +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { let sample = sample.transmute_copy(); - let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); - let owned_buffer: z_owned_buffer_t = Some(buffer).into(); - owned_buffer.as_ref().into() + sample.payload().transmute_handle() } -/// Returns the sample's payload after incrementing its internal reference count. -/// -/// Note that other samples may have received the same buffer, meaning that mutating this buffer may -/// affect the samples received by other subscribers. -#[no_mangle] -pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { - let sample = sample.transmute_copy(); - let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); - let owned_buffer: z_owned_buffer_t = Some(buffer).into(); - owned_buffer.into() -} /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { @@ -152,37 +118,45 @@ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { sample.kind().into() } /// The samples timestamp +/// +/// Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. #[no_mangle] -pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { +pub extern "C" fn z_sample_timestamp(sample: &z_sample_t, timestamp_out: &mut z_timestamp_t) -> bool { let sample = sample.transmute_copy(); - sample.timestamp().into() + if let Some(t) = sample.timestamp() { + *timestamp_out = t.transmute_copy(); + true + } else { + false + } } /// The qos with which the sample was received. /// TODO: split to methods (priority, congestion_control, express) -/// The sample's attachment. +/// Checks if sample contains an attachment. +#[no_mangle] +pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { + let sample = sample.transmute_copy(); + sample.attachment().is_some() +} + +/// Gets sample's attachment. /// -/// `sample` is aliased by the return value. +/// Before calling this function, ensure that `zc_sample_has_attachment` returns true #[no_mangle] -pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { +pub extern "C" fn z_sample_attachment(sample: z_sample_t) -> z_bytes_t { let sample = sample.transmute_copy(); - match sample.attachment() { - Some(attachment) => z_attachment_t { - data: attachment as *const _ as *mut c_void, - iteration_driver: Some(attachment_iteration_driver), - }, - None => z_attachment_null(), - } + sample.attachment().expect("Sample does not have an attachment").transmute_handle() } pub use crate::opaque_types::zc_owned_sample_t; -decl_transmute_owned!(default_inplace_init Option, zc_owned_sample_t); +decl_transmute_owned!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { let src = src.transmute_copy(); - let src = src.deref().clone(); + let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); } @@ -201,7 +175,7 @@ pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> z_sample_t { +pub extern "C" fn zc_sample_loan(sample: &'static zc_owned_sample_t) -> z_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_copy() } @@ -216,10 +190,6 @@ pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { Inplace::empty(sample.transmute_uninit_ptr()); } -/// The encoding of a payload, in a MIME-like format. -/// -/// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. -/// pub use crate::opaque_types::z_encoding_t; decl_transmute_copy!(&'static Encoding, z_encoding_t); @@ -231,7 +201,7 @@ decl_transmute_copy!(&'static Encoding, z_encoding_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_encoding_t; -decl_transmute_owned!(default_inplace_init Encoding, z_owned_encoding_t); +decl_transmute_owned!(Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] @@ -251,8 +221,8 @@ pub unsafe extern "C" fn z_encoding_from_str( Inplace::empty(encoding); 0 } else { - let s = CStr::from_ptr(s).to_string_lossy().as_ref(); - let value = Encoding::from_str(s).unwrap_infallible(); + let s = CStr::from_ptr(s).to_string_lossy(); + let value = Encoding::from_str(s.as_ref()).unwrap_infallible(); Inplace::init(encoding, value); 0 } @@ -269,7 +239,7 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - Inplace::drop(encoding); + Inplace::drop(encoding.transmute_mut()); } /// Returns ``true`` if `encoding` is valid. @@ -286,78 +256,11 @@ pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_en encoding.transmute_ref().transmute_copy() } -/// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` -/// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with -/// `z_check` and `z_str_check` correspondently -#[repr(C)] -pub struct z_owned_str_t { - pub _cstr: *mut libc::c_char, -} - -impl z_owned_str_t { - #[allow(clippy::missing_safety_doc)] - pub unsafe fn preallocate(len: usize) -> z_owned_str_t { - let cstr = libc::malloc(len + 1) as *mut libc::c_char; - *cstr.add(len) = 0; - z_owned_str_t { _cstr: cstr } - } - - #[allow(clippy::missing_safety_doc)] - pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping( - value.as_ptr(), - (self._cstr as *mut u8).add(start), - value.len(), - ); - } -} - -impl From<&[u8]> for z_owned_str_t { - fn from(value: &[u8]) -> Self { - unsafe { - let mut cstr = Self::preallocate(value.len()); - cstr.insert_unchecked(0, value); - cstr - } - } -} -impl Drop for z_owned_str_t { - fn drop(&mut self) { - unsafe { z_str_drop(self) } - } -} - -/// Frees `z_owned_str_t`, invalidating it for double-drop safety. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_str_drop(s: &mut z_owned_str_t) { - if s._cstr.is_null() { - return; - } - libc::free(std::mem::transmute(s._cstr)); - s._cstr = std::ptr::null_mut(); -} - -/// Returns ``true`` if `s` is a valid string -#[no_mangle] -pub extern "C" fn z_str_check(s: &z_owned_str_t) -> bool { - !s._cstr.is_null() -} - -/// Returns undefined `z_owned_str_t` -#[no_mangle] -pub extern "C" fn z_str_null() -> z_owned_str_t { - z_owned_str_t { - _cstr: std::ptr::null_mut(), - } -} - -/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. -#[no_mangle] -pub extern "C" fn z_str_loan(s: &z_owned_str_t) -> *const libc::c_char { - s._cstr -} +pub use crate::opaque_types::z_owned_value_t; +decl_transmute_owned!(Value, z_owned_value_t); +pub use crate::opaque_types::z_value_t; +decl_transmute_copy!(&'static Value, z_value_t); #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -421,3 +324,182 @@ impl From for ReplyKeyExpr { pub extern "C" fn zcu_reply_keyexpr_default() -> zcu_reply_keyexpr_t { ReplyKeyExpr::default().into() } + + +/// The Queryables that should be target of a :c:func:`z_get`. +/// +/// - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. +/// - **ALL_COMPLETE**: All complete queryables. +/// - **ALL**: All matching queryables. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Clone, Copy)] +pub enum z_query_target_t { + BEST_MATCHING, + ALL, + ALL_COMPLETE, +} + +impl From for z_query_target_t { + #[inline] + fn from(t: QueryTarget) -> Self { + match t { + QueryTarget::BestMatching => z_query_target_t::BEST_MATCHING, + QueryTarget::All => z_query_target_t::ALL, + QueryTarget::AllComplete => z_query_target_t::ALL_COMPLETE, + } + } +} + +impl From for QueryTarget { + #[inline] + fn from(val: z_query_target_t) -> Self { + match val { + z_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, + z_query_target_t::ALL => QueryTarget::All, + z_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, + } + } +} + +/// Create a default :c:type:`z_query_target_t`. +#[no_mangle] +pub extern "C" fn z_query_target_default() -> z_query_target_t { + QueryTarget::default().into() +} + +/// Consolidation mode values. +/// +/// - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector +/// If the selector contains time range properties, consolidation mode `NONE` is used. +/// Otherwise the `LATEST` consolidation mode is used. +/// - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. +/// - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time +/// w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple +/// replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp +/// ts2 > ts1. It optimizes latency. +/// - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. +/// It optimizes bandwidth. +#[repr(C)] +#[derive(Clone, Copy, Default)] +pub enum z_consolidation_mode_t { + AUTO = -1, + #[default] + NONE = 0, + MONOTONIC = 1, + LATEST = 2, +} + +impl From> for z_consolidation_mode_t { + #[inline] + fn from(cm: Mode) -> Self { + match cm { + Mode::Manual(cm) => Self::from(cm), + Mode::Auto => z_consolidation_mode_t::AUTO, + } + } +} + +impl From for z_consolidation_mode_t { + #[inline] + fn from(cm: ConsolidationMode) -> Self { + match cm { + ConsolidationMode::Auto => z_consolidation_mode_t::AUTO, + ConsolidationMode::None => z_consolidation_mode_t::NONE, + ConsolidationMode::Monotonic => z_consolidation_mode_t::MONOTONIC, + ConsolidationMode::Latest => z_consolidation_mode_t::LATEST, + } + } +} + +impl From for Mode { + #[inline] + fn from(val: z_consolidation_mode_t) -> Self { + match val { + z_consolidation_mode_t::AUTO => Mode::Auto, + z_consolidation_mode_t::NONE => Mode::Manual(ConsolidationMode::None), + z_consolidation_mode_t::MONOTONIC => Mode::Manual(ConsolidationMode::Monotonic), + z_consolidation_mode_t::LATEST => Mode::Manual(ConsolidationMode::Latest), + } + } +} + +/// The priority of zenoh messages. +/// +/// - **REAL_TIME** +/// - **INTERACTIVE_HIGH** +/// - **INTERACTIVE_LOW** +/// - **DATA_HIGH** +/// - **DATA** +/// - **DATA_LOW** +/// - **BACKGROUND** +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Clone, Copy)] +pub enum z_priority_t { + REAL_TIME = 1, + INTERACTIVE_HIGH = 2, + INTERACTIVE_LOW = 3, + DATA_HIGH = 4, + DATA = 5, + DATA_LOW = 6, + BACKGROUND = 7, +} + +impl From for z_priority_t { + fn from(p: Priority) -> Self { + match p { + Priority::RealTime => z_priority_t::REAL_TIME, + Priority::InteractiveHigh => z_priority_t::INTERACTIVE_HIGH, + Priority::InteractiveLow => z_priority_t::INTERACTIVE_LOW, + Priority::DataHigh => z_priority_t::DATA_HIGH, + Priority::Data => z_priority_t::DATA, + Priority::DataLow => z_priority_t::DATA_LOW, + Priority::Background => z_priority_t::BACKGROUND, + } + } +} + +impl From for Priority { + fn from(p: z_priority_t) -> Self { + match p { + z_priority_t::REAL_TIME => Priority::RealTime, + z_priority_t::INTERACTIVE_HIGH => Priority::InteractiveHigh, + z_priority_t::INTERACTIVE_LOW => Priority::InteractiveLow, + z_priority_t::DATA_HIGH => Priority::DataHigh, + z_priority_t::DATA => Priority::Data, + z_priority_t::DATA_LOW => Priority::DataLow, + z_priority_t::BACKGROUND => Priority::Background, + } + } +} + +/// The kind of congestion control. +/// +/// - **BLOCK** +/// - **DROP** +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Clone, Copy)] +pub enum z_congestion_control_t { + BLOCK, + DROP, +} + +impl From for z_congestion_control_t { + fn from(cc: CongestionControl) -> Self { + match cc { + CongestionControl::Block => z_congestion_control_t::BLOCK, + CongestionControl::Drop => z_congestion_control_t::DROP, + } + } +} + +impl From for CongestionControl { + fn from(cc: z_congestion_control_t) -> Self { + match cc { + z_congestion_control_t::BLOCK => CongestionControl::Block, + z_congestion_control_t::DROP => CongestionControl::Drop, + } + } +} \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index 824a45e37..23ef45a88 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,10 +16,11 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; +use crate::errors::{ZCError, Z_EPARSE}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; -use crate::{z_owned_str_t, z_str_null}; +use crate::{errors, z_owned_str_t, z_str_null}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -61,30 +62,19 @@ pub static Z_CONFIG_SCOUTING_DELAY_KEY: &c_char = pub static Z_CONFIG_ADD_TIMESTAMP_KEY: &c_char = unsafe { &*(b"timestamping/enabled\0".as_ptr() as *const c_char) }; -/// A loaned zenoh configuration. pub use crate::opaque_types::z_config_t; -decl_transmute_copy!(&'static Config, z_config_t); +decl_transmute_handle!(Config, z_config_t); -/// An owned zenoh configuration. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_config_t; decl_transmute_owned!(Option>, z_owned_config_t); /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t { +pub extern "C" fn z_config_loan(s: &'static z_owned_config_t) -> z_config_t { let s = s.transmute_ref(); let s = unwrap_ref_unchecked(s); let s = s.as_ref(); - s.transmute_copy() + s.transmute_handle() } /// Return a new, zenoh-allocated, empty configuration. @@ -111,12 +101,21 @@ pub extern "C" fn z_config_null(this: *mut MaybeUninit) { Inplace::empty(this); } +/// Clones the config. +#[no_mangle] +pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) { + let src = src.transmute_ref(); + let src = Box::new(src.clone()); + let dst = dst.transmute_uninit_ptr(); + Inplace::init(dst, Some(src)); +} + /// Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. /// Use `z_drop` to safely deallocate this string #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) -> z_owned_str_t { - let config = config.transmute_copy(); + let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, Err(_) => return z_str_null(), @@ -138,7 +137,7 @@ pub unsafe extern "C" fn zc_config_insert_json( key: *const c_char, value: *const c_char, ) -> i8 { - let config = config.transmute_copy(); + let config = config.transmute_mut(); let key = CStr::from_ptr(key); let value = CStr::from_ptr(value); match config.insert_json5(&key.to_string_lossy(), &value.to_string_lossy()) { @@ -162,36 +161,37 @@ pub extern "C" fn z_config_check(config: &z_owned_config_t) -> bool { config.as_ref().is_some() } -/// Creates a default, zenoh-allocated, configuration. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_config_default() -> z_owned_config_t { - z_config_new() -} - /// Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. /// /// Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_config_from_str(s: *const c_char) -> z_owned_config_t { +pub unsafe extern "C" fn zc_config_from_str( + s: *const c_char, + this: *mut MaybeUninit, +) -> errors::ZCError { + let mut res = errors::Z_OK; if s.is_null() { - z_config_null() + z_config_null(this); + res = errors::Z_EINVAL; } else { let conf_str = CStr::from_ptr(s); - let props: Option = json5::from_str(&conf_str.to_string_lossy()).ok(); - z_owned_config_t(std::mem::transmute(props.map(Box::new))) + let props: Option> = json5::from_str(&conf_str.to_string_lossy()) + .ok() + .map(|v| Box::new(v)); + if props.is_none() { + res = Z_EPARSE; + } + Inplace::init(this.transmute_uninit_ptr(), props); } + res } /// Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { - let config: &Config = match config.as_ref() { - Some(c) => c, - None => return z_str_null(), - }; + let config: &Config = config.transmute_ref(); match json5::to_string(config) { Ok(s) => s.as_bytes().into(), Err(_) => z_str_null(), @@ -201,28 +201,39 @@ pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { /// Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_config_from_file(path: *const c_char) -> z_owned_config_t { +pub unsafe extern "C" fn zc_config_from_file( + path: *const c_char, + this: *mut MaybeUninit, +) -> errors::ZCError { let path_str = CStr::from_ptr(path); - z_owned_config_t(std::mem::transmute(match path_str.to_str() { + let mut res = errors::Z_OK; + let config = match path_str.to_str() { Ok(path) => match zenoh::config::Config::from_file(path) { Ok(c) => Some(Box::new(c)), Err(e) => { log::error!("Couldn't read config from {}: {}", path, e); + res = errors::Z_EPARSE; None } }, Err(e) => { log::error!("Invalid path '{}': {}", path_str.to_string_lossy(), e); + res = errors::Z_EIO; None } - })) + }; + Inplace::init(this.transmute_uninit_ptr(), config); + res } /// Constructs a default, zenoh-allocated, peer mode configuration. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_config_peer() -> z_owned_config_t { - unsafe { z_owned_config_t(std::mem::transmute(Some(Box::new(zenoh::config::peer())))) } +pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { + Inplace::init( + this.transmute_uninit_ptr(), + Some(Box::new(zenoh::config::peer())), + ); } /// Constructs a default, zenoh-allocated, client mode configuration. @@ -232,7 +243,9 @@ pub extern "C" fn z_config_peer() -> z_owned_config_t { pub unsafe extern "C" fn z_config_client( peers: *const *const c_char, n_peers: usize, -) -> z_owned_config_t { + this: *mut MaybeUninit, +) -> ZCError { + let mut res = errors::Z_OK; let locators = if peers.is_null() { Vec::new() } else if let Ok(locators) = std::slice::from_raw_parts(peers, n_peers) @@ -243,6 +256,7 @@ pub unsafe extern "C" fn z_config_client( |mut acc, it| match it { Err(e) => { log::error!("Error parsing peer address: {}", e); + res = errors::Z_EPARSE; Err(()) } Ok(loc) => { @@ -254,9 +268,12 @@ pub unsafe extern "C" fn z_config_client( { locators } else { - return z_owned_config_t(std::mem::transmute(None::>)); + z_config_null(this); + return res; }; - z_owned_config_t(std::mem::transmute(Some(Box::new(zenoh::config::client( - locators, - ))))) + Inplace::init( + this.transmute_uninit_ptr(), + Some(Box::new(zenoh::config::client(locators))), + ); + res } diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 000000000..90e8508de --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,7 @@ +pub type ZCError = i8; +pub const Z_OK: ZCError = 0; +pub const Z_EINVAL: ZCError = -1; +pub const Z_EPARSE: ZCError = -2; +pub const Z_EIO: ZCError = -3; +pub const Z_ENETWORK: ZCError = -4; +pub const Z_EGENERIC: ZCError = i8::MIN; \ No newline at end of file diff --git a/src/get.rs b/src/get.rs index 5274a86b5..de8e9d183 100644 --- a/src/get.rs +++ b/src/get.rs @@ -13,60 +13,46 @@ // use libc::c_char; -use libc::c_void; -use std::mem::MaybeUninit; -use std::{ - convert::TryFrom, - ffi::CStr, - ops::{Deref, DerefMut}, -}; -use zenoh::buffers::ZBuf; -use zenoh::encoding::Encoding; -use zenoh::payload; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; +use std::mem::MaybeUninit; +use std::ptr::null_mut; +use std::ffi::CStr; -use zenoh::{ - prelude::{ConsolidationMode, KeyExpr, QueryTarget}, - query::{Mode, QueryConsolidation, Reply}, - sample::AttachmentBuilder, - value::Value, -}; +use zenoh::prelude::{ConsolidationMode, QueryTarget, Mode, QueryConsolidation, Reply}; -use crate::attachment::{ - insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, - z_attachment_t, -}; +use crate::errors; use crate::transmute::Inplace; use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; -use crate::z_encoding_default; -use crate::zc_owned_payload_t; -use crate::zc_payload_null; -use crate::zc_payload_t; +use crate::transmute::TransmuteUninitPtr; +use crate::z_consolidation_mode_t; +use crate::z_owned_encoding_t; +use crate::z_query_target_t; +use crate::z_sample_t; +use crate::z_owned_bytes_t; +use crate::z_value_t; use crate::{ - opaque_types::z_sample_t, z_closure_reply_call, z_encoding_t, z_keyexpr_t, - z_owned_closure_reply_t, z_session_t, LOG_INVALID_SESSION, + z_closure_reply_call, z_keyexpr_t, + z_owned_closure_reply_t, z_session_t, }; +use zenoh::prelude::SyncResolve; -/// An owned reply to a :c:func:`z_get`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_reply_t; -decl_transmute_owned!(default_inplace_init Option, z_owned_reply_t); +decl_transmute_owned!(Option, z_owned_reply_t); +pub use crate::opaque_types::z_reply_t; +decl_transmute_handle!(Reply, z_reply_t); /// Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. /// /// If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { +pub unsafe extern "C" fn z_reply_is_ok(reply: z_reply_t) -> bool { let reply = reply.transmute_ref(); - reply.as_ref().map(|r| r.sample.is_ok()).unwrap_or(false) + reply.result().is_ok() } /// Yields the contents of the reply by asserting it indicates a success. @@ -74,35 +60,19 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { /// You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { +pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { let reply = reply.transmute_ref(); - if let Some(sample) = reply.as_ref().and_then(|s| s.sample.as_ref().ok()) { - sample.transmute_copy() - } else { - panic!("Assertion failed: tried to treat `z_owned_reply_t` as Ok despite that not being the case") - } + reply.result().expect("Reply does not contain a sample").transmute_copy() } -/// A zenoh value. -/// -/// -pub use crate::opaque_types::z_owned_value_t; -decl_transmute_owned!(default_inplace_init Value, z_owned_value_t); -pub use crate::opaque_types::z_value_t; -decl_transmute_copy!(&'static Value, z_value_t); - /// Yields the contents of the reply by asserting it indicates a failure. /// /// You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { +pub unsafe extern "C" fn z_reply_err(reply: z_reply_t) -> z_value_t { let reply = reply.transmute_ref(); - if let Some(value) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { - value.into() - } else { - panic!("Assertion failed: tried to treat `z_owned_reply_t` as Err despite that not being the case") - } + reply.result().expect_err("Reply does not contain error").transmute_copy() } /// Returns an invalidated :c:type:`z_owned_reply_t`. @@ -113,9 +83,13 @@ pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { /// - overwrite the pointee with this function's return value, /// - you are now responsible for dropping your copy of the reply. #[no_mangle] -#[allow(improper_ctypes_definitions)] -pub extern "C" fn z_reply_null(reply: *mut MaybeUninit) { - Inplace::empty(z_owned_reply_t::transmute_uninit_ptr(reply)); +pub extern "C" fn z_reply_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); +} + +#[no_mangle] +pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: z_reply_t) { + Inplace::init(this.transmute_uninit_ptr(), Some(reply.transmute_ref().clone())); } /// Options passed to the :c:func:`z_get` function. @@ -124,15 +98,15 @@ pub extern "C" fn z_reply_null(reply: *mut MaybeUninit) { /// z_query_target_t target: The Queryables that should be target of the query. /// z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. /// z_value_t value: An optional value to attach to the query. -/// z_attachment_t attachment: The attachment to attach to the query. +/// z_bytes_t attachment: The attachment to attach to the query. /// uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. #[repr(C)] pub struct z_get_options_t { pub target: z_query_target_t, pub consolidation: z_query_consolidation_t, - pub payload: zc_owned_payload_t, - pub encoding: z_encoding_t, - pub attachment: z_attachment_t, + pub payload: *mut z_owned_bytes_t, + pub encoding: *mut z_owned_encoding_t, + pub attachment: *mut z_owned_bytes_t, pub timeout_ms: u64, } #[no_mangle] @@ -141,9 +115,9 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { target: QueryTarget::default().into(), consolidation: QueryConsolidation::default().into(), timeout_ms: 0, - payload: zc_payload_null(), - encoding: z_encoding_default(), - attachment: z_attachment_null(), + payload: null_mut(), + encoding: null_mut(), + attachment: null_mut(), } } @@ -154,7 +128,7 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression matching resources to query. +/// key_expr: The key expression matching resources to query. /// parameters: The query's parameters, similar to a url's query segment. /// callback: The callback function that will be called on reception of replies for this query. /// Note that the `reply` parameter of the callback is passed by mutable reference, @@ -165,11 +139,11 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { #[no_mangle] pub unsafe extern "C" fn z_get( session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, - options: Option<&mut z_get_options_t>, -) -> i8 { + options: z_get_options_t, +) -> errors::ZCError { let mut closure = z_owned_closure_reply_t::empty(); std::mem::swap(callback, &mut closure); let p = if parameters.is_null() { @@ -177,155 +151,51 @@ pub unsafe extern "C" fn z_get( } else { CStr::from_ptr(parameters).to_str().unwrap() }; - let Some(s) = session.upgrade() else { - log::error!("{LOG_INVALID_SESSION}"); - return i8::MIN; - }; - let mut q = s.get(KeyExpr::try_from(keyexpr).unwrap().with_parameters(p)); - if let Some(options) = options { - q = q - .consolidation(options.consolidation) - .target(options.target.into()); + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); - if let Some(payload) = options.payload.take() { - let mut value = Value::new(payload); - value.encoding = **options.encoding; - q = q.value(value); - } - if options.timeout_ms != 0 { - q = q.timeout(std::time::Duration::from_millis(options.timeout_ms)); + let mut get = session.get(key_expr.clone().with_parameters(p)); + if !options.payload.is_null() { + if let Some(payload) = unsafe { *options.payload }.transmute_mut().extract() { + get = get.payload(payload); } - if z_attachment_check(&options.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - options.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - q = q.attachment(attachment_builder.build()); - }; } - match q - .callback(move |response| z_closure_reply_call(&closure, &mut response.into())) + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + get = get.encoding(encoding); + } + if !options.attachment.is_null() { + let attachment = unsafe { *options.payload }.transmute_mut().extract(); + get = get.attachment(attachment); + } + + get = get.consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .target(options.target.into()); + match get + .callback(move |response| { + z_closure_reply_call(&closure, response.transmute_handle()) }) .res_sync() { - Ok(()) => 0, + Ok(()) => errors::Z_OK, Err(e) => { log::error!("{}", e); - e.errno().get() + errors::Z_EGENERIC } } } -/// Frees `reply_data`, invalidating it for double-drop safety. +/// Frees `reply`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_drop(reply_data: &mut z_owned_reply_t) { - std::mem::drop(reply_data.take()); +pub unsafe extern "C" fn z_reply_drop(this: &mut z_owned_reply_t) { + Inplace::drop(this.transmute_mut()) } -/// Returns ``true`` if `reply_data` is valid. +/// Returns ``true`` if `reply` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_check(reply_data: &z_owned_reply_t) -> bool { - reply_data.is_some() -} - -/// The Queryables that should be target of a :c:func:`z_get`. -/// -/// - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. -/// - **ALL_COMPLETE**: All complete queryables. -/// - **ALL**: All matching queryables. -#[allow(non_camel_case_types)] -#[repr(C)] -#[derive(Clone, Copy)] -pub enum z_query_target_t { - BEST_MATCHING, - ALL, - ALL_COMPLETE, -} - -impl From for z_query_target_t { - #[inline] - fn from(t: QueryTarget) -> Self { - match t { - QueryTarget::BestMatching => z_query_target_t::BEST_MATCHING, - QueryTarget::All => z_query_target_t::ALL, - QueryTarget::AllComplete => z_query_target_t::ALL_COMPLETE, - } - } -} - -impl From for QueryTarget { - #[inline] - fn from(val: z_query_target_t) -> Self { - match val { - z_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, - z_query_target_t::ALL => QueryTarget::All, - z_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, - } - } -} - -/// Create a default :c:type:`z_query_target_t`. -#[no_mangle] -pub extern "C" fn z_query_target_default() -> z_query_target_t { - QueryTarget::default().into() -} - -/// Consolidation mode values. -/// -/// - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector -/// If the selector contains time range properties, consolidation mode `NONE` is used. -/// Otherwise the `LATEST` consolidation mode is used. -/// - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. -/// - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time -/// w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple -/// replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp -/// ts2 > ts1. It optimizes latency. -/// - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. -/// It optimizes bandwidth. -#[repr(C)] -#[derive(Clone, Copy, Default)] -pub enum z_consolidation_mode_t { - AUTO = -1, - #[default] - NONE = 0, - MONOTONIC = 1, - LATEST = 2, -} - -impl From> for z_consolidation_mode_t { - #[inline] - fn from(cm: Mode) -> Self { - match cm { - Mode::Manual(cm) => Self::from(cm), - Mode::Auto => z_consolidation_mode_t::AUTO, - } - } -} - -impl From for z_consolidation_mode_t { - #[inline] - fn from(cm: ConsolidationMode) -> Self { - match cm { - ConsolidationMode::Auto => z_consolidation_mode_t::AUTO, - ConsolidationMode::None => z_consolidation_mode_t::NONE, - ConsolidationMode::Monotonic => z_consolidation_mode_t::MONOTONIC, - ConsolidationMode::Latest => z_consolidation_mode_t::LATEST, - } - } -} - -impl From for Mode { - #[inline] - fn from(val: z_consolidation_mode_t) -> Self { - match val { - z_consolidation_mode_t::AUTO => Mode::Auto, - z_consolidation_mode_t::NONE => Mode::Manual(ConsolidationMode::None), - z_consolidation_mode_t::MONOTONIC => Mode::Manual(ConsolidationMode::Monotonic), - z_consolidation_mode_t::LATEST => Mode::Manual(ConsolidationMode::Latest), - } - } +pub unsafe extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { + this.transmute_ref().is_some() } /// The replies consolidation strategy to apply on replies to a :c:func:`z_get`. diff --git a/src/info.rs b/src/info.rs index b4e523d8a..6a2558a66 100644 --- a/src/info.rs +++ b/src/info.rs @@ -1,3 +1,4 @@ +use crate::transmute::TransmuteCopy; // // Copyright (c) 2017, 2022 ZettaScale Technology. // @@ -11,17 +12,21 @@ // Contributors: // ZettaScale Zenoh team, // -use crate::{session::*, z_closure_zid_call, z_owned_closure_zid_t}; +use std::mem::MaybeUninit; +use crate::{errors, z_closure_zid_call, z_owned_closure_zid_t, z_session_t}; use zenoh::config::ZenohId; use zenoh::prelude::sync::SyncResolve; use zenoh::session::SessionDeclarations; -/// Represents a Zenoh ID. -/// -/// In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. pub use crate::opaque_types::z_id_t; decl_transmute_copy!(ZenohId, z_id_t); +impl From<[u8;16]> for z_id_t { + fn from(value: [u8;16]) -> Self { + unsafe { std::mem::transmute(value) } + } +} + /// Returns the local Zenoh ID. /// /// Unless the `session` is invalid, that ID is guaranteed to be non-zero. @@ -30,10 +35,8 @@ decl_transmute_copy!(ZenohId, z_id_t); #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { - match session.upgrade() { - Some(s) => std::mem::transmute::(s.info().zid().res_sync()), - None => z_id_t { id: [0; 16] }, - } + let session = session.transmute_copy(); + session.info().zid().res_sync().transmute_copy() } /// Fetches the Zenoh IDs of all connected peers. @@ -47,18 +50,14 @@ pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { pub unsafe extern "C" fn z_info_peers_zid( session: z_session_t, callback: &mut z_owned_closure_zid_t, -) -> i8 { +) -> errors::ZCError { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); - match session.upgrade() { - Some(s) => { - for id in s.info().peers_zid().res_sync() { - z_closure_zid_call(&closure, &std::mem::transmute(id)); - } - 0 - } - None => i8::MIN, + let session = session.transmute_copy(); + for id in session.info().peers_zid().res_sync() { + z_closure_zid_call(&closure, &id.transmute_copy()); } + errors::Z_OK } /// Fetches the Zenoh IDs of all connected routers. @@ -72,16 +71,12 @@ pub unsafe extern "C" fn z_info_peers_zid( pub unsafe extern "C" fn z_info_routers_zid( session: z_session_t, callback: &mut z_owned_closure_zid_t, -) -> i8 { +) -> errors::ZCError { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); - match session.upgrade() { - Some(s) => { - for id in s.info().routers_zid().res_sync() { - z_closure_zid_call(&closure, &std::mem::transmute(id)); - } - 0 - } - None => i8::MIN, + let session = session.transmute_copy(); + for id in session.info().routers_zid().res_sync() { + z_closure_zid_call(&closure, &id.transmute_copy()); } + errors::Z_OK } diff --git a/src/keyexpr.rs b/src/keyexpr.rs index a97691ad7..cf19224fa 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -12,133 +12,129 @@ // ZettaScale Zenoh team, // -use std::convert::TryFrom; use std::mem::MaybeUninit; -use std::ops::Deref; -use std::ops::DerefMut; +use crate::errors; +use crate::errors::ZCError; +use crate::errors::Z_OK; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; -use crate::z_bytes_t; +use crate::transmute::TransmuteUninitPtr; +use crate::z_slice_t; use crate::z_owned_str_t; -use crate::z_str_null; -use crate::LOG_INVALID_SESSION; +use crate::z_session_t; use libc::c_char; -use zenoh::core::ErrNo; use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; +use std::error::Error; -/// A zenoh-allocated key expression. -/// -/// Key expressions can identify a single key or a set of keys. -/// -/// Examples : -/// - ``"key/expression"``. -/// - ``"key/ex*"``. -/// -/// Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` -/// for wire and computation efficiency. -/// -/// A `key expression `_ can be either: -/// - A plain string expression. -/// - A pure numerical id. -/// - The combination of a numerical prefix and a string suffix. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_keyexpr_t; -decl_transmute_owned!(default_inplace_init Option>, z_owned_keyexpr_t); +decl_transmute_owned!(Option>, z_owned_keyexpr_t); /// Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { - Inplace::empty(z_owned_keyexpr_t::transmute_uninit_ptr(this)); + Inplace::empty(this.transmute_uninit_ptr()); +} + +fn keyexpr_create_inner(name: &mut str, should_auto_canonize: bool, should_copy: bool) -> Result, Box> { + if should_copy { + let s = name.to_owned(); + match should_auto_canonize { + true => KeyExpr::<'static>::autocanonize(s), + false => KeyExpr::<'static>::try_from(s), + } + } else { + match should_auto_canonize { + true => KeyExpr::<'static>::autocanonize(name), + false => KeyExpr::<'static>::try_from(name), + } + } +} + +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +unsafe fn keyexpr_create(name: &'static mut [u8], should_auto_canonize: bool, should_copy: bool) -> Result, errors::ZCError> { + match std::str::from_utf8_mut(name) { + Ok(name) => { + match keyexpr_create_inner(name, should_auto_canonize, should_copy) { + Ok(v) => { + Ok(v) + } + Err(e) => { + log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); + Err(errors::Z_EINVAL) + } + } + }, + Err(e) => { + log::error!("{}", e); + Err(errors::Z_EPARSE) + } + } } + -/// Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. + +/// Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr_new( - this: *mut MaybeUninit, name: *const c_char, -) -> i8 { - let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); + this: *mut MaybeUninit, +) -> errors::ZCError { if name.is_null() { - Inplace::empty(this); - return -1; + return errors::Z_EINVAL; } - let name = std::slice::from_raw_parts(name as _, libc::strlen(name)); - match std::str::from_utf8(name) { - Ok(name) => match KeyExpr::try_from(name) { - Ok(v) => { - Inplace::init(this, Some(v)); - 0 - } - Err(e) => { - log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); - Inplace::empty(this); - -1 - } + let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); + let this = this.transmute_uninit_ptr(); + match keyexpr_create(name, false, true) { + Ok(ke) => { + Inplace::init(this, Some(ke)); + errors::Z_OK }, Err(e) => { - log::error!("{}", e); Inplace::empty(this); - -1 + e } } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. +/// Constructs a :c:type:`z_owned_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( - this: *mut MaybeUninit, name: *const c_char, -) -> i8 { - let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); + this: *mut MaybeUninit, +) -> ZCError { if name.is_null() { - Inplace::empty(this); - return -1; + return errors::Z_EINVAL; } - 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) => { - Inplace::init(this, Some(v)); - 0 - } - Err(e) => { - log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); - Inplace::empty(this); - -1 - } - } - } + let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); + let this = this.transmute_uninit_ptr(); + match keyexpr_create(name, true, true) { + Ok(ke) => { + Inplace::init(this, Some(ke)); + errors::Z_OK + }, Err(e) => { - log::error!("{}", e); Inplace::empty(this); - -1 + e } } } /// 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 { - unwrap_ref_unchecked(keyexpr.transmute_ref()).transmute_copy() +pub extern "C" fn z_keyexpr_loan(key_expr: &'static z_owned_keyexpr_t) -> z_keyexpr_t { + unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } /// Frees `keyexpr` and invalidates it for double-drop safety. @@ -166,7 +162,7 @@ pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. pub use crate::opaque_types::z_keyexpr_t; -decl_transmute_copy!(&'static KeyExpr<'static>, z_keyexpr_t); +decl_transmute_handle!(KeyExpr<'static>, z_keyexpr_t); #[derive(Debug, Clone, Copy)] pub struct UninitializedKeyExprError; @@ -181,20 +177,11 @@ impl std::error::Error for UninitializedKeyExprError {} /// Otherwise returns error value #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> i8 { - let name = std::slice::from_raw_parts(start as _, len); - match std::str::from_utf8(name) { - Ok(name) => match keyexpr::new(name) { - Ok(_) => 0, - Err(e) => { - log::error!("Couldn't construct a keyexpr from `{}`: {}", name, e); - e.errno().get() - } - }, - Err(e) => { - log::error!("{:02x?} is not valid UTF8 {}", name, e); - i8::MIN - } +pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> ZCError { + let name = std::slice::from_raw_parts_mut(start as _, len); + match keyexpr_create(name, false, false) { + Ok(_) => errors::Z_OK, + Err(e) => e, } } @@ -207,12 +194,12 @@ pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> /// 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_canonize_null_terminated(start: *mut c_char) -> i8 { +pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) -> ZCError { let mut len = libc::strlen(start); match z_keyexpr_canonize(start, &mut len) { - 0 => { + Z_OK => { *start.add(len) = 0; - 0 + Z_OK } err => err, } @@ -226,90 +213,104 @@ pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) /// 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_canonize(start: *mut c_char, len: &mut usize) -> i8 { +pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) -> ZCError { let name = std::slice::from_raw_parts_mut(start as _, *len); - match std::str::from_utf8_mut(name) { - Ok(mut name) => match keyexpr::autocanonize(&mut name) { - Ok(k) => { - *len = k.len(); - 0 - } - Err(e) => { - log::error!("Canonization error: {e}"); - e.errno().get() - } + match keyexpr_create(name, true, false) { + Ok(ke) => { + *len = ke.len(); + errors::Z_OK }, - Err(e) => { - log::error!("{:02x?} is not valid UTF8 {}", name, e); - i8::MIN - } + Err(e) => e, } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string. -/// It is a loaned key expression that aliases `name`. +/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_keyexpr_from_slice(name: *const c_char, len: usize) -> z_keyexpr_t { - let name = std::slice::from_raw_parts(name as _, len); - match std::str::from_utf8(name) { - Ok(name) => match KeyExpr::try_from(name) { - Ok(v) => v.into(), - Err(e) => { - log::error!("Couldn't construct a keyexpr from `{}`: {}", name, e); - z_keyexpr_t::null() - } +pub unsafe extern "C" fn zc_keyexpr_from_slice(this: *mut MaybeUninit, name: *const c_char, len: usize) -> ZCError { + let this = this.transmute_uninit_ptr(); + if name.is_null() { + Inplace::empty(this); + return errors::Z_EINVAL; + } + let name = std::slice::from_raw_parts_mut(name as _, len); + + match keyexpr_create(name, false, false) { + Ok(ke) => { + Inplace::init(this, Some(ke)); + errors::Z_OK }, Err(e) => { - log::error!("{:02x?} is not valid UTF8 {}", name, e); - z_keyexpr_t::null() + Inplace::empty(this); + e } } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string. -/// It is a loaned key expression that aliases `name`. +/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. /// 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( + this: *mut MaybeUninit, name: *mut c_char, len: &mut usize, -) -> z_keyexpr_t { - if z_keyexpr_canonize(name, len) < 0 { - return z_keyexpr_t::null(); +) -> ZCError { + let this = this.transmute_uninit_ptr(); + if name.is_null() { + Inplace::empty(this); + return errors::Z_EINVAL; + } + let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); + + match keyexpr_create(name, true, false) { + Ok(ke) => { + *len = ke.len(); + Inplace::init(this, Some(ke)); + errors::Z_OK + }, + Err(e) => { + Inplace::empty(this); + e + } } - 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)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr(name: *const c_char) -> z_keyexpr_t { +pub unsafe extern "C" fn z_keyexpr(this: *mut MaybeUninit, name: *const c_char) -> ZCError { if name.is_null() { - z_keyexpr_t::null() + Inplace::empty(this.transmute_uninit_ptr()); + return errors::Z_EINVAL; } else { - zc_keyexpr_from_slice(name, libc::strlen(name)) + let len = libc::strlen(name); + zc_keyexpr_from_slice(this, name, len) } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string. -/// It is a loaned key expression that aliases `name`. +/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. /// 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() +pub unsafe extern "C" fn z_keyexpr_autocanonize(this: *mut MaybeUninit, name: *mut c_char) -> ZCError { + if name.is_null() { + Inplace::empty(this.transmute_uninit_ptr()); + return errors::Z_EINVAL; } else { - z_keyexpr(name) + let mut len = libc::strlen(name); + let res = zc_keyexpr_from_slice_autocanonize(this, name, &mut len); + if res == errors::Z_OK { + *name.add(len) = 0; + } + res } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: /// - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -320,16 +321,17 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize(name: *mut c_char) -> z_keyexpr_ #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( + this: *mut MaybeUninit, start: *const c_char, len: usize, -) -> z_keyexpr_t { +) { let name = std::slice::from_raw_parts(start as _, len); let name = std::str::from_utf8_unchecked(name); let name: KeyExpr = keyexpr::from_str_unchecked(name).into(); - name.into() + Inplace::init(this.transmute_uninit_ptr(), Some(name)); } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: /// /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: @@ -341,19 +343,16 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_unchecked(name: *const c_char) -> z_keyexpr_t { - zc_keyexpr_from_slice_unchecked(name, libc::strlen(name)) +pub unsafe extern "C" fn z_keyexpr_unchecked(this: *mut MaybeUninit, name: *const c_char) { + zc_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) } /// Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_to_string(keyexpr: z_keyexpr_t) -> z_owned_str_t { - match keyexpr.as_ref() { - Some(ke) => ke.as_bytes().into(), - None => z_str_null(), - } +pub unsafe extern "C" fn z_keyexpr_to_string(ke: z_keyexpr_t) -> z_owned_str_t { + ke.transmute_ref().as_bytes().into() } /// Returns the key expression's internal string by aliasing it. @@ -361,28 +360,17 @@ pub unsafe extern "C" fn z_keyexpr_to_string(keyexpr: z_keyexpr_t) -> z_owned_st /// Currently exclusive to zenoh-c #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_keyexpr_as_bytes(keyexpr: z_keyexpr_t) -> z_bytes_t { - match keyexpr.as_ref() { - Some(ke) => z_bytes_t { - start: ke.as_ptr(), - len: ke.len(), - }, - None => z_bytes_t { - start: std::ptr::null(), - len: 0, - }, +pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { + let ke = ke.transmute_ref(); + z_slice_t { + start: ke.as_ptr(), + len: ke.len() } } -impl<'a> From<&'a z_owned_keyexpr_t> for z_keyexpr_t { - fn from(oke: &'a z_owned_keyexpr_t) -> Self { - unsafe { std::mem::transmute_copy(oke) } - } -} - -impl<'a> From<&'a KeyExpr<'a>> for z_keyexpr_t { - fn from(key: &'a KeyExpr<'a>) -> Self { - key.borrowing_clone().into() +impl<'a> From<&'static KeyExpr<'static>> for z_keyexpr_t { + fn from(key: &'static KeyExpr<'static>) -> Self { + key.transmute_handle() } } @@ -398,103 +386,70 @@ impl<'a> From<&'a KeyExpr<'a>> for z_keyexpr_t { pub extern "C" fn z_declare_keyexpr( this: *mut MaybeUninit, session: z_session_t, - keyexpr: z_keyexpr_t, -) -> i8 { - let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); - let key_expr = keyexpr.transmute_copy(); - let session = session.transmute_ref(); - match session.upgrade() { - Some(s) => match s.declare_keyexpr(key_expr).res_sync() { - Ok(id) => { - id.into_owned().into(); - // TODO: store id to keyexpr - } - Err(e) => { - log::debug!("{}", e); - Inplace::empty(this); - i8::MIN - } - }, - None => { - log::debug!("{}", LOG_INVALID_SESSION); + key_expr: z_keyexpr_t, +) -> ZCError { + let this = this.transmute_uninit_ptr(); + let key_expr = key_expr.transmute_ref(); + let session = session.transmute_copy(); + match session.declare_keyexpr(key_expr).res_sync() { + Ok(id) => { + Inplace::init(this, Some(id.into_owned())); + errors::Z_OK + } + Err(e) => { + log::debug!("{}", e); Inplace::empty(this); - i8::MIN + errors::Z_EGENERIC } } } /// Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. +/// The keyxpr is consumed. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_keyexpr(session: z_session_t, kexpr: &mut z_owned_keyexpr_t) -> i8 { - let Some(kexpr) = kexpr.deref_mut().take() else { + let Some(kexpr) = kexpr.transmute_mut().take() else { log::debug!("Attempted to undeclare dropped keyexpr"); return i8::MIN; }; - - match session.upgrade() { - Some(s) => match s.undeclare(kexpr).res() { - Ok(()) => 0, - Err(e) => { - log::debug!("{}", e); - e.errno().get() - } - }, - None => { - log::debug!("{}", LOG_INVALID_SESSION); - i8::MIN + let session = session.transmute_copy(); + match session.undeclare(kexpr).res() { + Ok(()) => errors::Z_OK, + Err(e) => { + log::debug!("{}", e); + errors::Z_EGENERIC } } } #[allow(clippy::missing_safety_doc)] #[no_mangle] -/// Returns ``0`` if both ``left`` and ``right`` are equal. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. -pub extern "C" fn z_keyexpr_equals(left: z_keyexpr_t, right: z_keyexpr_t) -> i8 { - match (&*left, &*right) { - (Some(l), Some(r)) => { - if *l == *r { - 0 - } else { - -1 - } - } - _ => i8::MIN, - } +/// Returns ``0`` if both ``left`` and ``right`` are equal. +pub extern "C" fn z_keyexpr_equals(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { + let l = left.transmute_ref(); + let r = right.transmute_ref(); + *l == *r } #[allow(clippy::missing_safety_doc)] #[no_mangle] /// Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the -/// sets defined by ``left`` and ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. -pub extern "C" fn z_keyexpr_intersects(left: z_keyexpr_t, right: z_keyexpr_t) -> i8 { - match (&*left, &*right) { - (Some(l), Some(r)) => { - if l.intersects(r) { - 0 - } else { - -1 - } - } - _ => i8::MIN, - } +/// sets defined by ``left`` and ``right``. +pub extern "C" fn z_keyexpr_intersects(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { + let l = left.transmute_ref(); + let r = right.transmute_ref(); + l.intersects(r) } #[allow(clippy::missing_safety_doc)] #[no_mangle] /// Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set -/// defined by ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. -pub extern "C" fn z_keyexpr_includes(left: z_keyexpr_t, right: z_keyexpr_t) -> i8 { - match (&*left, &*right) { - (Some(l), Some(r)) => { - if l.includes(r) { - 0 - } else { - -1 - } - } - _ => i8::MIN, - } +/// defined by ``right``. +pub extern "C" fn z_keyexpr_includes(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { + let l = left.transmute_ref(); + let r = right.transmute_ref(); + l.includes(r) } #[allow(clippy::missing_safety_doc)] @@ -510,11 +465,10 @@ pub unsafe extern "C" fn z_keyexpr_concat( left: z_keyexpr_t, right_start: *const c_char, right_len: usize, -) -> z_owned_keyexpr_t { - let left = match left.as_ref() { - Some(l) => l, - None => return z_owned_keyexpr_t::null(), - }; + this: *mut MaybeUninit +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let left = left.transmute_ref(); let right = std::slice::from_raw_parts(right_start as _, right_len); let right = match std::str::from_utf8(right) { Ok(r) => r, @@ -525,14 +479,19 @@ pub unsafe extern "C" fn z_keyexpr_concat( left, e ); - return z_owned_keyexpr_t::null(); + Inplace::empty(this); + return errors::Z_EINVAL; } }; match left.concat(right) { - Ok(result) => result.into(), + Ok(result) => { + Inplace::init(this, Some(result)); + errors::Z_OK + } Err(e) => { log::error!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -541,20 +500,19 @@ pub unsafe extern "C" fn z_keyexpr_concat( #[no_mangle] /// Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. /// In case of error, the return value will be set to its invalidated state. -pub extern "C" fn z_keyexpr_join(left: z_keyexpr_t, right: z_keyexpr_t) -> z_owned_keyexpr_t { - let left = match left.as_ref() { - Some(l) => l, - None => return z_owned_keyexpr_t::null(), - }; - let right = match right.as_ref() { - Some(r) => r, - None => return z_owned_keyexpr_t::null(), - }; +pub extern "C" fn z_keyexpr_join(left: z_keyexpr_t, right: z_keyexpr_t, this: *mut MaybeUninit) -> errors::ZCError { + let left = left.transmute_ref(); + let right = right.transmute_ref(); + let this = this.transmute_uninit_ptr(); match left.join(right.as_str()) { - Ok(result) => result.into(), + Ok(result) => { + Inplace::init(this, Some(result)); + errors::Z_OK + } Err(e) => { log::error!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -593,8 +551,7 @@ pub extern "C" fn z_keyexpr_relation_to( left: z_keyexpr_t, right: z_keyexpr_t, ) -> z_keyexpr_intersection_level_t { - match (&*left, &*right) { - (Some(l), Some(r)) => l.relation_to(r).into(), - _ => z_keyexpr_intersection_level_t::DISJOINT, - } + let l = left.transmute_ref(); + let r = right.transmute_ref(); + l.relation_to(r).into() } diff --git a/src/lib.rs b/src/lib.rs index dde332eaf..ad25e1e28 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,7 @@ pub mod opaque_types; pub use crate::opaque_types::*; mod collections; +pub mod errors; pub use crate::collections::*; mod config; pub use crate::config::*; @@ -31,28 +32,28 @@ mod commons; pub use crate::commons::*; mod payload; pub use crate::payload::*; -// mod keyexpr; -// pub use crate::keyexpr::*; -// mod info; -// pub use crate::info::*; -// mod get; -// pub use crate::get::*; -// mod queryable; -// pub use crate::queryable::*; +mod keyexpr; +pub use crate::keyexpr::*; +mod info; +pub use crate::info::*; +mod get; +pub use crate::get::*; +mod queryable; +pub use crate::queryable::*; // mod put; // pub use crate::put::*; -// mod scouting; -// pub use crate::scouting::*; +mod scouting; +pub use crate::scouting::*; mod session; pub use crate::session::*; // mod subscriber; // pub use crate::subscriber::*; // // mod pull_subscriber; // // pub use crate::pull_subscriber::*; -// mod publisher; -// pub use crate::publisher::*; -// mod closures; -// pub use closures::*; +mod publisher; +pub use crate::publisher::*; +mod closures; +pub use closures::*; // mod liveliness; // pub use liveliness::*; // mod publication_cache; @@ -60,7 +61,6 @@ pub use crate::session::*; // // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. // // mod querying_subscriber; // // pub use querying_subscriber::*; -// pub mod attachment; // pub use platform::*; // pub mod platform; // #[cfg(feature = "shared-memory")] diff --git a/src/payload.rs b/src/payload.rs index 8959e8ac2..4ed3feb3e 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,175 +1,116 @@ +use crate::errors::{self, ZCError}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; -use crate::{z_bytes_empty, z_bytes_t, z_owned_bytes_t, z_owned_str_t}; +use crate::{z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap}; use core::slice; use std::any::Any; +use std::borrow::Cow; +use std::io::{Read, Seek, SeekFrom}; use std::mem::MaybeUninit; use std::slice::from_raw_parts_mut; -use zenoh::buffers::HasReader; -use zenoh::buffers::Reader; -use zenoh::buffers::ZBufReader; -use zenoh::buffers::{SplitBuffer, ZBuf, ZSliceBuffer}; +use zenoh::buffers::{ZSlice, ZSliceBuffer}; +use zenoh::bytes::{ZBytes, ZBytesReader}; -pub use crate::opaque_types::z_owned_buffer_t; -decl_transmute_owned!(Option, z_owned_buffer_t); +pub use crate::opaque_types::z_owned_bytes_t; +decl_transmute_owned!(Option, z_owned_bytes_t); -/// The gravestone value for `z_owned_buffer_t`. +/// The gravestone value for `z_owned_bytes_t`. #[no_mangle] -extern "C" fn z_buffer_null(this: *mut MaybeUninit) { +extern "C" fn z_bytes_null(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); Inplace::empty(this); } -/// Decrements the buffer's reference counter, destroying it if applicable. +/// Decrements the payload's reference counter, destroying it if applicable. /// -/// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. +/// `this` will be reset to `z_buffer_null`, preventing UB on double-frees. #[no_mangle] -extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { - let buffer = buffer.transmute_mut(); - Inplace::drop(buffer); +extern "C" fn z_bytes_drop(this: &mut z_owned_bytes_t) { + let this = this.transmute_mut(); + Inplace::drop(this); } -/// Returns `true` if the buffer is in a valid state. +/// Returns `true` if the payload is in a valid state. #[no_mangle] -extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { - buffer.transmute_ref().is_some() +extern "C" fn z_bytes_check(payload: &z_owned_bytes_t) -> bool { + payload.transmute_ref().is_some() } -/// Loans the buffer, allowing you to call functions that only need a loan of it. +/// Loans the payload, allowing you to call functions that only need a loan of it. #[no_mangle] -extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { - let buffer = buffer.transmute_ref(); - let buffer = unwrap_ref_unchecked(buffer); - buffer.transmute_copy() +extern "C" fn z_bytes_loan(payload: &'static z_owned_bytes_t) -> z_bytes_t { + let payload = payload.transmute_ref(); + let payload = unwrap_ref_unchecked(payload); + payload.transmute_handle() } -/// A loan of a `z_owned_buffer_t`. -/// -/// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. -pub use crate::opaque_types::z_buffer_t; -decl_transmute_copy!(&'static ZBuf, z_buffer_t); +pub use crate::opaque_types::z_bytes_t; +decl_transmute_handle!(ZBytes, z_bytes_t); -/// Increments the buffer's reference count, returning an owned version of the buffer. +/// Increments the payload's reference count, returning an owned version of it. #[no_mangle] -extern "C" fn z_buffer_clone(dst: *mut MaybeUninit, buffer: &z_owned_buffer_t) { +extern "C" fn z_bytes_clone(src: &z_owned_bytes_t, dst: *mut MaybeUninit) { let dst = dst.transmute_uninit_ptr(); - let buffer = buffer.transmute_ref(); - let buffer = buffer.as_ref().map(Clone::clone); - Inplace::init(dst, buffer); -} - -/// Returns the number of slices in the buffer. -/// -/// If the return value is 0 or 1, then the buffer's data is contiguous in memory. -#[no_mangle] -extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { - ZBuf::slices(buffer.transmute_copy()).len() + let src = src.transmute_ref(); + let src = src.as_ref().map(Clone::clone); + Inplace::init(dst, src); } -/// Returns total number bytes in the buffer. -#[no_mangle] -extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { - ZBuf::slices(buffer.transmute_copy()).fold(0, |acc, s| acc + s.len()) -} - -/// Returns the `index`th slice of the buffer, aliasing it. -/// -/// Out of bounds accesses will return `z_bytes_empty`. -#[no_mangle] -extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { - let buf = buffer.transmute_copy(); - ZBuf::slices(buf) - .nth(index) - .map_or(z_bytes_empty(), |slice| slice.into()) -} - -/// An owned payload, backed by a reference counted owner. -/// -/// The `payload` field may be modified, and Zenoh will take the new values into account. -#[allow(non_camel_case_types)] -pub type zc_owned_payload_t = z_owned_buffer_t; - -/// Clones the `payload` by incrementing its reference counter. -#[no_mangle] -pub extern "C" fn zc_payload_rcinc( - dst: *mut MaybeUninit, - payload: &zc_owned_payload_t, -) { - z_buffer_clone(dst, payload) -} -/// Returns `false` if `payload` is the gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { - z_buffer_check(payload) -} -/// Decrements `payload`'s backing refcount, releasing the memory if appropriate. -#[no_mangle] -pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { - z_buffer_drop(payload) -} -/// Constructs `zc_owned_payload_t`'s gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_null(this: *mut MaybeUninit) { - z_buffer_null(this); -} - -/// Returns a :c:type:`zc_payload_t` loaned from `payload`. +/// Returns total number bytes in the payload. #[no_mangle] -pub extern "C" fn zc_payload_loan(payload: &zc_owned_payload_t) -> zc_payload_t { - z_buffer_loan(payload) +extern "C" fn z_bytes_len(payload: z_bytes_t) -> usize { + payload.transmute_ref().len() } -#[allow(non_camel_case_types)] -pub type zc_payload_t = z_buffer_t; - -/// Increments internal payload reference count, returning owned payload. +/// Decodes payload into null-terminated string. #[no_mangle] -pub extern "C" fn zc_payload_clone( - dst: *mut MaybeUninit, - payload: &zc_owned_payload_t, -) { - z_buffer_clone(dst, payload) +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_decode_into_string( + payload: z_bytes_t, + dst: *mut MaybeUninit, +) -> ZCError { + let len = z_bytes_len(payload); + let cstr = z_owned_str_t::preallocate(len); + let payload = payload.transmute_ref(); + payload.reader().read(from_raw_parts_mut(cstr._cstr as *mut u8, len)); + Inplace::init(dst, cstr); + errors::Z_OK } -/// Decodes payload into null-terminated string +/// Decodes payload into bytes map. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_string( - payload: zc_payload_t, - cstr: &mut z_owned_str_t, -) -> i8 { - *cstr = z_owned_str_t::preallocate(zc_payload_len(payload)); - let payload = payload.transmute_copy(); - let mut pos = 0; - for s in payload.slices() { - cstr.insert_unchecked(pos, s); - pos += s.len(); - } - 0 +pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( + payload: z_bytes_t, + dst: *mut MaybeUninit, +) -> ZCError { + let dst = dst.transmute_uninit_ptr(); + let payload = payload.transmute_ref(); + let hm = ZHashMap::from_iter(payload.iter::<(Cow<'static, [u8]>, Cow<'static, [u8]>)>()); + Inplace::init(dst, Some(hm)); + errors::Z_OK } -/// Decodes payload into null-terminated string +/// Decodes payload into owned bytes #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_bytes( - payload: zc_payload_t, - b: &mut z_owned_bytes_t, -) -> i8 { - *b = z_owned_bytes_t::preallocate(zc_payload_len(payload)); - let payload = payload.transmute_copy(); - let mut pos = 0; - for s in payload.slices() { - b.insert_unchecked(pos, s); - pos += s.len(); - } - 0 +pub unsafe extern "C" fn z_bytes_decode_into_bytes( + payload: z_bytes_t, + dst: *mut MaybeUninit, +) -> ZCError { + let len = z_bytes_len(payload); + let b = z_owned_slice_t::preallocate(len); + let payload = payload.transmute_ref(); + payload.reader().read(from_raw_parts_mut(b.start, len)); + Inplace::init(dst, b); + errors::Z_OK } -unsafe impl Send for z_bytes_t {} -unsafe impl Sync for z_bytes_t {} +unsafe impl Send for z_slice_t {} +unsafe impl Sync for z_slice_t {} -impl ZSliceBuffer for z_bytes_t { +impl ZSliceBuffer for z_slice_t { fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.start, self.len) } } @@ -184,77 +125,132 @@ impl ZSliceBuffer for z_bytes_t { /// Encodes byte sequence by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_bytes( - dst: *mut MaybeUninit, - bytes: z_bytes_t, +pub unsafe extern "C" fn z_bytes_encode_from_bytes( + this: *mut MaybeUninit, + bytes: z_slice_t, ) { - let dst = dst.transmute_uninit_ptr(); - let buf = ZBuf::from(bytes); - Inplace::init(dst, Some(buf)); + let this = this.transmute_uninit_ptr(); + let payload = ZBytes::from(ZSlice::from(bytes)); + Inplace::init(this, Some(payload)); +} + +/// Encodes bytes map by copying. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( + this: *mut MaybeUninit, + bytes_map: z_slice_map_t, +) { + let dst = this.transmute_uninit_ptr(); + let hm = bytes_map.transmute_ref(); + let payload = ZBytes::from_iter(hm.iter()); + Inplace::init(dst, Some(payload)); } /// Encodes a null-terminated string by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_string( - dst: *mut MaybeUninit, +pub unsafe extern "C" fn z_bytes_encode_from_string( + this: *mut MaybeUninit, cstr: *const libc::c_char, ) { - let bytes = z_bytes_t { + let bytes = z_slice_t { start: cstr as *const u8, len: libc::strlen(cstr), }; - zc_payload_encode_from_bytes(dst, bytes); -} - -/// Returns total number bytes in the payload. -#[no_mangle] -pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { - z_buffer_len(payload) + z_bytes_encode_from_bytes(this, bytes); } -pub use crate::opaque_types::zc_owned_payload_reader; -decl_transmute_owned!(Option>, zc_owned_payload_reader); +pub use crate::opaque_types::z_owned_bytes_t_reader_t; +decl_transmute_owned!(Option>, z_owned_bytes_t_reader_t); -pub use crate::opaque_types::zc_payload_reader; -decl_transmute_copy!(&'static ZBufReader<'static>, zc_payload_reader); +pub use crate::opaque_types::z_bytes_reader_t; +decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); /// Creates a reader for the specified `payload`. /// /// Returns 0 in case of success, -1 if `payload` is not valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_init( - this: *mut MaybeUninit, - payload: zc_payload_t, +pub unsafe extern "C" fn z_bytes_reader_new( + payload: z_bytes_t, + this: *mut MaybeUninit, ) { let this = this.transmute_uninit_ptr(); - let payload = payload.transmute_copy(); + let payload = payload.transmute_ref(); let reader = payload.reader(); Inplace::init(this, Some(reader)); } +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_reader_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_reader_check(reader: &z_owned_bytes_t_reader_t) -> bool { + let reader = reader.transmute_ref(); + reader.as_ref().is_some() +} + +#[no_mangle] +extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_t_reader_t) { + let reader = this.transmute_mut(); + Inplace::drop(reader); +} + +#[no_mangle] +extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_t_reader_t) -> z_bytes_reader_t { + let reader = reader.transmute_ref(); + let reader = unwrap_ref_unchecked(reader); + reader.transmute_handle() +} + /// Reads data into specified destination. /// /// Will read at most `len` bytes. /// Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_read( - reader: zc_payload_reader, +pub unsafe extern "C" fn z_bytes_reader_read( + reader: z_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { - let reader = reader.transmute_copy(); + let reader = reader.transmute_mut(); let buf = unsafe { from_raw_parts_mut(dest, len) }; - reader.read(buf).map(|n| n.get()).unwrap_or(0) + reader.read(buf).unwrap_or(0) } -/// Returns number of the remaining bytes in the payload -/// +/// Sets the `reader` position indicator for the payload to the value pointed to by offset. +/// The new position is exactly offset bytes measured from the beginning of the payload if origin is SEEK_SET, +/// from the current reader position if origin is SEEK_CUR, and from the end of the payload if origin is SEEK_END. +/// Return ​0​ upon success, negative error code otherwise. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_reader_seek(reader: z_bytes_reader_t, offset: i64, origin: libc::c_int) -> ZCError { + let reader = reader.transmute_mut(); + let pos = match origin { + libc::SEEK_SET => offset.try_into().map(|r| SeekFrom::Start(r)), + libc::SEEK_CUR => Ok(SeekFrom::Current(offset)), + libc::SEEK_END => Ok(SeekFrom::End(offset)), + _ => { return errors::Z_EINVAL; } + }; + match pos.map(|p| reader.seek(p)) { + Ok(_) => 0, + Err(_) => errors::Z_EINVAL + } +} + +/// Returns the read position indicator. +/// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_remaining(reader: zc_payload_reader) -> usize { - let reader = reader.transmute_copy(); - reader.remaining() +pub unsafe extern "C" fn z_bytes_reader_tell(reader: z_bytes_reader_t) -> i64 { + let reader = reader.transmute_mut(); + reader.stream_position().map(|p| p as i64).unwrap_or(-1) } + diff --git a/src/publisher.rs b/src/publisher.rs index c829a8533..833798959 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -12,32 +12,36 @@ // ZettaScale Zenoh team, // +use crate::errors; +use crate::transmute::unwrap_ref_unchecked; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; +use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteUninitPtr; +use crate::z_owned_encoding_t; use crate::zcu_closure_matching_status_call; use crate::zcu_owned_closure_matching_status_t; -use std::ops::{Deref, DerefMut}; -use zenoh::encoding::Encoding; +use std::mem::MaybeUninit; +use std::ptr; +use zenoh::handlers::DefaultHandler; use zenoh::prelude::SessionDeclarations; use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; use zenoh::{ - prelude::{Priority, Value}, + prelude::Priority, publication::MatchingListener, publication::Publisher, - sample::AttachmentBuilder, }; -use crate::attachment::{ - insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, - z_attachment_t, -}; -use libc::c_void; +use zenoh::prelude::SyncResolve; use crate::{ - impl_guarded_transmute, z_congestion_control_t, z_encoding_default, z_encoding_t, z_keyexpr_t, - z_owned_keyexpr_t, z_priority_t, z_session_t, zc_owned_payload_t, GuardedTransmute, - UninitializedKeyExprError, LOG_INVALID_SESSION, + z_congestion_control_t, z_keyexpr_t, + z_priority_t, z_session_t, z_owned_bytes_t }; /// Options passed to the :c:func:`z_declare_publisher` function. @@ -60,47 +64,10 @@ pub extern "C" fn z_publisher_options_default() -> z_publisher_options_t { } } -/// An owned zenoh publisher. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_publisher_t([u64; 7]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_publisher_t([u32; 8]); - -impl_guarded_transmute!(noderefs Option>, z_owned_publisher_t); - -impl<'a> From>> for z_owned_publisher_t { - fn from(val: Option) -> Self { - val.transmute() - } -} -impl Deref for z_owned_publisher_t { - type Target = Option>; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl DerefMut for z_owned_publisher_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl z_owned_publisher_t { - pub fn null() -> Self { - None.into() - } -} +pub use crate::opaque_types::z_owned_publisher_t; +decl_transmute_owned!(Option>, z_owned_publisher_t); +pub use crate::opaque_types::z_publisher_t; +decl_transmute_copy!(&'static Publisher<'static>, z_publisher_t); /// Declares a publisher for the given key expression. /// @@ -109,7 +76,7 @@ impl z_owned_publisher_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression to publish. +/// key_expr: The key expression to publish. /// options: additional options for the publisher. /// /// Returns: @@ -139,92 +106,64 @@ impl z_owned_publisher_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_publisher( session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, options: Option<&z_publisher_options_t>, -) -> z_owned_publisher_t { - match session.upgrade() { - Some(s) => { - let keyexpr = keyexpr.deref().as_ref().map(|s| s.clone().into_owned()); - if let Some(key_expr) = keyexpr { - let mut p = s.declare_publisher(key_expr); - if let Some(options) = options { - p = p - .congestion_control(options.congestion_control.into()) - .priority(options.priority.into()); - } - match p.res_sync() { - Err(e) => { - log::error!("{}", e); - None - } - Ok(publisher) => Some(publisher), - } - } else { - log::error!("{}", UninitializedKeyExprError); - None - } + this: *mut MaybeUninit, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref().clone().into_owned(); + let mut p = session.declare_publisher(key_expr); + if let Some(options) = options { + p = p + .congestion_control(options.congestion_control.into()) + .priority(options.priority.into()); + } + match p.res_sync() { + Err(e) => { + log::error!("{}", e); + Inplace::empty(this); + errors::Z_EGENERIC } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - None + Ok(publisher) => { + Inplace::init(this, Some(publisher)); + errors::Z_OK } } - .into() } /// Constructs a null safe-to-drop value of 'z_owned_publisher_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_null() -> z_owned_publisher_t { - z_owned_publisher_t::null() +pub extern "C" fn z_publisher_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); } /// Returns ``true`` if `pub` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_publisher_check(pbl: &z_owned_publisher_t) -> bool { - pbl.as_ref().is_some() -} - -/// A loaned zenoh publisher. -#[allow(non_camel_case_types)] -#[derive(Clone, Copy)] -#[repr(C)] -pub struct z_publisher_t(*const z_owned_publisher_t); - -impl<'a> AsRef>> for z_owned_publisher_t { - fn as_ref(&self) -> &'a Option> { - unsafe { std::mem::transmute(self) } - } -} - -impl<'a> AsMut>> for z_owned_publisher_t { - fn as_mut(&mut self) -> &'a mut Option> { - unsafe { std::mem::transmute(self) } - } -} - -impl<'a> AsRef>> for z_publisher_t { - fn as_ref(&self) -> &'a Option> { - unsafe { (*self.0).as_ref() } - } +pub extern "C" fn z_publisher_check(pbl: &'static z_owned_publisher_t) -> bool { + pbl.transmute_ref().is_some() } /// Returns a :c:type:`z_publisher_t` loaned from `p`. #[no_mangle] -pub extern "C" fn z_publisher_loan(p: &z_owned_publisher_t) -> z_publisher_t { - z_publisher_t(p) +pub extern "C" fn z_publisher_loan(p: &'static z_owned_publisher_t) -> z_publisher_t { + let p = p.transmute_ref(); + let p = unwrap_ref_unchecked(p); + p.transmute_copy() } /// Options passed to the :c:func:`z_publisher_put` function. /// /// Members: -/// z_encoding_t encoding: The encoding of the payload. -/// z_attachment_t attachment: The attachment to attach to the publication. +/// z_owned_encoding_t encoding: The encoding of the payload. +/// z_owned_bytes_t attachment: The attachment to attach to the publication. #[repr(C)] pub struct z_publisher_put_options_t { - pub encoding: z_encoding_t, - pub attachment: z_attachment_t, + pub encoding: *mut z_owned_encoding_t, + pub attachment: *mut z_owned_bytes_t, } /// Constructs the default value for :c:type:`z_publisher_put_options_t`. @@ -232,8 +171,8 @@ pub struct z_publisher_put_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t { z_publisher_put_options_t { - encoding: z_encoding_default(), - attachment: z_attachment_null(), + encoding: ptr::null_mut(), + attachment: ptr::null_mut(), } } @@ -243,7 +182,7 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t /// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher /// - constructed from a `zc_owned_shmbuf_t` /// -/// The payload's encoding can be sepcified through the options. +/// The payload and all owned options fields are consumed upon function return. /// /// Parameters: /// session: The zenoh session. @@ -255,39 +194,34 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_publisher_put( publisher: z_publisher_t, - payload: Option<&mut zc_owned_payload_t>, - options: Option<&z_publisher_put_options_t>, -) -> i8 { - if let Some(p) = publisher.as_ref() { - let Some(payload) = payload.and_then(|p| p.take()) else { - log::debug!("Attempted to put without a payload"); - return i8::MIN; - }; - let put = match options { - Some(options) => { - let encoding = *options.encoding; - let mut put = p.put(payload).encoding(*encoding); - if z_attachment_check(&options.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - options.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - put = put.attachment(attachment_builder.build()); - }; - put - } - None => p.put(payload), - }; - if let Err(e) = put.res_sync() { - log::error!("{}", e); - e.errno().get() - } else { - 0 + payload: &mut z_owned_bytes_t, + options: z_publisher_put_options_t, +) -> errors::ZCError { + let publisher = publisher.transmute_copy(); + let payload = match payload.transmute_mut().extract() { + Some(p) => p, + None => { + log::debug!("Attempted to put with a null payload"); + return errors::Z_EINVAL; } + }; + + let mut put = publisher.put(payload); + + if !options.encoding.is_null() { + let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + put = put.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + put = put.attachment(attachment); + } + + if let Err(e) = put.res_sync() { + log::error!("{}", e); + errors::Z_EGENERIC } else { - i8::MIN + errors::Z_OK } } @@ -315,60 +249,28 @@ pub extern "C" fn z_publisher_delete_options_default() -> z_publisher_delete_opt #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_delete( publisher: z_publisher_t, - _options: *const z_publisher_delete_options_t, -) -> i8 { - if let Some(p) = publisher.as_ref() { - if let Err(e) = p.delete().res_sync() { - log::error!("{}", e); - e.errno().get() - } else { - 0 - } + _options: z_publisher_delete_options_t, +) -> errors::ZCError { + let publisher = publisher.transmute_copy(); + + if let Err(e) = publisher.delete().res_sync() { + log::error!("{}", e); + errors::Z_EGENERIC } else { - i8::MIN + errors::Z_OK } } /// Returns the key expression of the publisher #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_owned_keyexpr_t { - if let Some(p) = publisher.as_ref() { - p.key_expr().clone().into() - } else { - z_keyexpr_t::null().into() - } +pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_keyexpr_t { + let publisher = publisher.transmute_copy(); + publisher.key_expr().transmute_handle() } -/// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C, align(8))] -pub struct zcu_owned_matching_listener_t([u64; 4]); - -impl_guarded_transmute!(noderefs - Option>, - zcu_owned_matching_listener_t -); - -impl From>> for zcu_owned_matching_listener_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} - -impl zcu_owned_matching_listener_t { - pub fn null() -> Self { - None.into() - } -} +pub use crate::opaque_types::zcu_owned_matching_listener_t; +decl_transmute_owned!(Option>, zcu_owned_matching_listener_t); /// A struct that indicates if there exist Subscribers matching the Publisher's key expression. /// @@ -386,38 +288,42 @@ pub struct zcu_matching_status_t { pub extern "C" fn zcu_publisher_matching_listener_callback( publisher: z_publisher_t, callback: &mut zcu_owned_closure_matching_status_t, -) -> zcu_owned_matching_listener_t { + this: *mut MaybeUninit +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); std::mem::swap(callback, &mut closure); - { - if let Some(p) = publisher.as_ref() { - let listener = p - .matching_listener() - .callback_mut(move |matching_status| { - let status = zcu_matching_status_t { - matching: matching_status.matching_subscribers(), - }; - zcu_closure_matching_status_call(&closure, &status); - }) - .res() - .unwrap(); - Some(listener) - } else { - None - } + let publisher = publisher.transmute_copy(); + let listener = publisher + .matching_listener() + .callback_mut(move |matching_status| { + let status = zcu_matching_status_t { + matching: matching_status.matching_subscribers(), + }; + zcu_closure_matching_status_call(&closure, &status); + }) + .res(); + match listener { + Ok(l) => { + Inplace::empty(this); + errors::Z_OK + }, + Err(e) => { + log::error!("{}", e); + errors::Z_EGENERIC + } } - .into() } /// Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> i8 { - if let Some(p) = publisher.take() { +pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> errors::ZCError { + if let Some(p) = publisher.transmute_mut().extract().take() { if let Err(e) = p.undeclare().res_sync() { log::error!("{}", e); - return e.errno().get(); + return errors::Z_EGENERIC; } } - 0 + errors::Z_OK } diff --git a/src/put.rs b/src/put.rs index 59e9e5e3c..c2d1bddd2 100644 --- a/src/put.rs +++ b/src/put.rs @@ -14,7 +14,7 @@ use crate::commons::*; use crate::keyexpr::*; use crate::session::*; -use crate::zc_owned_payload_t; +use crate::z_owned_bytes_t; use crate::LOG_INVALID_SESSION; use libc::c_void; use zenoh::encoding; @@ -27,103 +27,23 @@ use zenoh::sample::ValueBuilderTrait; use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, - z_attachment_t, + z_bytes_t, }; -/// The priority of zenoh messages. -/// -/// - **REAL_TIME** -/// - **INTERACTIVE_HIGH** -/// - **INTERACTIVE_LOW** -/// - **DATA_HIGH** -/// - **DATA** -/// - **DATA_LOW** -/// - **BACKGROUND** -#[allow(non_camel_case_types)] -#[repr(C)] -#[derive(Clone, Copy)] -pub enum z_priority_t { - REAL_TIME = 1, - INTERACTIVE_HIGH = 2, - INTERACTIVE_LOW = 3, - DATA_HIGH = 4, - DATA = 5, - DATA_LOW = 6, - BACKGROUND = 7, -} - -impl From for z_priority_t { - fn from(p: Priority) -> Self { - match p { - Priority::RealTime => z_priority_t::REAL_TIME, - Priority::InteractiveHigh => z_priority_t::INTERACTIVE_HIGH, - Priority::InteractiveLow => z_priority_t::INTERACTIVE_LOW, - Priority::DataHigh => z_priority_t::DATA_HIGH, - Priority::Data => z_priority_t::DATA, - Priority::DataLow => z_priority_t::DATA_LOW, - Priority::Background => z_priority_t::BACKGROUND, - } - } -} - -impl From for Priority { - fn from(p: z_priority_t) -> Self { - match p { - z_priority_t::REAL_TIME => Priority::RealTime, - z_priority_t::INTERACTIVE_HIGH => Priority::InteractiveHigh, - z_priority_t::INTERACTIVE_LOW => Priority::InteractiveLow, - z_priority_t::DATA_HIGH => Priority::DataHigh, - z_priority_t::DATA => Priority::Data, - z_priority_t::DATA_LOW => Priority::DataLow, - z_priority_t::BACKGROUND => Priority::Background, - } - } -} - -/// The kind of congestion control. -/// -/// - **BLOCK** -/// - **DROP** -#[allow(non_camel_case_types)] -#[repr(C)] -#[derive(Clone, Copy)] -pub enum z_congestion_control_t { - BLOCK, - DROP, -} - -impl From for z_congestion_control_t { - fn from(cc: CongestionControl) -> Self { - match cc { - CongestionControl::Block => z_congestion_control_t::BLOCK, - CongestionControl::Drop => z_congestion_control_t::DROP, - } - } -} - -impl From for CongestionControl { - fn from(cc: z_congestion_control_t) -> Self { - match cc { - z_congestion_control_t::BLOCK => CongestionControl::Block, - z_congestion_control_t::DROP => CongestionControl::Drop, - } - } -} - /// Options passed to the :c:func:`z_put` function. /// /// Members: /// z_encoding_t encoding: The encoding of the payload. /// z_congestion_control_t congestion_control: The congestion control to apply when routing this message. /// z_priority_t priority: The priority of this message. -/// z_attachment_t attachment: The attachment to this message. +/// z_bytes_t attachment: The attachment to this message. #[repr(C)] #[allow(non_camel_case_types)] pub struct z_put_options_t { pub encoding: z_encoding_t, pub congestion_control: z_congestion_control_t, pub priority: z_priority_t, - pub attachment: z_attachment_t, + pub attachment:z_bytes_t, } /// Constructs the default value for :c:type:`z_put_options_t`. @@ -158,7 +78,7 @@ pub extern "C" fn z_put_options_default() -> z_put_options_t { pub extern "C" fn z_put( session: z_session_t, keyexpr: z_keyexpr_t, - payload: Option<&mut zc_owned_payload_t>, + payload: Option<&mut z_owned_bytes_t>, opts: Option<&z_put_options_t>, ) -> i8 { match session.upgrade() { @@ -188,7 +108,7 @@ pub extern "C" fn z_put( Ok(()) => 0, } } else { - log::debug!("zc_payload_null was provided as payload for put"); + log::debug!("z_bytes_null was provided as payload for put"); i8::MIN } } diff --git a/src/queryable.rs b/src/queryable.rs index 30baf5af2..875918cab 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -11,52 +11,29 @@ // Contributors: // ZettaScale Zenoh team, // -use crate::attachment::{ - attachment_iteration_driver, insert_in_attachment_builder, z_attachment_check, - z_attachment_iterate, z_attachment_null, z_attachment_t, -}; -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteRef}; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}; use crate::{ - z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, z_keyexpr_t, - z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, zc_payload_t, - LOG_INVALID_SESSION, + errors, z_slice_t, z_closure_query_call, z_keyexpr_t,z_owned_bytes_t, z_owned_closure_query_t, z_owned_encoding_t, z_session_t, z_value_t, z_bytes_t }; -use libc::c_void; +use zenoh::sample::{SampleBuilderTrait, ValueBuilderTrait}; use std::mem::MaybeUninit; -use std::ops::{Deref, DerefMut}; +use std::ptr::null_mut; use zenoh::prelude::SessionDeclarations; -use zenoh::{ - prelude::Sample, - queryable::{Query, Queryable}, - sample::AttachmentBuilder, -}; +use zenoh::prelude::{Query, Queryable}; +use zenoh::prelude::SyncResolve; -/// An owned zenoh queryable. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_queryable_t; -decl_transmute_owned!(default_inplace_init Option>, z_owned_queryable_t); +decl_transmute_owned!(Option>, z_owned_queryable_t); /// Constructs a null safe-to-drop value of 'z_owned_queryable_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_queryable_null(this: *mut MaybeUninit) { - Inplace::empty(z_owned_queryable_t::transmute_uninit_ptr(this)); + Inplace::empty(this.transmute_uninit_ptr()); } -// Loaned variant of a Query received by a Queryable. -/// -/// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. -/// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. pub use crate::opaque_types::z_query_t; -decl_transmute_copy!(&'static Query, z_query_t); +decl_transmute_handle!(Query, z_query_t); /// Owned variant of a Query received by a Queryable. /// @@ -67,12 +44,12 @@ decl_transmute_copy!(&'static Query, z_query_t); /// Holding onto an `z_owned_query_t` for too long (10s by default, can be set in `z_get`'s options) will trigger a timeout error /// to be sent to the querier by the infrastructure, and new responses to the outdated query will be silently dropped. pub use crate::opaque_types::z_owned_query_t; -decl_transmute_owned!(default_inplace_init Option, z_owned_query_t); +decl_transmute_owned!(Option, z_owned_query_t); /// The gravestone value of `z_owned_query_t`. #[no_mangle] -pub extern "C" fn z_query_null(query: *mut MaybeUninit) { - Inplace::empty(z_owned_query_t::transmute_uninit_ptr(query)); +pub extern "C" fn z_query_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } /// Returns `false` if `this` is in a gravestone state, `true` otherwise. /// @@ -85,10 +62,10 @@ pub extern "C" fn z_query_check(query: &z_owned_query_t) -> bool { /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] -pub extern "C" fn z_query_loan(this: &z_owned_query_t) -> z_query_t { +pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> z_query_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); - this.transmute_copy() + this.transmute_handle() } /// Destroys the query, setting `this` to its gravestone value to prevent double-frees. /// @@ -101,9 +78,11 @@ pub extern "C" fn z_query_drop(this: &mut z_owned_query_t) { /// /// This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). #[no_mangle] -pub extern "C" fn z_query_clone(query: z_query_t) -> z_owned_query_t { - let query = query.transmute_copy(); - query.and_then(|q| q.cloned()).into() +pub extern "C" fn z_query_clone(this: *mut MaybeUninit, query: z_query_t) { + let query = query.transmute_ref(); + let query = query.clone(); + let this = this.transmute_uninit_ptr(); + Inplace::init(this, Some(query)); } /// Options passed to the :c:func:`z_declare_queryable` function. @@ -126,13 +105,13 @@ pub extern "C" fn z_queryable_options_default() -> z_queryable_options_t { /// sent via :c:func:`z_query_reply`. /// /// Members: -/// z_encoding_t encoding: The encoding of the payload. -/// z_attachment_t attachment: The attachment to this reply. +/// z_owned_encoding_t encoding: The encoding of the payload. +/// z_owned_bytes_t attachment: The attachment to this reply. #[allow(non_camel_case_types)] #[repr(C)] pub struct z_query_reply_options_t { - pub encoding: z_encoding_t, - pub attachment: z_attachment_t, + pub encoding: *mut z_owned_encoding_t, + pub attachment: *mut z_owned_bytes_t, } /// Constructs the default value for :c:type:`z_query_reply_options_t`. @@ -140,8 +119,8 @@ pub struct z_query_reply_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { z_query_reply_options_t { - encoding: z_encoding_default(), - attachment: z_attachment_null(), + encoding: null_mut(), + attachment: null_mut(), } } @@ -149,7 +128,7 @@ pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression the Queryable will reply to. +/// key_expr: The key expression the Queryable will reply to. /// callback: The callback function that will be called each time a matching query is received. /// options: Options for the queryable. /// @@ -159,30 +138,33 @@ pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { #[no_mangle] pub extern "C" fn z_declare_queryable( session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_query_t, options: Option<&z_queryable_options_t>, -) -> z_owned_queryable_t { + this: *mut MaybeUninit +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut closure, callback); - - let session = match session.upgrade() { - Some(s) => s, - None => { - log::error!("{}", LOG_INVALID_SESSION); - return None.into(); - } - }; + let session = session.transmute_copy(); + let keyexpr = key_expr.transmute_ref(); let mut builder = session.declare_queryable(keyexpr); if let Some(options) = options { builder = builder.complete(options.complete); } - builder - .callback(move |query| z_closure_query_call(&closure, &z_query_t::from(&query))) - .res_sync() - .map_err(|e| log::error!("{}", e)) - .ok() - .into() + let queryable = builder + .callback(move |query| z_closure_query_call(&closure, query.transmute_handle())) + .res_sync(); + match queryable { + Ok(q) => { + Inplace::init(this, Some(q)); + errors::Z_OK + } + Err(e) => { + log::error!("{}", e); + errors::Z_EGENERIC + } + } } /// Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. @@ -191,21 +173,20 @@ pub extern "C" fn z_declare_queryable( /// qable: The :c:type:`z_owned_queryable_t` to undeclare. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> i8 { - if let Some(qable) = qable.take() { +pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> errors::ZCError { + if let Some(qable) = qable.transmute_mut().extract().take() { if let Err(e) = qable.undeclare().res_sync() { log::error!("{}", e); - return e.errno().get(); + return errors::Z_EGENERIC; } } - 0 + errors::Z_OK } /// Returns ``true`` if `qable` is valid. -#[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { - qable.as_ref().is_some() + qable.transmute_ref().is_some() } /// Send a reply to a query. @@ -217,93 +198,90 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { /// /// Parameters: /// query: The query to reply to. -/// key: The key of this reply. +/// key_expr: The key of this reply. /// payload: The value of this reply. /// options: The options of this reply. +/// +/// The payload and all owned options fields are consumed upon function return. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_reply( - query: &z_query_t, - key: z_keyexpr_t, - payload: Option<&mut zc_owned_payload_t>, - options: Option<&z_query_reply_options_t>, -) -> i8 { - let Some(query) = query.as_ref() else { - log::error!("Called `z_query_reply` with invalidated `query`"); - return i8::MIN; + query: z_query_t, + key_expr: z_keyexpr_t, + payload: &mut z_owned_bytes_t, + options: z_query_reply_options_t, +) -> errors::ZCError { + let query = query.transmute_ref(); + let key_expr = key_expr.transmute_ref(); + + let payload = match payload.transmute_mut().extract() { + Some(p) => p, + None => { + log::debug!("Attempted to reply with a null payload"); + return errors::Z_EINVAL; + } + }; + + let mut reply = query.reply(key_expr, payload); + + if !options.encoding.is_null() { + let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + reply = reply.encoding(encoding); }; - if let Some(key) = &*key { - // TODO: reimplement with reply builder - // - // if let Some(payload) = payload.and_then(|p| p.take()) { - // let mut s = Sample::new(key.clone().into_owned(), payload); - // if let Some(o) = options { - // s.encoding = o.encoding.into(); - // if z_attachment_check(&o.attachment) { - // let mut attachment_builder = AttachmentBuilder::new(); - // z_attachment_iterate( - // o.attachment, - // insert_in_attachment_builder, - // &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - // ); - // s = s.with_attachment(attachment_builder.build()); - // }; - // } - // if let Err(e) = query.reply(Ok(s)).res_sync() { - // log::error!("{}", e); - // return e.errno().get(); - // } - // return 0; - // } + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + reply = reply.attachment(attachment); } - i8::MIN + + if let Err(e) = reply.res_sync() { + log::error!("{}", e); + return errors::Z_EGENERIC; + } + return errors::Z_OK; } /// Get a query's key by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> z_keyexpr_t { - let Some(query) = query.as_ref() else { - return z_keyexpr_t::null(); - }; - query.key_expr().borrowing_clone().into() +pub extern "C" fn z_query_keyexpr(query: z_query_t) -> z_keyexpr_t { + query.transmute_ref().key_expr().transmute_handle() } /// Get a query's `value selector `_ by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_bytes_t { - let Some(query) = query.as_ref() else { - return z_bytes_t::empty(); - }; - let complement = query.parameters(); - z_bytes_t { - start: complement.as_ptr(), - len: complement.len(), +pub extern "C" fn z_query_parameters(query: z_query_t) -> z_slice_t { + let query = query.transmute_ref(); + let params = query.parameters().as_str(); + z_slice_t { + start: params.as_ptr(), + len: params.len(), } } -/// Get a query's `payload value `_ by aliasing it. +/// Checks if query contains a payload value. +pub extern "C" fn z_query_has_value(query: z_query_t) -> bool { + query.transmute_ref().value().is_some() +} + +/// Checks if query contains an attachment. +pub extern "C" fn z_query_has_attachment(query: z_query_t) -> bool { + query.transmute_ref().attachment().is_some() +} + +/// Gets a query's `payload value `_ by aliasing it. /// /// **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** -#[allow(clippy::missing_safety_doc)] +/// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] -pub unsafe extern "C" fn z_query_value(query: &z_query_t) -> z_value_t { - let v = query.as_ref().and_then(|q| q.value()); - v.into() +pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { + query.transmute_ref().value().expect("Query does not contain a value").transmute_copy() } -/// Returns the attachment to the query by aliasing. +/// Gets the attachment to the query by aliasing. /// -/// `z_check(return_value) == false` if there was no attachment to the query. -#[allow(clippy::missing_safety_doc)] +/// Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. #[no_mangle] -pub unsafe extern "C" fn z_query_attachment(query: &z_query_t) -> z_attachment_t { - match query.as_ref().and_then(|q| q.attachment()) { - Some(attachment) => z_attachment_t { - data: attachment as *const _ as *mut c_void, - iteration_driver: Some(attachment_iteration_driver), - }, - None => z_attachment_null(), - } +pub extern "C" fn z_query_attachment(query: z_query_t) -> z_bytes_t { + query.transmute_ref().attachment().expect("Query does not contain an attachment").transmute_handle() } diff --git a/src/scouting.rs b/src/scouting.rs index c7dd80be7..61cba7426 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -12,12 +12,11 @@ // ZettaScale Zenoh team, // 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, CopyableToCArray, + errors::{self, Z_OK}, transmute::{Inplace, TransmuteRef}, z_closure_hello_call, z_config_check, z_config_clone, z_config_drop, z_config_new, z_config_null, z_config_t, z_id_t, 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, os::raw::c_void}; +use std::{ffi::CString, mem::MaybeUninit, os::raw::c_void}; use zenoh::scouting::Hello; use zenoh_protocol::core::{whatami::WhatAmIMatcher, WhatAmI}; use zenoh_util::core::AsyncResolve; @@ -157,7 +156,7 @@ pub extern "C" fn z_hello_loan(hello: &z_owned_hello_t) -> z_hello_t { pub extern "C" fn z_hello_null() -> z_owned_hello_t { z_owned_hello_t { _whatami: 0, - _pid: z_id_t { id: [0; 16] }, + _pid: [0; 16].into(), _locators: z_owned_str_array_t { val: std::ptr::null_mut(), len: 0, @@ -188,32 +187,47 @@ pub const DEFAULT_SCOUTING_TIMEOUT: c_ulong = 1000; #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_scouting_config_null() -> z_owned_scouting_config_t { - z_owned_scouting_config_t { - _config: z_config_null(), +pub extern "C" fn z_scouting_config_null(this: *mut MaybeUninit) { + let mut _config = MaybeUninit::::uninit(); + z_config_null(&mut _config as *mut MaybeUninit); + let _config = unsafe { _config.assume_init() }; + + let config = z_owned_scouting_config_t { + _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, - } + }; + (unsafe { &mut *this }).write(config); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_scouting_config_default() -> z_owned_scouting_config_t { - z_owned_scouting_config_t { - _config: z_config_default(), +pub extern "C" fn z_scouting_config_default(this: *mut MaybeUninit) { + let mut _config = MaybeUninit::::uninit(); + z_config_new(&mut _config as *mut MaybeUninit); + let _config = unsafe { _config.assume_init() }; + + let config = z_owned_scouting_config_t { + _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, - } + }; + (unsafe { &mut *this }).write(config); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_scouting_config_from(config: z_config_t) -> z_owned_scouting_config_t { - z_owned_scouting_config_t { - _config: config.as_ref().clone().into(), +pub extern "C" fn z_scouting_config_from(config: z_config_t, this: *mut MaybeUninit) { + let mut dst = MaybeUninit::uninit(); + z_config_clone(&config, &mut dst as *mut _); + let _config = unsafe { dst.assume_init() }; + + let config = z_owned_scouting_config_t { + _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, - } + }; + (unsafe { &mut *this }).write(config); } #[no_mangle] @@ -225,7 +239,7 @@ pub extern "C" fn z_scouting_config_check(config: &z_owned_scouting_config_t) -> #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_scouting_config_drop(config: &mut z_owned_scouting_config_t) { - std::mem::drop(std::mem::replace(config, z_scouting_config_null())); + z_config_drop(&mut config._config) } /// Scout for routers and/or peers. @@ -241,16 +255,17 @@ pub extern "C" fn z_scouting_config_drop(config: &mut z_owned_scouting_config_t) pub extern "C" fn z_scout( config: &mut z_owned_scouting_config_t, callback: &mut z_owned_closure_hello_t, -) -> i8 { +) -> errors::ZCError { if cfg!(feature = "logger-autoinit") { zc_init_logger(); } - let config = std::mem::replace(config, z_scouting_config_null()); let what = WhatAmIMatcher::try_from(config.zc_what).unwrap_or(WhatAmI::Router | WhatAmI::Peer); #[allow(clippy::unnecessary_cast)] // Required for multi-target let timeout = config.zc_timeout_ms as u64; - let mut config = config._config; - let config = config.as_mut().take().expect("invalid config"); + let config = match config._config.transmute_mut().extract().take() { + Some(c) => c, + None => { return errors::Z_EINVAL ;} + }; let mut closure = z_owned_closure_hello_t::empty(); std::mem::swap(&mut closure, callback); @@ -266,7 +281,7 @@ pub extern "C" fn z_scout( async_std::task::sleep(std::time::Duration::from_millis(timeout)).await; std::mem::drop(scout); }); - 0 + Z_OK } /// Converts the kind of zenoh entity into a string. diff --git a/src/session.rs b/src/session.rs index 7f758d330..86682da16 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,25 +12,14 @@ // ZettaScale Zenoh team, // -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; -use crate::{config::*, z_owned_config_t, zc_init_logger}; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr}; +use crate::{errors, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; -use std::ops::Deref; -use std::sync::{Arc, Weak}; +use std::sync::Arc; use zenoh::core::ErrNo; use zenoh::prelude::sync::SyncResolve; use zenoh::session::Session; -/// An owned zenoh session. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. use crate::opaque_types::z_owned_session_t; decl_transmute_owned!(Option>, z_owned_session_t); @@ -47,7 +36,7 @@ decl_transmute_copy!(&'static Session, z_session_t); /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(s: &z_owned_session_t) -> z_session_t { +pub extern "C" fn z_session_loan(s: &'static z_owned_session_t) -> z_session_t { let s = s.transmute_ref(); let s = unwrap_ref_unchecked(s); let s = s.as_ref(); @@ -58,37 +47,38 @@ pub extern "C" fn z_session_loan(s: &z_owned_session_t) -> z_session_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_session_null(s: *mut MaybeUninit) { - Inplace::empty(z_owned_session_t::transmute_uninit_ptr(s)); + Inplace::empty(s.transmute_uninit_ptr()); } /// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. +/// Config value is always consumed upon function return. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_open( this: *mut MaybeUninit, config: &mut z_owned_config_t, -) -> i8 { - let this = z_owned_session_t::transmute_uninit_ptr(this); +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); if cfg!(feature = "logger-autoinit") { zc_init_logger(); } - let config = match config.as_mut().take() { + let config = match config.transmute_mut().take() { Some(c) => c, None => { log::error!("Config not provided"); Inplace::empty(this); - return -1; + return errors::Z_EINVAL; } }; match zenoh::open(*config).res() { Ok(s) => { Inplace::init(this, Some(Arc::new(s))); - 0 + errors::Z_OK } Err(e) => { log::error!("Error opening session: {}", e); Inplace::empty(this); - -1 + errors::Z_ENETWORK } } } @@ -131,7 +121,7 @@ pub extern "C" fn zc_session_rcinc( src: &z_owned_session_t, ) -> i8 { // session.as_ref().as_ref().and_then(|s| s.upgrade()).into() - let dst = z_owned_session_t::transmute_uninit_ptr(dst); + let dst = dst.transmute_uninit_ptr(); let Some(src) = src.transmute_ref() else { return -1; }; diff --git a/src/shm.rs b/src/shm.rs index 50f8b7236..52f9d51cd 100644 --- a/src/shm.rs +++ b/src/shm.rs @@ -23,7 +23,7 @@ use zenoh::{ shm::{SharedMemoryBuf, SharedMemoryManager}, }; -use crate::{z_session_t, zc_owned_payload_t, zc_payload_null}; +use crate::{z_session_t, z_owned_bytes_t, z_bytes_null}; #[repr(C)] pub struct zc_owned_shm_manager_t(usize); @@ -179,10 +179,10 @@ pub extern "C" fn zc_shmbuf_null() -> zc_owned_shmbuf_t { /// Constructs an owned payload from an owned SHM buffer. #[no_mangle] -pub extern "C" fn zc_shmbuf_into_payload(buf: &mut zc_owned_shmbuf_t) -> zc_owned_payload_t { +pub extern "C" fn zc_shmbuf_into_payload(buf: &mut zc_owned_shmbuf_t) -> z_owned_bytes_t { match buf.get_mut().take() { Some(buf) => ZBuf::from(buf).try_into().unwrap_or_default(), - None => zc_payload_null(), + None => z_bytes_null(), } } diff --git a/src/transmute.rs b/src/transmute.rs index 3fe026532..4aaa3d157 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -16,6 +16,8 @@ // unsafe { std::mem::transmute::<&'a T, &'static T>(value) } // } +use std::mem::MaybeUninit; + pub fn unwrap_ref_unchecked(value: &Option) -> &T { debug_assert!(value.is_some()); unsafe { value.as_ref().unwrap_unchecked() } @@ -26,6 +28,15 @@ pub(crate) trait TransmuteRef: Sized { fn transmute_mut(&mut self) -> &mut T; } +pub(crate) trait TransmuteFromHandle: Sized { + fn transmute_ref(self) -> &'static T; + fn transmute_mut(self) -> &'static mut T; +} + +pub(crate) trait TransmuteIntoHandle: Sized { + fn transmute_handle(&self) -> T; +} + pub(crate) trait TransmuteCopy { fn transmute_copy(self) -> T; } @@ -50,6 +61,15 @@ pub(crate) trait Inplace: Sized { unsafe { std::ptr::drop_in_place(this) }; Inplace::empty(this as *mut std::mem::MaybeUninit); } + + // Move the object out of this, leaving it in empty state + fn extract(self: &mut Self) -> Self { + let mut out: MaybeUninit = MaybeUninit::uninit(); + Self::empty(&mut out); + let mut out = unsafe { out.assume_init() }; + std::mem::swap(&mut out, self); + out + } // TODO: for effective inplace_init, we can provide a method that takes a closure that initializes the object in place } @@ -125,6 +145,14 @@ macro_rules! decl_transmute_copy { }; } +#[macro_export] +macro_rules! decl_transmute_handle { + ($zenoh_type:ty, $c_type:ty) => { + validate_equivalence!(&'static $zenoh_type, $c_type); + impl_transmute_handle!($c_type, $zenoh_type); + }; +} + macro_rules! impl_transmute_ref { ($src_type:ty, $dst_type:ty) => { impl $crate::transmute::TransmuteRef<$dst_type> for $src_type { @@ -157,3 +185,22 @@ macro_rules! impl_transmute_uninit_ptr { } }; } + + +macro_rules! impl_transmute_handle { + ($c_type:ty, $zenoh_type:ty) => { + impl $crate::transmute::TransmuteFromHandle<$zenoh_type> for $c_type { + fn transmute_ref(self) -> &'static $zenoh_type { + unsafe { std::mem::transmute::<$c_type, &'static $zenoh_type>(self) } + } + fn transmute_mut(self) -> &'static mut $zenoh_type { + unsafe { std::mem::transmute::<$c_type, &'static mut $zenoh_type>(self) } + } + } + impl $crate::transmute::TransmuteIntoHandle<$c_type> for $zenoh_type { + fn transmute_handle(& self) -> $c_type { + unsafe { std::mem::transmute::<& $zenoh_type, $c_type>(self) } + } + } + }; +} \ No newline at end of file diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index e7b72ef96..062c7c7ad 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -51,12 +51,12 @@ void query_handler(const z_query_t *query, void *arg) { } #endif - z_bytes_t pred = z_query_parameters(query); + z_slice_t pred = z_query_parameters(query); (void)(pred); z_value_t payload_value = z_query_value(query); (void)(payload_value); z_query_reply_options_t _ret_qreply_opt = z_query_reply_options_default(); - zc_owned_payload_t payload = zc_payload_encode_from_string(value); + z_owned_bytes_t payload = z_bytes_encode_from_string(value); z_query_reply(query, z_keyexpr(z_loan(k_str)), z_move(payload), &_ret_qreply_opt); z_drop(z_move(k_str)); @@ -261,7 +261,7 @@ int main(int argc, char **argv) { z_encoding_t _ret_encoding = z_encoding_default(); _ret_encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); _ret_put_opt.encoding = _ret_encoding; - zc_owned_payload_t payload = zc_payload_encode_from_string(value); + z_owned_bytes_t payload = z_bytes_encode_from_string(value); _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), z_move(payload), &_ret_put_opt); assert(_ret_int8 == 0); @@ -294,7 +294,7 @@ int main(int argc, char **argv) { assert(z_check(_ret_pub)); z_publisher_put_options_t _ret_pput_opt = z_publisher_put_options_default(); - payload = zc_payload_encode_from_string(value); + payload = z_bytes_encode_from_string(value); _ret_int8 = z_publisher_put(z_loan(_ret_pub), z_move(payload), &_ret_pput_opt); assert(_ret_int8 == 0); diff --git a/tests/z_api_attachment_test.c b/tests/z_api_attachment_test.c index 737048e9b..7669a3605 100644 --- a/tests/z_api_attachment_test.c +++ b/tests/z_api_attachment_test.c @@ -23,31 +23,31 @@ void writting_through_map_by_alias_read_by_get() { // Writing - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_alias(&map, z_bytes_from_str("k1"), z_bytes_from_str("v1")); - z_bytes_map_insert_by_alias(&map, z_bytes_from_str("k2"), z_bytes_from_str("v2")); - z_attachment_t attachment = z_bytes_map_as_attachment(&map); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_alias(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); + z_slice_map_insert_by_alias(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); + z_bytes_t attachment = z_slice_map_as_attachment(&map); // Elements check - assert(z_bytes_map_len(&map) == 2); + assert(z_slice_map_len(&map) == 2); assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); - z_bytes_t a1 = z_attachment_get(attachment, z_bytes_from_str("k1")); + z_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); - z_bytes_t a2 = z_attachment_get(attachment, z_bytes_from_str("k2")); + z_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); ASSERT_STR_BYTES_EQUAL("v2", a2); - z_bytes_t a_non = z_attachment_get(attachment, z_bytes_from_str("k_non")); + z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); z_drop(z_move(map)); } -int8_t _attachment_reader(z_bytes_t key, z_bytes_t value, void* ctx) { +int8_t _attachment_reader(z_slice_t key, z_slice_t value, void* ctx) { assert((size_t)ctx == 42); if (!strncmp(key.start, "k1", key.len)) { assert(!strncmp(value.start, "v1", value.len)); @@ -60,13 +60,13 @@ int8_t _attachment_reader(z_bytes_t key, z_bytes_t value, void* ctx) { void writting_through_map_by_copy_read_by_iter() { // Writing - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str("k1"), z_bytes_from_str("v1")); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str("k2"), z_bytes_from_str("v2")); - z_attachment_t attachment = z_bytes_map_as_attachment(&map); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_copy(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); + z_slice_map_insert_by_copy(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); + z_bytes_t attachment = z_slice_map_as_attachment(&map); // Elements check - assert(z_bytes_map_len(&map) == 2); + assert(z_slice_map_len(&map) == 2); assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); @@ -78,38 +78,38 @@ void writting_through_map_by_copy_read_by_iter() { int8_t _iteration_driver(const void* data, z_attachment_iter_body_t body, void* ctx) { int8_t ret = 0; - ret = body(z_bytes_from_str("k1"), z_bytes_from_str("v1"), ctx); + ret = body(z_slice_from_str("k1"), z_slice_from_str("v1"), ctx); if (ret) { return ret; } - ret = body(z_bytes_from_str("k2"), z_bytes_from_str("v2"), ctx); + ret = body(z_slice_from_str("k2"), z_slice_from_str("v2"), ctx); return ret; } void writting_no_map_read_by_get() { - z_attachment_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; + z_bytes_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; // Elements check assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); - z_bytes_t a1 = z_attachment_get(attachment, z_bytes_from_str("k1")); + z_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); - z_bytes_t a2 = z_attachment_get(attachment, z_bytes_from_str("k2")); + z_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); ASSERT_STR_BYTES_EQUAL("v2", a2); - z_bytes_t a_non = z_attachment_get(attachment, z_bytes_from_str("k_non")); + z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); } void invalid_attachment_safety() { - z_attachment_t attachment = z_attachment_null(); + z_bytes_t attachment = z_attachment_null(); assert(z_attachment_is_empty(attachment)); assert(z_attachment_len(attachment) == 0); - z_bytes_t a_non = z_attachment_get(attachment, z_bytes_from_str("k_non")); + z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); diff --git a/tests/z_api_null_drop_test.c b/tests/z_api_null_drop_test.c index 814d80e7c..b82f27aef 100644 --- a/tests/z_api_null_drop_test.c +++ b/tests/z_api_null_drop_test.c @@ -43,7 +43,7 @@ int main(int argc, char **argv) { z_owned_reply_channel_closure_t reply_channel_closure_null_1 = z_reply_channel_closure_null(); z_owned_reply_channel_t reply_channel_null_1 = z_reply_channel_null(); z_owned_str_t str_null_1 = z_str_null(); - zc_owned_payload_t payload_null_1 = zc_payload_null(); + z_owned_bytes_t payload_null_1 = z_bytes_null(); zc_owned_shmbuf_t shmbuf_null_1 = zc_shmbuf_null(); zc_owned_shm_manager_t shm_manager_null_1 = zc_shm_manager_null(); @@ -88,7 +88,7 @@ int main(int argc, char **argv) { z_owned_reply_channel_closure_t reply_channel_closure_null_2; z_owned_reply_channel_t reply_channel_null_2; z_owned_str_t str_null_2; - zc_owned_payload_t payload_null_2; + z_owned_bytes_t payload_null_2; zc_owned_shmbuf_t shmbuf_null_2; zc_owned_shm_manager_t shm_manager_null_2; diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c index 10b1a3177..9d8df0076 100644 --- a/tests/z_api_payload_test.c +++ b/tests/z_api_payload_test.c @@ -24,17 +24,17 @@ void test_reader() { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; uint8_t data_out[10] = {0}; - z_bytes_t bytes = {.start = data, .len = 10 }; + z_slice_t bytes = {.start = data, .len = 10 }; - zc_owned_payload_t payload = zc_payload_encode_from_bytes(bytes); - zc_payload_reader reader; - zc_payload_reader_init(z_loan(payload), &reader); - assert(zc_payload_reader_remaining(&reader) == 10); + z_owned_bytes_t payload = z_bytes_encode_from_bytes(bytes); + z_bytes_reader reader; + z_bytes_reader_init(z_loan(payload), &reader); + assert(z_bytes_reader_remaining(&reader) == 10); - zc_payload_reader_read(&reader, data_out, 5); - assert(zc_payload_reader_remaining(&reader) == 5); - zc_payload_reader_read(&reader, data_out, 5); - assert(zc_payload_reader_remaining(&reader) == 0); + z_bytes_reader_read(&reader, data_out, 5); + assert(z_bytes_reader_remaining(&reader) == 5); + z_bytes_reader_read(&reader, data_out, 5); + assert(z_bytes_reader_remaining(&reader) == 0); assert(memcmp(data, data_out, 10)); } diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 03a6d893c..e0246ad01 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -61,7 +61,7 @@ int run_publisher() { // values for cache for (int i = 0; i < values_count / 2; ++i) { - zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } @@ -71,7 +71,7 @@ int run_publisher() { // values for subscribe for (int i = values_count / 2; i < values_count; ++i) { - zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } @@ -94,7 +94,7 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index ccb2c1e82..63bb54f4a 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -47,15 +47,15 @@ int run_publisher() { return -1; } - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_CONST), z_bytes_from_str(V_CONST)); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_CONST), z_slice_from_str(V_CONST)); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - options.attachment = z_bytes_map_as_attachment(&map); + options.attachment = z_slice_map_as_attachment(&map); for (int i = 0; i < values_count; ++i) { - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_VAR), z_bytes_from_str(values[i])); - zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_VAR), z_slice_from_str(values[i])); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); z_publisher_put(z_loan(pub), z_move(payload), &options); } @@ -75,7 +75,7 @@ void data_handler(const z_sample_t *sample, void *arg) { z_drop(z_move(keystr)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); @@ -83,10 +83,10 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(payload_value)); - z_bytes_t v_const = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_CONST)); + z_slice_t v_const = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_bytes_t v_var = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_VAR)); + z_slice_t v_var = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[val_num], v_var); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index ad5969fa2..6d681bb49 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -49,7 +49,7 @@ int run_publisher() { for (int i = 0; i < values_count; ++i) { z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); z_publisher_put(z_loan(pub), z_move(payload), &options); } @@ -68,7 +68,7 @@ void data_handler(const z_sample_t *sample, void *arg) { z_drop(z_move(keystr)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 909da8c24..9ea97fe8f 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -33,24 +33,24 @@ void query_handler(const z_query_t *query, void *context) { static int value_num = 0; z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_bytes_t pred = z_query_parameters(query); + z_slice_t pred = z_query_parameters(query); z_value_t payload_value = z_query_value(query); - z_attachment_t attachment = z_query_attachment(query); + z_bytes_t attachment = z_query_attachment(query); - z_bytes_t v_const = z_attachment_get(attachment, z_bytes_from_str(K_CONST)); + z_slice_t v_const = z_attachment_get(attachment, z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_bytes_t v_var = z_attachment_get(attachment, z_bytes_from_str(K_VAR)); + z_slice_t v_var = z_attachment_get(attachment, z_slice_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[value_num], v_var); - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_CONST), z_bytes_from_str(V_CONST)); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_CONST), z_slice_from_str(V_CONST)); z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - options.attachment = z_bytes_map_as_attachment(&map); - zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + options.attachment = z_slice_map_as_attachment(&map); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[value_num]); z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); z_drop(z_move(map)); @@ -93,14 +93,14 @@ int run_get() { return -1; } - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_CONST), z_bytes_from_str(V_CONST)); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_CONST), z_slice_from_str(V_CONST)); z_get_options_t opts = z_get_options_default(); - opts.attachment = z_bytes_map_as_attachment(&map); + opts.attachment = z_slice_map_as_attachment(&map); for (int val_num = 0; val_num < values_count; ++val_num) { - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_VAR), z_bytes_from_str(values[val_num])); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_VAR), z_slice_from_str(values[val_num])); z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get(z_loan(s), z_keyexpr(keyexpr), "", z_move(channel.send), &opts); @@ -111,14 +111,14 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); exit(-1); } - z_bytes_t v_const = z_attachment_get(z_sample_attachment(&sample), z_bytes_from_str(K_CONST)); + z_slice_t v_const = z_attachment_get(z_sample_attachment(&sample), z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 3b3abad94..b63686ecb 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -29,12 +29,12 @@ void query_handler(const z_query_t *query, void *context) { static int value_num = 0; z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_bytes_t pred = z_query_parameters(query); + z_slice_t pred = z_query_parameters(query); z_value_t payload_value = z_query_value(query); z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[value_num]); z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); @@ -87,7 +87,7 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); From 931ca4903281196547ca9f8323511c46a4e7118d Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 22 Apr 2024 19:44:04 +0200 Subject: [PATCH 048/377] all builds except shm --- Cargo.lock | 9 +- Cargo.toml | 1 + Cargo.toml.in | 1 + build-resources/opaque-types/Cargo.lock | 1 + build-resources/opaque-types/Cargo.toml | 1 + build-resources/opaque-types/src/lib.rs | 135 ++--- include/zenoh-gen.h | 635 +++++++++++++++++++++++- src/closures/sample_closure.rs | 10 +- src/commons.rs | 21 +- src/errors.rs | 5 + src/get.rs | 2 +- src/keyexpr.rs | 4 +- src/lib.rs | 25 +- src/liveliness.rs | 210 +++----- src/payload.rs | 7 +- src/platform/synchronization.rs | 329 +++++------- src/publication_cache.rs | 126 ++--- src/publisher.rs | 2 +- src/put.rs | 141 +++--- src/querying_subscriber.rs | 220 ++++---- src/subscriber.rs | 208 ++++---- src/transmute.rs | 37 +- 22 files changed, 1266 insertions(+), 864 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c10ee7ae4..3ebd15726 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,18 +433,18 @@ checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "const_format" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" dependencies = [ "proc-macro2", "quote", @@ -3152,6 +3152,7 @@ dependencies = [ "async-trait", "cbindgen", "chrono", + "const_format", "env_logger", "fs2", "fs_extra", diff --git a/Cargo.toml b/Cargo.toml index 767d9a3a3..4e62df310 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" unwrap-infallible = "0.1.5" +const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` #zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } #zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } diff --git a/Cargo.toml.in b/Cargo.toml.in index b68560103..af0cd4fa0 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -51,6 +51,7 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" unwrap-infallible = "0.1.5" +const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` #zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } #zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index b3cd2f5b5..87d494976 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -1147,6 +1147,7 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" name = "opaque-types" version = "0.1.0" dependencies = [ + "const_format", "zenoh", "zenoh-ext", ] diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml index 93f88d05d..a1c020ed4 100644 --- a/build-resources/opaque-types/Cargo.toml +++ b/build-resources/opaque-types/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` # zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } +const_format = "0.2.32" zenoh = { path = "../../../zenoh/zenoh", features = [ "shared-memory", "unstable", diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index dd5443d73..846e887a3 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,12 +1,17 @@ use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; +use std::sync::Condvar; +use std::sync::Mutex; +use std::sync::MutexGuard; +use std::thread::JoinHandle; use zenoh::config::Config; use zenoh::config::ZenohId; use zenoh::encoding::Encoding; use zenoh::handlers::DefaultHandler; use zenoh::key_expr::KeyExpr; use zenoh::bytes::{ZBytes, ZBytesReader}; +use zenoh::liveliness::LivelinessToken; use zenoh::publication::MatchingListener; use zenoh::publication::Publisher; use zenoh::query::Reply; @@ -14,75 +19,22 @@ use zenoh::queryable::Query; use zenoh::queryable::Queryable; use zenoh::sample::Sample; use zenoh::session::Session; +use zenoh::subscriber::Subscriber; use zenoh::time::Timestamp; use zenoh::value::Value; -// Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. -// pub struct FetchingSubscriberWrapper { -// fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, -// session: z_session_t, -// } - #[macro_export] macro_rules! get_opaque_type_data { ($src_type:ty, $name:ident) => { const _: () = { - const fn get_num_digits(n: usize) -> usize { - let mut out = 0; - let mut res = n; - while res > 0 { - out += 1; - res = res / 10; - } - if out == 0 { - out = 1; - } - out - } - - const fn write_str(src: &[u8], mut dst: [u8; MSG_LEN], offset: usize) -> [u8; MSG_LEN] { - let mut i = 0; - while i < src.len() { - dst[i + offset] = src[i]; - i += 1; - } - dst - } - - const fn write_num(src: usize, mut dst: [u8; MSG_LEN], offset: usize) -> [u8; MSG_LEN] { - let mut i = 0; - let num_digits = get_num_digits(src) as u32; - while i < num_digits { - dst[i as usize + offset] = b'0' + ((src / 10u32.pow(num_digits - i - 1) as usize) % 10) as u8; - i += 1; - } - dst - } - + use const_format::concatcp; const DST_NAME: &str = stringify!($name); const ALIGN: usize = std::mem::align_of::<$src_type>(); const SIZE: usize = std::mem::size_of::<$src_type>(); - const TYPE_TOKEN: [u8; 6] = *b"type: "; - const ALIGN_TOKEN: [u8; 9] = *b", align: "; - const SIZE_TOKEN: [u8; 8] = *b", size: "; - const SIZE_NUM_DIGITS: usize = get_num_digits(SIZE); - const ALIGN_NUM_DIGITS: usize = get_num_digits(ALIGN); - const MSG_LEN: usize = TYPE_TOKEN.len() + ALIGN_TOKEN.len() + SIZE_TOKEN.len() + SIZE_NUM_DIGITS + ALIGN_NUM_DIGITS + DST_NAME.len(); - const TYPE_OFFSET: usize = TYPE_TOKEN.len(); - const ALIGN_OFFSET: usize = TYPE_OFFSET + DST_NAME.len() + ALIGN_TOKEN.len(); - const SIZE_OFFSET: usize = ALIGN_OFFSET + ALIGN_NUM_DIGITS + SIZE_TOKEN.len(); - let mut msg: [u8; MSG_LEN] = [b' '; MSG_LEN]; - - msg = write_str(&TYPE_TOKEN, msg, 0); - msg = write_str(&DST_NAME.as_bytes(), msg, TYPE_OFFSET); - msg = write_str(&ALIGN_TOKEN, msg, ALIGN_OFFSET - ALIGN_TOKEN.len()); - msg = write_num(ALIGN, msg, ALIGN_OFFSET); - msg = write_str(&SIZE_TOKEN, msg, SIZE_OFFSET - SIZE_TOKEN.len()); - msg = write_num(SIZE, msg, SIZE_OFFSET); - - panic!("{}", unsafe { - std::str::from_utf8_unchecked(msg.as_slice()) - }); + const INFO_MESSAGE: &str = concatcp!( + "type: ", DST_NAME, ", align: ", ALIGN, ", size: ", SIZE + ); + panic!("{}", INFO_MESSAGE); }; } } @@ -151,14 +103,18 @@ get_opaque_type_data!(&'static Query, z_query_t); get_opaque_type_data!(Option>, z_owned_queryable_t); get_opaque_type_data!(&'static Queryable<'static, ()>, z_queryable_t); -// get_opaque_type_data!( -// Option>, -// ze_owned_querying_subscriber_t -// ); -// get_opaque_type_data!( -// &'static FetchingSubscriberWrapper, -// ze_querying_subscriber_t -// ); +/// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. +/// +/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); +get_opaque_type_data!(&'static (zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); /// A zenoh-allocated key expression. /// @@ -255,3 +211,48 @@ get_opaque_type_data!(&'static Publisher<'static>, z_publisher_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, zcu_owned_matching_listener_t); + + +/// An owned zenoh subscriber. Destroying the subscriber cancels the subscription. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_subscriber_t); +get_opaque_type_data!(&'static Subscriber<'static, ()>, z_subscriber_t); + +/// A liveliness token that can be used to provide the network with information about connectivity to its +/// declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key +/// expressions. +/// +/// A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. +get_opaque_type_data!(Option>, zc_owned_liveliness_token_t); +get_opaque_type_data!(&'static LivelinessToken<'static>, zc_liveliness_token_t); + + +/// An owned zenoh publication_cache. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, ze_owned_publication_cache_t); +get_opaque_type_data!(&'static zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); + + +get_opaque_type_data!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); +get_opaque_type_data!(&'static (Mutex<()>, Option>), z_mutex_t); + +get_opaque_type_data!(Option, z_owned_condvar_t); +get_opaque_type_data!(&'static Condvar, z_condvar_t); + +get_opaque_type_data!(Option>, z_owned_task_t); \ No newline at end of file diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index 1761f69b2..19b3fc6c9 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -90,6 +90,17 @@ typedef enum z_query_target_t { Z_QUERY_TARGET_T_ALL_COMPLETE, } z_query_target_t; +/** + * The subscription reliability. + * + * - **Z_RELIABILITY_BEST_EFFORT** + * - **Z_RELIABILITY_RELIABLE** + */ +typedef enum z_reliability_t { + Z_RELIABILITY_T_BEST_EFFORT, + Z_RELIABILITY_T_RELIABLE, +} z_reliability_t; + typedef enum z_sample_kind_t { Z_SAMPLE_KIND_T_PUT = 0, Z_SAMPLE_KIND_T_DELETE = 1, @@ -173,6 +184,15 @@ typedef struct ALIGN(8) z_bytes_reader_t { uint8_t _0[8]; } z_bytes_reader_t; +/** + * Clock + * Uses monotonic clock + */ +typedef struct z_clock_t { + uint64_t t; + const void *t_base; +} z_clock_t; + /** * An owned zenoh session. * @@ -346,7 +366,7 @@ typedef struct ALIGN(8) z_sample_t { * * Members: * void *context: a pointer to an arbitrary state. - * void *call(const struct z_sample_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. * void *drop(void*): allows the callback's state to be freed. * * Closures are not guaranteed not to be called concurrently. @@ -359,7 +379,7 @@ typedef struct ALIGN(8) z_sample_t { */ typedef struct z_owned_closure_sample_t { void *context; - void (*call)(const struct z_sample_t*, void *context); + void (*call)(struct z_sample_t, void *context); void (*drop)(void*); } z_owned_closure_sample_t; @@ -385,6 +405,18 @@ typedef struct z_owned_closure_zid_t { void (*drop)(void*); } z_owned_closure_zid_t; +typedef struct ALIGN(8) z_owned_condvar_t { + uint8_t _0[24]; +} z_owned_condvar_t; + +typedef struct ALIGN(8) z_condvar_t { + uint8_t _0[8]; +} z_condvar_t; + +typedef struct ALIGN(8) z_mutex_t { + uint8_t _0[8]; +} z_mutex_t; + /** * An owned zenoh configuration. * @@ -512,6 +544,40 @@ typedef struct ALIGN(8) z_owned_queryable_t { uint8_t _0[32]; } z_owned_queryable_t; +/** + * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_subscriber_t { + uint8_t _0[32]; +} z_owned_subscriber_t; + +/** + * Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. + * + * Members: + * z_reliability_t reliability: The subscription reliability. + */ +typedef struct z_subscriber_options_t { + enum z_reliability_t reliability; +} z_subscriber_options_t; + +/** + * Options passed to the :c:func:`z_delete` function. + */ +typedef struct z_delete_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_delete_options_t; + typedef struct ALIGN(8) z_owned_encoding_t { uint8_t _0[48]; } z_owned_encoding_t; @@ -579,6 +645,10 @@ typedef struct z_hello_t { struct z_str_array_t locators; } z_hello_t; +typedef struct ALIGN(8) z_owned_mutex_t { + uint8_t _0[32]; +} z_owned_mutex_t; + typedef struct ALIGN(8) z_publisher_t { uint8_t _0[8]; } z_publisher_t; @@ -603,6 +673,22 @@ typedef struct z_publisher_put_options_t { struct z_owned_bytes_t *attachment; } z_publisher_put_options_t; +/** + * Options passed to the :c:func:`z_put` function. + * + * Members: + * z_encoding_t encoding: The encoding of the payload. + * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. + * z_priority_t priority: The priority of this message. + * z_bytes_t attachment: The attachment to this message. + */ +typedef struct z_put_options_t { + struct z_owned_encoding_t *encoding; + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; + struct z_owned_bytes_t *attachment; +} z_put_options_t; + /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -707,6 +793,58 @@ typedef struct z_owned_scouting_config_t { */ typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); +typedef struct ALIGN(8) z_subscriber_t { + uint8_t _0[8]; +} z_subscriber_t; + +typedef struct ALIGN(8) z_owned_task_t { + uint8_t _0[24]; +} z_owned_task_t; + +typedef struct z_task_attr_t { + size_t _0; +} z_task_attr_t; + +/** + * Time + * Uses system clock + */ +typedef struct z_time_t { + uint64_t t; +} z_time_t; + +/** + * The options for `zc_liveliness_declare_token` + */ +typedef struct zc_liveliness_declaration_options_t { + uint8_t _dummy; +} zc_liveliness_declaration_options_t; + +/** + * The options for :c:func:`zc_liveliness_declare_subscriber` + */ +typedef struct zc_liveliness_declare_subscriber_options_t { + uint8_t _dummy; +} zc_liveliness_declare_subscriber_options_t; + +/** + * A liveliness token that can be used to provide the network with information about connectivity to its + * declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key + * expressions. + * + * A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. + */ +typedef struct ALIGN(8) zc_owned_liveliness_token_t { + uint8_t _0[32]; +} zc_owned_liveliness_token_t; + +/** + * The options for :c:func:`zc_liveliness_declare_subscriber` + */ +typedef struct zc_liveliness_get_options_t { + uint32_t timeout_ms; +} zc_liveliness_get_options_t; + /** * An owned sample. * @@ -765,6 +903,85 @@ typedef struct ALIGN(8) zcu_owned_matching_listener_t { uint8_t _0[40]; } zcu_owned_matching_listener_t; +/** + * An owned zenoh publication_cache. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_publication_cache_t { + uint8_t _0[96]; +} ze_owned_publication_cache_t; + +/** + * Options passed to the :c:func:`ze_declare_publication_cache` function. + * + * Members: + * z_keyexpr_t queryable_prefix: The prefix used for queryable + * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this + * publication cache + * bool queryable_complete: the `complete` option for the queryable + * size_t history: The the history size + * size_t resources_limit: The limit number of cached resources + */ +typedef struct ze_publication_cache_options_t { + const struct z_keyexpr_t *queryable_prefix; + enum zcu_locality_t queryable_origin; + bool queryable_complete; + size_t history; + size_t resources_limit; +} ze_publication_cache_options_t; + +/** + * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. + * + * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_querying_subscriber_t { + uint8_t _0[64]; +} ze_owned_querying_subscriber_t; + +/** + * Represents the set of options that can be applied to a querying subscriber, + * upon its declaration via :c:func:`ze_declare_querying_subscriber`. + * + * Members: + * z_reliability_t reliability: The subscription reliability. + * zcu_locality_t allowed_origin: The restriction for the matching publications that will be + * receive by this subscriber. + * z_keyexpr_t query_selector: The selector to be used for queries. + * z_query_target_t query_target: The target to be used for queries. + * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. + * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. + * uint64_t query_timeout_ms: The timeout to be used for queries. + */ +typedef struct ze_querying_subscriber_options_t { + enum z_reliability_t reliability; + enum zcu_locality_t allowed_origin; + const struct z_keyexpr_t *query_selector; + enum z_query_target_t query_target; + struct z_query_consolidation_t query_consolidation; + enum zcu_reply_keyexpr_t query_accept_replies; + uint64_t query_timeout_ms; +} ze_querying_subscriber_options_t; + +typedef struct ALIGN(8) ze_querying_subscriber_t { + uint8_t _0[8]; +} ze_querying_subscriber_t; + #define Z_OK 0 #define Z_EINVAL -1 @@ -775,6 +992,14 @@ typedef struct ALIGN(8) zcu_owned_matching_listener_t { #define Z_ENETWORK -4 +#define Z_EBUSY_MUTEX -16 + +#define Z_EINVAL_MUTEX -22 + +#define Z_EAGAIN_MUTEX -11 + +#define Z_EPOISON_MUTEX -22 + #define Z_EGENERIC INT8_MIN extern const unsigned int Z_ROUTER; @@ -917,6 +1142,14 @@ ZCError z_bytes_reader_seek(struct z_bytes_reader_t reader, */ ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t reader); +ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); + +ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); + +ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); + +ZENOHC_API struct z_clock_t z_clock_now(void); + /** * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. * @@ -998,7 +1231,7 @@ ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); */ ZENOHC_API void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - const struct z_sample_t *sample); + struct z_sample_t sample); /** * Drops the closure. Droping an uninitialized closure is a no-op. @@ -1027,6 +1260,20 @@ ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); */ ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); +ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); + +ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); + +ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); + +ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); + +ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); + +ZENOHC_API ZCError z_condvar_signal(struct z_condvar_t this_); + +ZENOHC_API ZCError z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); + /** * Returns ``true`` if `config` is valid. */ @@ -1152,6 +1399,66 @@ ZCError z_declare_queryable(struct z_session_t session, const struct z_queryable_options_t *options, struct z_owned_queryable_t *this_); +/** + * Declare a subscriber for a given key expression. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to subscribe. + * callback: The callback function that will be called each time a data matching the subscribed expression is received. + * opts: The options to be passed to describe the options to be passed to the subscriber declaration. + * + * Returns: + * A :c:type:`z_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the subscriber is still valid, + * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a subscriber passing `NULL` for the options: + * + * .. code-block:: C + * + * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); + * + * is equivalent to initializing and passing the default subscriber options: + * + * .. code-block:: C + * + * z_subscriber_options_t opts = z_subscriber_options_default(); + * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); + */ +ZENOHC_API +ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct z_subscriber_options_t options); + +/** + * Delete data. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to delete. + * options: The put options. + * Returns: + * ``0`` in case of success, negative values in case of failure. + */ +ZENOHC_API +ZCError z_delete(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_delete_options_t opts); + +/** + * Constructs the default value for :c:type:`z_put_options_t`. + */ +ZENOHC_API struct z_delete_options_t z_delete_options_default(void); + /** * Returns ``true`` if `encoding` is valid. */ @@ -1421,6 +1728,20 @@ ZENOHC_API void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, const char *name); +ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); + +ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); + +ZENOHC_API ZCError z_mutex_init(struct z_owned_mutex_t *this_); + +ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); + +ZENOHC_API ZCError z_mutex_lock(struct z_mutex_t this_); + +ZENOHC_API ZCError z_mutex_try_lock(struct z_mutex_t this_); + +ZENOHC_API ZCError z_mutex_unlock(struct z_mutex_t this_); + /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. * Config value is always consumed upon function return. @@ -1498,6 +1819,32 @@ ZCError z_publisher_put(struct z_publisher_t publisher, */ ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); +/** + * Put data, transfering its ownership. + * + * + * The payload's encoding and attachment can be sepcified through the options. These values are consumed upon function + * return. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to put. + * payload: The value to put (consumed upon function return). + * options: The put options. + * Returns: + * ``0`` in case of success, negative error values in case of failure. + */ +ZENOHC_API +ZCError z_put(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_put_options_t options); + +/** + * Constructs the default value for :c:type:`z_put_options_t`. + */ +ZENOHC_API struct z_put_options_t z_put_options_default(void); + /** * Gets the attachment to the query by aliasing. * @@ -1666,6 +2013,16 @@ ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); */ ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); +ZENOHC_API void z_random_fill(void *buf, size_t len); + +ZENOHC_API uint16_t z_random_u16(void); + +ZENOHC_API uint32_t z_random_u32(void); + +ZENOHC_API uint64_t z_random_u64(void); + +ZENOHC_API uint8_t z_random_u8(void); + /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1832,6 +2189,12 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); */ ZENOHC_API void z_session_null(struct z_owned_session_t *s); +ZENOHC_API int8_t z_sleep_ms(size_t time); + +ZENOHC_API int8_t z_sleep_s(size_t time); + +ZENOHC_API int8_t z_sleep_us(size_t time); + /** * Returns ``true`` if `b` is initialized. */ @@ -1976,6 +2339,61 @@ ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); */ ZENOHC_API struct z_owned_str_t z_str_null(void); +/** + * Returns ``true`` if `sub` is valid. + */ +ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber); + +/** + * Returns the key expression of the subscriber. + */ +ZENOHC_API struct z_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); + +/** + * Returns a :c:type:`z_subscriber_t` loaned from `this`. + */ +ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *this_); + +/** + * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type + */ +ZENOHC_API void z_subscriber_null(struct z_owned_subscriber_t *this_); + +/** + * Constructs the default value for :c:type:`z_subscriber_options_t`. + */ +ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); + +ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); + +/** + * Detaches the task and releases all allocated resources. + */ +ZENOHC_API void z_task_detach(struct z_owned_task_t *this_); + +ZENOHC_API +ZCError z_task_init(struct z_owned_task_t *this_, + const struct z_task_attr_t *_attr, + void (*fun)(void *arg), + void *arg); + +/** + * Joins the task and releases all allocated resources + */ +ZENOHC_API ZCError z_task_join(struct z_owned_task_t *this_); + +ZENOHC_API void z_task_null(struct z_owned_task_t *this_); + +ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); + +ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); + +ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); + +ZENOHC_API struct z_time_t z_time_now(void); + +ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); + ZENOHC_API struct z_id_t z_timestamp_get_id(const struct z_timestamp_t *timestamp); ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); @@ -2000,6 +2418,12 @@ ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); */ ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); +/** + * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); + /** * Converts the kind of zenoh entity into a string. * @@ -2094,6 +2518,82 @@ void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, const char *start, size_t len); +ZENOHC_API +struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_default(void); + +/** + * Declares a subscriber on liveliness tokens that intersect `key`. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t key_expr: The key expression to subscribe. + * z_owned_closure_sample_t callback: The callback function that will be called each time a + * liveliness token status changed. + * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. + * + * Returns: + * A :c:type:`z_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the subscriber is still valid, + * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct zc_liveliness_declare_subscriber_options_t _options); + +/** + * Constructs and declares a liveliness token on the network. + * + * Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity + * is achieved, and a DELETE sample if it's lost. + * + * Passing `NULL` as options is valid and equivalent to a pointer to the default options. + */ +ZENOHC_API +ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct zc_liveliness_declaration_options_t _options); + +/** + * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. + * + * Note that the same "value stealing" tricks apply as with a normal :c:func:`z_get` + * + * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. + */ +ZENOHC_API +ZCError zc_liveliness_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_reply_t *callback, + struct zc_liveliness_get_options_t options); + +/** + * The gravestone value for `zc_liveliness_get_options_t` + */ +ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); + +ZENOHC_API +struct zc_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_default(void); + +/** + * Returns `true` unless the token is at its gravestone value. + */ +ZENOHC_API bool zc_liveliness_token_check(const struct zc_owned_liveliness_token_t *this_); + +/** + * The gravestone value for liveliness tokens. + */ +ZENOHC_API void zc_liveliness_token_null(struct zc_owned_liveliness_token_t *this_); + +/** + * Destroys a liveliness token, notifying subscribers of its destruction. + */ +ZENOHC_API ZCError zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); + /** * Creates a new blocking fifo channel, returned as a pair of closures. * @@ -2214,3 +2714,132 @@ ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, struct zcu_owned_matching_listener_t *this_); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); + +/** + * Declares a Publication Cache. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t key_expr: The key expression to publish. + * ze_publication_cache_options_t options: Additional options for the publication_cache. + * + * Returns: + * :c:type:`ze_owned_publication_cache_t`. + * + * + * Example: + * Declaring a publication cache `NULL` for the options: + * + * .. code-block:: C + * + * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), NULL); + * + * is equivalent to initializing and passing the default publication cache options: + * + * .. code-block:: C + * + * ze_publication_cache_options_t opts = ze_publication_cache_options_default(); + * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); + */ +ZENOHC_API +ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct ze_publication_cache_options_t options); + +/** + * Declares a Querying Subscriber for a given key expression. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t keyexpr: The key expression to subscribe. + * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. + * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. + * + * Returns: + * :c:type:`ze_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the querying subscriber is still valid, + * you may use `ze_querying_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a subscriber passing ``NULL`` for the options: + * + * .. code-block:: C + * + * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); + * + * is equivalent to initializing and passing the default subscriber options: + * + * .. code-block:: C + * + * z_subscriber_options_t opts = z_subscriber_options_default(); + * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); + */ +ZENOHC_API +ZCError ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct ze_querying_subscriber_options_t options); + +/** + * Returns ``true`` if `pub_cache` is valid. + */ +ZENOHC_API bool ze_publication_cache_check(const struct ze_owned_publication_cache_t *this_); + +/** + * Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type + */ +ZENOHC_API void ze_publication_cache_null(struct ze_owned_publication_cache_t *this_); + +/** + * Constructs the default value for :c:type:`ze_publication_cache_options_t`. + */ +ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); + +/** + * Returns ``true`` if `this` is valid. + */ +ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subscriber_t *this_); + +/** + * Make a :c:type:`ze_owned_querying_subscriber_t` to perform an additional query on a specified selector. + * The queried samples will be merged with the received publications and made available in the subscriber callback. + */ +ZENOHC_API +ZCError ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, + struct z_keyexpr_t selector, + const struct z_get_options_t *options); + +/** + * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. + */ +ZENOHC_API +struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); + +/** + * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type + */ +ZENOHC_API void ze_querying_subscriber_null(struct ze_owned_querying_subscriber_t *this_); + +/** + * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. + */ +ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); + +/** + * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); + +/** + * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); diff --git a/src/closures/sample_closure.rs b/src/closures/sample_closure.rs index 6f0e55707..4d95cf177 100644 --- a/src/closures/sample_closure.rs +++ b/src/closures/sample_closure.rs @@ -4,7 +4,7 @@ use libc::c_void; /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(const struct z_sample_t*, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_sample_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_sample_t { @@ -47,7 +47,7 @@ pub extern "C" fn z_closure_sample_null() -> z_owned_closure_sample_t { /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: &z_sample_t) { +pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: z_sample_t) { match closure.call { Some(call) => call(sample, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -60,10 +60,10 @@ pub extern "C" fn z_closure_sample_drop(closure: &mut z_owned_closure_sample_t) let mut empty_closure = z_owned_closure_sample_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_sample_t { +impl From for z_owned_closure_sample_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: &z_sample_t, this: *mut c_void) { + extern "C" fn call(sample: z_sample_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; this(sample) } diff --git a/src/commons.rs b/src/commons.rs index ba29657be..fb245e40b 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -19,6 +19,7 @@ use std::str::FromStr; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; @@ -87,34 +88,34 @@ pub unsafe extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t /// /// A sample is the value associated to a given resource at a given point in time. use crate::opaque_types::z_sample_t; -decl_transmute_copy!(&'static Sample, z_sample_t); +decl_transmute_handle!(Sample, z_sample_t); /// The Key Expression of the sample. /// /// `sample` is aliased by its return value. #[no_mangle] pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.key_expr().into() } /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.encoding().transmute_copy() } /// The sample's data, the return value aliases the sample. /// #[no_mangle] pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.payload().transmute_handle() } /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.kind().into() } /// The samples timestamp @@ -122,7 +123,7 @@ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { /// Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t, timestamp_out: &mut z_timestamp_t) -> bool { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); if let Some(t) = sample.timestamp() { *timestamp_out = t.transmute_copy(); true @@ -136,7 +137,7 @@ pub extern "C" fn z_sample_timestamp(sample: &z_sample_t, timestamp_out: &mut z_ /// Checks if sample contains an attachment. #[no_mangle] pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.attachment().is_some() } @@ -145,7 +146,7 @@ pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { /// Before calling this function, ensure that `zc_sample_has_attachment` returns true #[no_mangle] pub extern "C" fn z_sample_attachment(sample: z_sample_t) -> z_bytes_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.attachment().expect("Sample does not have an attachment").transmute_handle() } @@ -155,7 +156,7 @@ decl_transmute_owned!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { - let src = src.transmute_copy(); + let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); @@ -176,7 +177,7 @@ pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] pub extern "C" fn zc_sample_loan(sample: &'static zc_owned_sample_t) -> z_sample_t { - unwrap_ref_unchecked(sample.transmute_ref()).transmute_copy() + unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } /// Destroy the sample. diff --git a/src/errors.rs b/src/errors.rs index 90e8508de..298752442 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,4 +4,9 @@ pub const Z_EINVAL: ZCError = -1; pub const Z_EPARSE: ZCError = -2; pub const Z_EIO: ZCError = -3; pub const Z_ENETWORK: ZCError = -4; +// negativ pthread error codes (due to convention to return negative values on error) +pub const Z_EBUSY_MUTEX: ZCError = -16; +pub const Z_EINVAL_MUTEX: ZCError = -22; +pub const Z_EAGAIN_MUTEX: ZCError = -11; +pub const Z_EPOISON_MUTEX: ZCError = -22; // same as Z_EINVAL_MUTEX pub const Z_EGENERIC: ZCError = i8::MIN; \ No newline at end of file diff --git a/src/get.rs b/src/get.rs index de8e9d183..9a6855559 100644 --- a/src/get.rs +++ b/src/get.rs @@ -62,7 +62,7 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: z_reply_t) -> bool { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { let reply = reply.transmute_ref(); - reply.result().expect("Reply does not contain a sample").transmute_copy() + reply.result().expect("Reply does not contain a sample").transmute_handle() } /// Yields the contents of the reply by asserting it indicates a failure. diff --git a/src/keyexpr.rs b/src/keyexpr.rs index cf19224fa..9d4cc194b 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -44,7 +44,7 @@ pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } -fn keyexpr_create_inner(name: &mut str, should_auto_canonize: bool, should_copy: bool) -> Result, Box> { +fn keyexpr_create_inner(name: &'static mut str, should_auto_canonize: bool, should_copy: bool) -> Result, Box> { if should_copy { let s = name.to_owned(); match should_auto_canonize { @@ -69,7 +69,7 @@ unsafe fn keyexpr_create(name: &'static mut [u8], should_auto_canonize: bool, sh Ok(v) } Err(e) => { - log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); + log::error!("Couldn't construct a keyexpr: {}", e); Err(errors::Z_EINVAL) } } diff --git a/src/lib.rs b/src/lib.rs index ad25e1e28..6e6f5843e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,29 +40,28 @@ mod get; pub use crate::get::*; mod queryable; pub use crate::queryable::*; -// mod put; -// pub use crate::put::*; +mod put; +pub use crate::put::*; mod scouting; pub use crate::scouting::*; mod session; pub use crate::session::*; -// mod subscriber; -// pub use crate::subscriber::*; +mod subscriber; +pub use crate::subscriber::*; // // mod pull_subscriber; // // pub use crate::pull_subscriber::*; mod publisher; pub use crate::publisher::*; mod closures; pub use closures::*; -// mod liveliness; -// pub use liveliness::*; -// mod publication_cache; -// pub use publication_cache::*; -// // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. -// // mod querying_subscriber; -// // pub use querying_subscriber::*; -// pub use platform::*; -// pub mod platform; +mod liveliness; +pub use liveliness::*; +mod publication_cache; +pub use publication_cache::*; +mod querying_subscriber; +pub use querying_subscriber::*; +pub use platform::*; +pub mod platform; // #[cfg(feature = "shared-memory")] // mod shm; diff --git a/src/liveliness.rs b/src/liveliness.rs index 46ec7c8a5..ec50a7798 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -12,76 +12,46 @@ // ZettaScale Zenoh Team, // +use std::mem::MaybeUninit; +use zenoh::prelude::SyncResolve; use zenoh::{ - liveliness::{Liveliness, LivelinessToken}, - prelude::SessionDeclarations, + liveliness::{Liveliness, LivelinessToken}, prelude::SessionDeclarations }; +use crate::transmute::TransmuteIntoHandle; use crate::{ - opaque_types::z_sample_t, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, - z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, + errors, transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t }; -/// A liveliness token that can be used to provide the network with information about connectivity to its -/// declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key -/// expressions. -/// -/// A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. -#[repr(C)] -pub struct zc_owned_liveliness_token_t { - _inner: [usize; 4], -} +use crate::opaque_types::zc_owned_liveliness_token_t; +use crate::opaque_types::zc_liveliness_token_t; +decl_transmute_owned!(Option>, zc_owned_liveliness_token_t); +decl_transmute_handle!(LivelinessToken<'static>, zc_liveliness_token_t); /// The gravestone value for liveliness tokens. #[no_mangle] -pub extern "C" fn zc_liveliness_token_null() -> zc_owned_liveliness_token_t { - zc_owned_liveliness_token_t { _inner: [0; 4] } +pub extern "C" fn zc_liveliness_token_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); } /// Returns `true` unless the token is at its gravestone value. #[no_mangle] -pub extern "C" fn zc_liveliness_token_check(token: &zc_owned_liveliness_token_t) -> bool { - token._inner.iter().any(|v| *v != 0) +pub extern "C" fn zc_liveliness_token_check(this: &zc_owned_liveliness_token_t) -> bool { + this.transmute_ref().is_some() } /// The options for `zc_liveliness_declare_token` #[repr(C)] -pub struct zc_owned_liveliness_declaration_options_t { - _inner: u8, -} -/// The gravestone value for `zc_owned_liveliness_declaration_options_t` -#[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_null( -) -> zc_owned_liveliness_declaration_options_t { - zc_owned_liveliness_declaration_options_t { _inner: 0 } -} -/// Returns `true` if the options are valid. -#[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_check( - _opts: &zc_owned_liveliness_declaration_options_t, -) -> bool { - true +pub struct zc_liveliness_declaration_options_t { + _dummy: u8, } -/// Destroys the options. + #[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_drop( - opts: &mut zc_owned_liveliness_declaration_options_t, -) { - *opts = zc_liveliness_declaration_options_null() -} -impl From> for zc_owned_liveliness_token_t { - fn from(value: LivelinessToken<'static>) -> Self { - unsafe { core::mem::transmute(value) } - } -} -impl From for Option> { - fn from(value: zc_owned_liveliness_token_t) -> Self { - if value._inner.iter().all(|v| *v == 0) { - None - } else { - Some(unsafe { core::mem::transmute(value) }) - } - } +pub extern "C" fn zc_liveliness_declaration_options_default( +) -> zc_liveliness_declaration_options_t { + zc_liveliness_declaration_options_t { _dummy: 0 } } + /// Constructs and declares a liveliness token on the network. /// /// Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity @@ -90,67 +60,57 @@ impl From for Option> { /// Passing `NULL` as options is valid and equivalent to a pointer to the default options. #[no_mangle] pub extern "C" fn zc_liveliness_declare_token( + this: *mut MaybeUninit, session: z_session_t, - key: z_keyexpr_t, - _options: Option<&zc_owned_liveliness_declaration_options_t>, -) -> zc_owned_liveliness_token_t { - let Some(session) = session.upgrade() else { - log::error!("Failed to declare liveliness token: provided session was invalid"); - return zc_liveliness_token_null(); - }; - match session.liveliness().declare_token(key).res() { - Ok(token) => unsafe { core::mem::transmute(token) }, + key_expr: z_keyexpr_t, + _options: zc_liveliness_declaration_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + match session.liveliness().declare_token(key_expr).res() { + Ok(token) => { + Inplace::init(this, Some(token)); + errors::Z_OK + }, Err(e) => { - log::error!("Failed to declare liveliness token: {e}"); - zc_liveliness_token_null() + log::error!("Failed to undeclare token: {e}"); + Inplace::empty(this); + errors::Z_EGENERIC } } } /// Destroys a liveliness token, notifying subscribers of its destruction. #[no_mangle] -pub extern "C" fn zc_liveliness_undeclare_token(token: &mut zc_owned_liveliness_token_t) { - let Some(token): Option = - core::mem::replace(token, zc_liveliness_token_null()).into() - else { - return; - }; - if let Err(e) = token.undeclare().res() { - log::error!("Failed to undeclare token: {e}"); +pub extern "C" fn zc_liveliness_undeclare_token(this: &mut zc_owned_liveliness_token_t) -> errors::ZCError { + let this = this.transmute_mut(); + if let Some(token) = this.extract().take() { + if let Err(e) = token.undeclare().res() { + log::error!("Failed to undeclare token: {e}"); + return errors::Z_EGENERIC; + } } + errors::Z_OK } /// The options for :c:func:`zc_liveliness_declare_subscriber` #[repr(C)] -pub struct zc_owned_liveliness_declare_subscriber_options_t { - _inner: u8, +pub struct zc_liveliness_declare_subscriber_options_t { + _dummy: u8, } -/// The gravestone value for `zc_owned_liveliness_declare_subscriber_options_t` -#[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_null( -) -> zc_owned_liveliness_declare_subscriber_options_t { - zc_owned_liveliness_declare_subscriber_options_t { _inner: 0 } -} -/// Returns `true` if the options are valid. -#[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_check( - _opts: &zc_owned_liveliness_declare_subscriber_options_t, -) -> bool { - true -} -/// Destroys the options. + #[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_drop( - opts: &mut zc_owned_liveliness_declare_subscriber_options_t, -) { - *opts = zc_liveliness_subscriber_options_null() +pub extern "C" fn zc_liveliness_subscriber_options_default( +) -> zc_liveliness_declare_subscriber_options_t { + zc_liveliness_declare_subscriber_options_t { _dummy: 0 } } /// Declares a subscriber on liveliness tokens that intersect `key`. /// /// Parameters: /// z_session_t session: The zenoh session. -/// z_keyexpr_t keyexpr: The key expression to subscribe. +/// z_keyexpr_t key_expr: The key expression to subscribe. /// z_owned_closure_sample_t callback: The callback function that will be called each time a /// liveliness token status changed. /// zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. @@ -162,29 +122,33 @@ pub extern "C" fn zc_liveliness_subscriber_options_drop( /// you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[no_mangle] pub extern "C" fn zc_liveliness_declare_subscriber( + this: *mut MaybeUninit, session: z_session_t, - key: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - _options: Option<&zc_owned_liveliness_declare_subscriber_options_t>, -) -> z_owned_subscriber_t { - let Some(session) = session.upgrade() else { - log::error!("Failed to declare liveliness token: provided session was invalid"); - return z_owned_subscriber_t::null(); - }; + _options: zc_liveliness_declare_subscriber_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let session = session.transmute_copy(); let callback = core::mem::replace(callback, z_owned_closure_sample_t::empty()); + let key_expr = key_expr.transmute_ref(); match session .liveliness() - .declare_subscriber(key) + .declare_subscriber(key_expr) .callback(move |sample| { - let sample = z_sample_t::new(&sample); - z_closure_sample_call(&callback, &sample) + let sample = sample.transmute_handle(); + z_closure_sample_call(&callback, sample) }) .res() { - Ok(token) => z_owned_subscriber_t::new(token), + Ok(subscriber) => { + Inplace::init(this, Some(subscriber)); + errors::Z_OK + } Err(e) => { log::error!("Failed to subscribe to liveliness: {e}"); - z_owned_subscriber_t::null() + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -194,26 +158,12 @@ pub extern "C" fn zc_liveliness_declare_subscriber( pub struct zc_liveliness_get_options_t { timeout_ms: u32, } -/// The gravestone value for `zc_liveliness_get_options_t` -#[no_mangle] -pub extern "C" fn zc_liveliness_get_options_null() -> zc_liveliness_get_options_t { - zc_liveliness_get_options_t { timeout_ms: 0 } -} + /// The gravestone value for `zc_liveliness_get_options_t` #[no_mangle] pub extern "C" fn zc_liveliness_get_options_default() -> zc_liveliness_get_options_t { zc_liveliness_get_options_t { timeout_ms: 10000 } } -/// Returns `true` if the options are valid. -#[no_mangle] -pub extern "C" fn zc_liveliness_get_options_check(_opts: &zc_liveliness_get_options_t) -> bool { - true -} -/// Destroys the options. -#[no_mangle] -pub extern "C" fn zc_liveliness_get_options_drop(opts: &mut zc_liveliness_get_options_t) { - *opts = zc_liveliness_get_options_null() -} /// Queries liveliness tokens currently on the network with a key expression intersecting with `key`. /// @@ -223,27 +173,23 @@ pub extern "C" fn zc_liveliness_get_options_drop(opts: &mut zc_liveliness_get_op #[no_mangle] pub extern "C" fn zc_liveliness_get( session: z_session_t, - key: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_reply_t, - options: Option<&zc_liveliness_get_options_t>, -) -> i8 { - let Some(session) = session.upgrade() else { - log::error!("Failed to declare liveliness token: provided session was invalid"); - return i8::MIN; - }; + options: zc_liveliness_get_options_t, +) -> errors::ZCError { + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_reply_t::empty()); let liveliness: Liveliness<'static> = session.liveliness(); let mut builder = liveliness - .get(key) - .callback(move |response| z_closure_reply_call(&callback, &mut response.into())); - if let Some(options) = options { - builder = builder.timeout(core::time::Duration::from_millis(options.timeout_ms as u64)) - } + .get(key_expr) + .callback(move |response| z_closure_reply_call(&callback, response.transmute_handle())); + builder = builder.timeout(core::time::Duration::from_millis(options.timeout_ms as u64)); match builder.res() { - Ok(()) => 0, + Ok(()) => errors::Z_OK, Err(e) => { log::error!("Failed to subscribe to liveliness: {e}"); - e.errno().get() + errors::Z_EGENERIC } } } diff --git a/src/payload.rs b/src/payload.rs index 4ed3feb3e..2dd56c7d9 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -5,7 +5,6 @@ use crate::transmute::{ use crate::{z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap}; use core::slice; use std::any::Any; -use std::borrow::Cow; use std::io::{Read, Seek, SeekFrom}; use std::mem::MaybeUninit; use std::slice::from_raw_parts_mut; @@ -87,7 +86,11 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( ) -> ZCError { let dst = dst.transmute_uninit_ptr(); let payload = payload.transmute_ref(); - let hm = ZHashMap::from_iter(payload.iter::<(Cow<'static, [u8]>, Cow<'static, [u8]>)>()); + let iter = payload.iter::<(Vec, Vec)>(); + let mut hm = ZHashMap::new(); + for (k, v) in iter { + hm.insert(k.into(), v.into()); + } Inplace::init(dst, Some(hm)); errors::Z_OK } diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index a16664352..fa6523128 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -1,240 +1,186 @@ use std::{ - sync::{Condvar, Mutex, MutexGuard}, - thread::{self, JoinHandle}, + mem::MaybeUninit, sync::{Condvar, Mutex, MutexGuard}, thread::{self, JoinHandle} }; use libc::c_void; -use crate::{impl_guarded_transmute, GuardedTransmute}; +use crate::{errors, transmute::{unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}}; +pub use crate::opaque_types::z_owned_mutex_t; +pub use crate::opaque_types::z_mutex_t; -pub struct ZMutex<'a> { - mutex: Mutex<()>, - lock: Option>, -} - -pub struct ZMutexPtr { - data: Option>>, -} - -/// Mutex -/// -#[repr(C)] -#[derive(Clone, Copy)] -pub struct z_mutex_t(usize); +decl_transmute_owned!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); +decl_transmute_handle!((Mutex<()>, Option>), z_mutex_t); -impl_guarded_transmute!(noderefs z_mutex_t, ZMutexPtr); -impl_guarded_transmute!(noderefs ZMutexPtr, z_mutex_t); -// using the same error codes as in GNU pthreads, but with negative sign -// due to convention to return negative values on error -const EBUSY: i8 = -16; -const EINVAL: i8 = -22; -const EAGAIN: i8 = -11; -const EPOISON: i8 = -22; // same as EINVAL +#[no_mangle] +pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let m = (Mutex::<()>::new(()), None::>); + Inplace::init(this, Some(m)); + errors::Z_OK +} #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_init(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let t = ZMutexPtr { - data: Some(Box::new(ZMutex { - mutex: Mutex::new(()), - lock: None, - })), - }; - *m = t.transmute(); - 0 +pub extern "C" fn z_mutex_drop(this: &mut z_owned_mutex_t) { + let _ = this.transmute_mut().extract().take(); } #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_free(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let mut t = (*m).transmute(); +pub extern "C" fn z_mutex_check(this: &z_owned_mutex_t) -> bool { + this.transmute_ref().is_some() +} - t.data.take(); - *m = t.transmute(); - 0 +#[no_mangle] +pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } + #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_lock(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let mut t = (*m).transmute(); - if t.data.is_none() { - return EINVAL; - } - let mut_data = t.data.as_mut().unwrap(); - match mut_data.mutex.lock() { +pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::ZCError { + let this = this.transmute_mut(); + + match this.0.lock() { Ok(new_lock) => { - let old_lock = mut_data.lock.replace(std::mem::transmute(new_lock)); + let old_lock = this.1.replace(new_lock); std::mem::forget(old_lock); } Err(_) => { - return EPOISON; + return errors::Z_EPOISON_MUTEX; } } - - *m = t.transmute(); - 0 + errors::Z_OK } #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_unlock(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let mut t = (*m).transmute(); - if t.data.is_none() { - return EINVAL; - } - let mut_data = t.data.as_mut().unwrap(); - if mut_data.lock.is_none() { - return EINVAL; +pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::ZCError { + let this = this.transmute_mut(); + if this.1.is_none() { + return errors::Z_EINVAL_MUTEX; } else { - mut_data.lock.take(); + this.1.take(); } - *m = t.transmute(); - 0 + errors::Z_OK } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_try_lock(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let mut t = (*m).transmute(); - if t.data.is_none() { - return EINVAL; - } - let mut_data = t.data.as_mut().unwrap(); - let mut ret: i8 = 0; - match mut_data.mutex.try_lock() { +pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::ZCError { + let this = this.transmute_mut(); + match this.0.try_lock() { Ok(new_lock) => { - let old_lock = mut_data.lock.replace(std::mem::transmute(new_lock)); + let old_lock = this.1.replace(new_lock); std::mem::forget(old_lock); } Err(_) => { - ret = EBUSY; + return errors::Z_EBUSY_MUTEX; } } - *m = t.transmute(); - ret + errors::Z_OK } -struct ZCondvarPtr { - data: Option>, + +pub use crate::opaque_types::z_owned_condvar_t; +pub use crate::opaque_types::z_condvar_t; + +decl_transmute_owned!(Option, z_owned_condvar_t); +decl_transmute_handle!(Condvar, z_condvar_t); + +#[no_mangle] +pub extern "C" fn z_condvar_init(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::init(this, Some(Condvar::new())); } -/// Condvar -/// -#[repr(C)] -#[derive(Clone, Copy)] -pub struct z_condvar_t(usize); +#[no_mangle] +pub extern "C" fn z_condvar_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); +} -impl_guarded_transmute!(noderefs z_condvar_t, ZCondvarPtr); -impl_guarded_transmute!(noderefs ZCondvarPtr, z_condvar_t); +#[no_mangle] +pub extern "C" fn z_condvar_drop(this: &mut z_owned_condvar_t) { + let _ = this.transmute_mut().extract().take(); +} #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_init(cv: *mut z_condvar_t) -> i8 { - if cv.is_null() { - return EINVAL; - } - let t: ZCondvarPtr = ZCondvarPtr { - data: Some(Box::new(Condvar::new())), - }; - *cv = t.transmute(); - 0 +pub extern "C" fn z_condvar_check(this: &z_owned_condvar_t) -> bool { + this.transmute_ref().is_some() } #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_free(cv: *mut z_condvar_t) -> i8 { - if cv.is_null() { - return EINVAL; - } - let mut t = (*cv).transmute(); - if t.data.is_none() { - return EINVAL; - } - t.data.take(); - *cv = t.transmute(); - 0 +pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> z_condvar_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_signal(cv: *mut z_condvar_t) -> i8 { - if cv.is_null() { - return EINVAL; - } - let t = (*cv).transmute(); - if t.data.is_none() { - return EINVAL; - } - t.data.as_ref().unwrap().notify_one(); - *cv = t.transmute(); - 0 +pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::ZCError { + let this = this.transmute_mut(); + this.notify_one(); + errors::Z_OK } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_wait(cv: *mut z_condvar_t, m: *mut z_mutex_t) -> i8 { - if cv.is_null() { - return EINVAL; +pub unsafe extern "C" fn z_condvar_wait(this: z_condvar_t, m: z_mutex_t) -> errors::ZCError { + let this = this.transmute_mut(); + let m = m.transmute_mut(); + if m.1.is_none() { + return errors::Z_EINVAL_MUTEX; // lock was not aquired prior to wait call } - let tcv = (*cv).transmute(); - if tcv.data.is_none() { - return EINVAL; - } - if m.is_null() { - return EINVAL; - } - let mut tm = (*m).transmute(); - if tm.data.is_none() || tm.data.as_ref().unwrap().lock.is_none() { - return EINVAL; - } - let mut_data = tm.data.as_mut().unwrap(); - let lock = mut_data.lock.take().unwrap(); - match tcv.data.as_ref().unwrap().wait(lock) { - Ok(new_lock) => mut_data.lock = Some(std::mem::transmute(new_lock)), - Err(_) => return EPOISON, + + let lock = m.1.take().unwrap(); + match this.wait(lock) { + Ok(new_lock) => m.1 = Some(new_lock), + Err(_) => return errors::Z_EPOISON_MUTEX, } - *cv = tcv.transmute(); - *m = tm.transmute(); - 0 -} -struct ZTask { - join_handle: JoinHandle<()>, + errors::Z_OK } -struct ZTaskPtr { - data: Option>, -} +pub use crate::opaque_types::z_owned_task_t; -/// Task -/// -#[repr(C)] -#[derive(Clone, Copy)] -pub struct z_task_t(usize); +decl_transmute_owned!(Option>, z_owned_task_t); #[repr(C)] #[derive(Clone, Copy)] pub struct z_task_attr_t(usize); -impl_guarded_transmute!(noderefs z_task_t, ZTaskPtr); -impl_guarded_transmute!(noderefs ZTaskPtr, z_task_t); +#[no_mangle] +pub extern "C" fn z_task_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); +} + +/// Detaches the task and releases all allocated resources. +#[no_mangle] +pub extern "C" fn z_task_detach(this: &mut z_owned_task_t) { + let _ = this.transmute_mut().extract().take(); +} + +/// Joins the task and releases all allocated resources +#[no_mangle] +pub extern "C" fn z_task_join(this: &mut z_owned_task_t) -> errors::ZCError { + let this = this.transmute_mut().extract().take(); + if let Some(task) = this { + match task.join() { + Ok(_) => errors::Z_OK, + Err(_) => errors::Z_EINVAL_MUTEX, + } + } else { + errors::Z_OK + } +} + +#[no_mangle] +pub extern "C" fn z_task_check(this: &z_owned_task_t) -> bool { + this.transmute_ref().is_some() +} + struct FunArgPair { fun: unsafe extern "C" fn(arg: *mut c_void), @@ -252,42 +198,19 @@ unsafe impl Send for FunArgPair {} #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_task_init( - task: *mut z_task_t, + this: *mut MaybeUninit, _attr: *const z_task_attr_t, fun: unsafe extern "C" fn(arg: *mut c_void), arg: *mut c_void, -) -> i8 { - if task.is_null() { - return EINVAL; - } - - let mut ttask = ZTaskPtr { data: None }; +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let fun_arg_pair = FunArgPair { fun, arg }; - let mut ret = 0; match thread::Builder::new().spawn(move || fun_arg_pair.call()) { - Ok(join_handle) => ttask.data = Some(Box::new(ZTask { join_handle })), - Err(_) => ret = EAGAIN, + Ok(join_handle) => { + Inplace::init(this, Some(join_handle)); + }, + Err(_) => return errors::Z_EAGAIN_MUTEX, } - *task = ttask.transmute(); - ret -} - -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_task_join(task: *mut z_task_t) -> i8 { - if task.is_null() { - return EINVAL; - } - let mut ttask = (*task).transmute(); - if ttask.data.is_none() { - return EINVAL; - } - let data = ttask.data.take(); - let ret = match data.unwrap().join_handle.join() { - Ok(_) => 0, - Err(_) => EINVAL, - }; - *task = ttask.transmute(); - ret -} + errors::Z_OK +} \ No newline at end of file diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 50e1dad47..dadc91cc3 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -12,13 +12,15 @@ // ZettaScale Zenoh team, // -use std::ops::Deref; +use std::mem::MaybeUninit; +use zenoh::prelude::SyncResolve; +use std::ptr::null; use zenoh_ext::SessionExt; +use crate::transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; use crate::{ - impl_guarded_transmute, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t, - UninitializedKeyExprError, + errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t }; /// Options passed to the :c:func:`ze_declare_publication_cache` function. @@ -32,7 +34,7 @@ use crate::{ /// size_t resources_limit: The limit number of cached resources #[repr(C)] pub struct ze_publication_cache_options_t { - pub queryable_prefix: z_keyexpr_t, + pub queryable_prefix: *const z_keyexpr_t, pub queryable_origin: zcu_locality_t, pub queryable_complete: bool, pub history: usize, @@ -43,7 +45,7 @@ pub struct ze_publication_cache_options_t { #[no_mangle] pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache_options_t { ze_publication_cache_options_t { - queryable_prefix: z_keyexpr_t::null(), + queryable_prefix: null(), queryable_origin: zcu_locality_default(), queryable_complete: false, history: 1, @@ -51,36 +53,16 @@ pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache } } -/// An owned zenoh publication_cache. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C)] -pub struct ze_owned_publication_cache_t([usize; 1]); - -type PublicationCache = Option>>; -impl_guarded_transmute!(PublicationCache, ze_owned_publication_cache_t); - -impl ze_owned_publication_cache_t { - pub fn new(pub_cache: zenoh_ext::PublicationCache<'static>) -> Self { - Some(Box::new(pub_cache)).into() - } - pub fn null() -> Self { - None.into() - } -} +pub use crate::opaque_types::ze_owned_publication_cache_t; +pub use crate::opaque_types::ze_publication_cache_t; +decl_transmute_owned!(Option>, ze_owned_publication_cache_t); +decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); /// Declares a Publication Cache. /// /// Parameters: /// z_session_t session: The zenoh session. -/// z_keyexpr_t keyexpr: The key expression to publish. +/// z_keyexpr_t key_expr: The key expression to publish. /// ze_publication_cache_options_t options: Additional options for the publication_cache. /// /// Returns: @@ -103,74 +85,64 @@ impl ze_owned_publication_cache_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_declare_publication_cache( + this: *mut MaybeUninit, session: z_session_t, - keyexpr: z_keyexpr_t, - options: Option<&ze_publication_cache_options_t>, -) -> ze_owned_publication_cache_t { - match session.upgrade() { - Some(s) => { - let keyexpr = keyexpr.deref().as_ref().map(|s| s.clone().into_owned()); - if let Some(key_expr) = keyexpr { - let mut p = s.declare_publication_cache(key_expr); - if let Some(options) = options { - p = p.history(options.history); - p = p.queryable_allowed_origin(options.queryable_origin.into()); - p = p.queryable_complete(options.queryable_complete); - if options.resources_limit != 0 { - p = p.resources_limit(options.resources_limit) - } - if options.queryable_prefix.deref().is_some() { - let queryable_prefix = options - .queryable_prefix - .deref() - .as_ref() - .map(|s| s.clone().into_owned()); - if let Some(queryable_prefix) = queryable_prefix { - p = p.queryable_prefix(queryable_prefix) - } - } - } - match p.res_sync() { - Ok(publication_cache) => ze_owned_publication_cache_t::new(publication_cache), - Err(e) => { - log::error!("{}", e); - ze_owned_publication_cache_t::null() - } - } - } else { - log::error!("{}", UninitializedKeyExprError); - ze_owned_publication_cache_t::null() - } + key_expr: z_keyexpr_t, + options: ze_publication_cache_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + let mut p = session.declare_publication_cache(key_expr); + p = p.history(options.history); + p = p.queryable_allowed_origin(options.queryable_origin.into()); + p = p.queryable_complete(options.queryable_complete); + if options.resources_limit != 0 { + p = p.resources_limit(options.resources_limit) + } + if !options.queryable_prefix.is_null() { + let queryable_prefix = unsafe { *options.queryable_prefix }.transmute_ref(); + p = p.queryable_prefix(queryable_prefix.clone()); + } + match p.res_sync() { + Ok(publication_cache) => { + Inplace::init(this, Some(publication_cache)); + errors::Z_OK + } + Err(e) => { + log::error!("{}", e); + Inplace::empty(this); + errors::Z_EGENERIC } - None => ze_owned_publication_cache_t::null(), } } /// Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn ze_publication_cache_null() -> ze_owned_publication_cache_t { - ze_owned_publication_cache_t::null() +pub extern "C" fn ze_publication_cache_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); } /// Returns ``true`` if `pub_cache` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn ze_publication_cache_check(pub_cache: &ze_owned_publication_cache_t) -> bool { - pub_cache.as_ref().is_some() +pub extern "C" fn ze_publication_cache_check(this: &ze_owned_publication_cache_t) -> bool { + this.transmute_ref().is_some() } /// Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_undeclare_publication_cache( - pub_cache: &mut ze_owned_publication_cache_t, -) -> i8 { - if let Some(p) = pub_cache.take() { + this: &mut ze_owned_publication_cache_t, +) -> errors::ZCError { + if let Some(p) = this.transmute_mut().extract().take() { if let Err(e) = p.close().res_sync() { log::error!("{}", e); - return e.errno().get(); + return errors::Z_EGENERIC; } } - 0 + errors::Z_OK } diff --git a/src/publisher.rs b/src/publisher.rs index 833798959..2ebf4c410 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -304,7 +304,7 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( }) .res(); match listener { - Ok(l) => { + Ok(_) => { Inplace::empty(this); errors::Z_OK }, diff --git a/src/put.rs b/src/put.rs index c2d1bddd2..5457dd522 100644 --- a/src/put.rs +++ b/src/put.rs @@ -1,3 +1,5 @@ +use std::ptr::null_mut; + // // Copyright (c) 2017, 2022 ZettaScale Technology. // @@ -12,24 +14,25 @@ // ZettaScale Zenoh team, // use crate::commons::*; +use crate::errors; use crate::keyexpr::*; use crate::session::*; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteRef; use crate::z_owned_bytes_t; +use crate::z_session_t; use crate::LOG_INVALID_SESSION; use libc::c_void; use zenoh::encoding; +use zenoh::key_expr; use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; use zenoh::publication::CongestionControl; -use zenoh::sample::AttachmentBuilder; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; -use crate::attachment::{ - insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, - z_bytes_t, -}; - /// Options passed to the :c:func:`z_put` function. /// /// Members: @@ -40,10 +43,10 @@ use crate::attachment::{ #[repr(C)] #[allow(non_camel_case_types)] pub struct z_put_options_t { - pub encoding: z_encoding_t, + pub encoding: *mut z_owned_encoding_t, pub congestion_control: z_congestion_control_t, pub priority: z_priority_t, - pub attachment:z_bytes_t, + pub attachment: *mut z_owned_bytes_t, } /// Constructs the default value for :c:type:`z_put_options_t`. @@ -51,71 +54,60 @@ pub struct z_put_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_put_options_default() -> z_put_options_t { z_put_options_t { - encoding: z_encoding_default(), + encoding: null_mut(), congestion_control: CongestionControl::default().into(), priority: Priority::default().into(), - attachment: z_attachment_null(), + attachment: null_mut(), } } -/// Put data, transfering the buffer ownership. +/// Put data, transfering its ownership. /// -/// This is avoids copies when transfering data that was either: -/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher -/// - constructed from a `zc_owned_shmbuf_t` /// -/// The payload's encoding can be sepcified through the options. +/// The payload's encoding and attachment can be sepcified through the options. These values are consumed upon function +/// return. /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression to put. -/// payload: The value to put. +/// key_expr: The key expression to put. +/// payload: The value to put (consumed upon function return). /// options: The put options. /// Returns: -/// ``0`` in case of success, negative values in case of failure. +/// ``0`` in case of success, negative error values in case of failure. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_put( session: z_session_t, - keyexpr: z_keyexpr_t, - payload: Option<&mut z_owned_bytes_t>, - opts: Option<&z_put_options_t>, -) -> i8 { - match session.upgrade() { - Some(s) => { - if let Some(payload) = payload.and_then(|p| p.take()) { - let mut res = s.put(keyexpr, payload); - if let Some(opts) = opts { - res = res - .encoding(**opts.encoding) - .congestion_control(opts.congestion_control.into()) - .priority(opts.priority.into()); - if z_attachment_check(&opts.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - opts.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - res = res.attachment(attachment_builder.build()); - }; - } - match res.res_sync() { - Err(e) => { - log::error!("{}", e); - e.errno().get() - } - Ok(()) => 0, - } - } else { - log::debug!("z_bytes_null was provided as payload for put"); - i8::MIN - } - } + key_expr: z_keyexpr_t, + payload: &mut z_owned_bytes_t, + options: z_put_options_t, +) -> errors::ZCError { + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + let payload = match payload.transmute_mut().extract() { + Some(p) => p, None => { - log::debug!("{}", LOG_INVALID_SESSION); - i8::MIN + log::debug!("Attempted to put with a null payload"); + return errors::Z_EINVAL; } + }; + + let mut put = session.put(key_expr, payload); + + if !options.encoding.is_null() { + let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + put = put.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + put = put.attachment(attachment); + } + + if let Err(e) = put.res_sync() { + log::error!("{}", e); + errors::Z_EGENERIC + } else { + errors::Z_OK } } @@ -141,7 +133,7 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression to delete. +/// key_expr: The key expression to delete. /// options: The put options. /// Returns: /// ``0`` in case of success, negative values in case of failure. @@ -149,28 +141,21 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_delete( session: z_session_t, - keyexpr: z_keyexpr_t, - opts: Option<&z_delete_options_t>, -) -> i8 { - match session.upgrade() { - Some(s) => { - let mut res = s.delete(keyexpr); - if let Some(opts) = opts { - res = res - .congestion_control(opts.congestion_control.into()) - .priority(opts.priority.into()); - } - match res.res_sync() { - Err(e) => { - log::error!("{}", e); - e.errno().get() - } - Ok(()) => 0, - } - } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - i8::MIN + key_expr: z_keyexpr_t, + opts: z_delete_options_t, +) -> errors::ZCError { + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + let del + = session.delete(key_expr) + .congestion_control(opts.congestion_control.into()) + .priority(opts.priority.into()); + + match del.res_sync() { + Err(e) => { + log::error!("{}", e); + errors::Z_EGENERIC } + Ok(()) => errors::Z_OK, } } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 92e797e2e..4ab406708 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -13,45 +13,37 @@ // use std::mem::MaybeUninit; +use std::ptr::null; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh::prelude::SessionDeclarations; +use zenoh::session; +use zenoh::session::Session; +use zenoh::subscriber::Reliability; use zenoh_ext::*; -use crate::z_closure_owned_query_call; -use crate::ze_owned_publication_cache_t; -use crate::{ - impl_guarded_transmute, opaque_types::z_sample_t, z_closure_sample_call, z_get_options_t, - z_keyexpr_t, z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, +use crate::errors; +use crate::transmute::unwrap_ref_unchecked; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; +use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteUninitPtr; +use crate::z_keyexpr_t; +use crate::z_owned_closure_sample_t; +use crate::z_reliability_t; +use crate::{z_closure_sample_call, z_get_options_t, + z_query_consolidation_none, z_query_consolidation_t, z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, - zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, LOG_INVALID_SESSION, + zcu_reply_keyexpr_default, zcu_reply_keyexpr_t }; -pub struct FetchingSubscriberWrapper { - fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, - session: z_session_t, -} -//type FetchingSubscriber = Option>>; - -/// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. -/// -/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. use crate::opaque_types::ze_owned_querying_subscriber_t; -decl_transmute_owned!(default_inplace_init Option>, z_owned_querying_subscriber_t); - use crate::opaque_types::ze_querying_subscriber_t; -decl_transmute_copy!( - &'static Option>, - z_querying_subscriber_t -); +decl_transmute_owned!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); +decl_transmute_handle!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); /// Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type #[no_mangle] @@ -59,7 +51,7 @@ decl_transmute_copy!( pub extern "C" fn ze_querying_subscriber_null( this: *mut MaybeUninit, ) { - let this = ze_owned_querying_subscriber_t::transmute_uninit_ptr(this); + let this = this.transmute_uninit_ptr(); Inplace::empty(this); } @@ -78,9 +70,9 @@ pub extern "C" fn ze_querying_subscriber_null( #[repr(C)] #[allow(non_camel_case_types)] pub struct ze_querying_subscriber_options_t { - // reliability: z_reliability_t, + reliability: z_reliability_t, allowed_origin: zcu_locality_t, - query_selector: z_keyexpr_t, + query_selector: *const z_keyexpr_t, query_target: z_query_target_t, query_consolidation: z_query_consolidation_t, query_accept_replies: zcu_reply_keyexpr_t, @@ -91,9 +83,9 @@ pub struct ze_querying_subscriber_options_t { #[no_mangle] pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscriber_options_t { ze_querying_subscriber_options_t { - // reliability: SubInfo::default().reliability.into(), + reliability: Reliability::BestEffort.into(), allowed_origin: zcu_locality_default(), - query_selector: z_keyexpr_t::null(), + query_selector: null(), query_target: z_query_target_default(), query_consolidation: z_query_consolidation_none(), query_accept_replies: zcu_reply_keyexpr_default(), @@ -135,55 +127,46 @@ pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscr #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn ze_declare_querying_subscriber( + this: *mut MaybeUninit, session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - options: Option<&ze_querying_subscriber_options_t>, -) -> ze_owned_querying_subscriber_t { + options: ze_querying_subscriber_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); - - match session.upgrade() { - Some(s) => { - let mut sub = s.declare_subscriber(keyexpr).querying(); - if let Some(options) = options { - sub = sub - // .reliability(options.reliability.into()) - .allowed_origin(options.allowed_origin.into()) - .query_target(options.query_target.into()) - .query_consolidation(options.query_consolidation) - .query_accept_replies(options.query_accept_replies.into()); - if options.query_selector.is_some() { - let query_selector = options - .query_selector - .as_ref() - .map(|s| s.clone().into_owned()); - if let Some(query_selector) = query_selector { - sub = sub.query_selector(query_selector) - } - } - if options.query_timeout_ms != 0 { - sub = sub - .query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); - } - } - match sub - .callback(move |sample| { - let sample = z_sample_t::new(&sample); - z_closure_sample_call(&closure, &sample) - }) - .res() - { - Ok(sub) => ze_owned_querying_subscriber_t::new(sub, session), - Err(e) => { - log::debug!("{}", e); - ze_owned_querying_subscriber_t::null() - } - } + let session = session.transmute_copy(); + let mut sub = session.declare_subscriber(key_expr.transmute_ref()).querying(); + sub = sub + .reliability(options.reliability.into()) + .allowed_origin(options.allowed_origin.into()) + .query_target(options.query_target.into()) + .query_consolidation(options.query_consolidation) + .query_accept_replies(options.query_accept_replies.into()); + if !options.query_selector.is_null() { + let query_selector = unsafe { *options.query_selector }.transmute_ref().clone(); + sub = sub.query_selector(query_selector) + } + if options.query_timeout_ms != 0 { + sub = sub + .query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); + } + let sub = sub + .callback(move |sample| { + let sample = sample.transmute_handle(); + z_closure_sample_call(&closure, sample); + }); + match sub.res() + { + Ok(sub) => { + Inplace::init(this, Some((sub, session))); + errors::Z_OK } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - ze_owned_querying_subscriber_t::null() + Err(e) => { + log::debug!("{}", e); + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -196,68 +179,57 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( sub: ze_querying_subscriber_t, selector: z_keyexpr_t, options: Option<&z_get_options_t>, -) -> i8 { +) -> errors::ZCError { unsafe impl Sync for z_get_options_t {} - - if let Some(sub) = sub.as_ref() { - match sub.session.upgrade() { - Some(s) => { - if let Err(e) = sub - .fetching_subscriber - .fetch({ - let selector = KeyExpr::try_from(selector).unwrap(); - move |cb| match options { - Some(options) => s - .get(selector) - .target(options.target.into()) - .consolidation(options.consolidation) - .timeout(std::time::Duration::from_millis(options.timeout_ms)) - .callback(cb) - .res_sync(), - None => s.get(selector).callback(cb).res_sync(), - } - }) - .res() - { - log::debug!("{}", e); - return -1; - } - } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - return -1; - } + let sub = sub.transmute_ref(); + let session = sub.1; + let selector = selector.transmute_ref().clone(); + if let Err(e) = sub.0 + .fetch({ + let selector = KeyExpr::try_from(selector).unwrap(); + move |cb| match options { + Some(options) => session + .get(selector) + .target(options.target.into()) + .consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .callback(cb) + .res_sync(), + None => session.get(selector).callback(cb).res_sync(), } + }) + .res() + { + log::debug!("{}", e); + return errors::Z_EGENERIC; } - 0 + errors::Z_OK } /// Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn ze_undeclare_querying_subscriber(sub: &mut ze_owned_querying_subscriber_t) -> i8 { - let sub = sub.transmute_mut(); - - if let Some(s) = sub.take() { - if let Err(e) = s.fetching_subscriber.close().res_sync() { - log::warn!("{}", e); - return e.errno().get(); +pub extern "C" fn ze_undeclare_querying_subscriber(this: &mut ze_owned_querying_subscriber_t) -> errors::ZCError { + if let Some(s) = this.transmute_mut().extract().take() { + if let Err(e) = s.0.close().res_sync() { + log::error!("{}", e); + return errors::Z_EGENERIC } } - 0 + errors::Z_OK } -/// Returns ``true`` if `sub` is valid. +/// Returns ``true`` if `this` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn ze_querying_subscriber_check(sub: &ze_owned_querying_subscriber_t) -> bool { - sub.as_ref().is_some() +pub extern "C" fn ze_querying_subscriber_check(this: &ze_owned_querying_subscriber_t) -> bool { + this.transmute_ref().is_some() } -/// Returns a :c:type:`ze_querying_subscriber_loan` loaned from `p`. +/// Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. #[no_mangle] -pub extern "C" fn ze_querying_subscriber_loan( - p: &ze_owned_querying_subscriber_t, -) -> ze_querying_subscriber_t { - ze_querying_subscriber_t(p) +pub extern "C" fn ze_querying_subscriber_loan(this: &ze_owned_querying_subscriber_t,) -> ze_querying_subscriber_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } diff --git a/src/subscriber.rs b/src/subscriber.rs index acdae4f60..ceab769cf 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -12,107 +12,76 @@ // ZettaScale Zenoh team, // -use crate::commons::*; -use crate::impl_guarded_transmute; +use std::mem::MaybeUninit; + +use crate::errors; use crate::keyexpr::*; -use crate::session::*; +use crate::transmute::unwrap_ref_unchecked; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; +use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteUninitPtr; use crate::z_closure_sample_call; use crate::z_owned_closure_sample_t; -use crate::LOG_INVALID_SESSION; +use crate::z_session_t; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -// use zenoh::subscriber::Reliability; -// use zenoh_protocol::core::SubInfo; -use zenoh_util::core::zresult::ErrNo; +use zenoh::subscriber::Reliability; +use zenoh::subscriber::Subscriber; /// The subscription reliability. /// /// - **Z_RELIABILITY_BEST_EFFORT** /// - **Z_RELIABILITY_RELIABLE** -// #[allow(non_camel_case_types, clippy::upper_case_acronyms)] -// #[repr(C)] -// #[derive(Clone, Copy)] -// pub enum z_reliability_t { -// BEST_EFFORT, -// RELIABLE, -// } - -// impl From for z_reliability_t { -// #[inline] -// fn from(r: Reliability) -> Self { -// match r { -// Reliability::BestEffort => z_reliability_t::BEST_EFFORT, -// Reliability::Reliable => z_reliability_t::RELIABLE, -// } -// } -// } - -// impl From for Reliability { -// #[inline] -// fn from(val: z_reliability_t) -> Self { -// match val { -// z_reliability_t::BEST_EFFORT => Reliability::BestEffort, -// z_reliability_t::RELIABLE => Reliability::Reliable, -// } -// } -// } - -/**************************************/ -/* DECLARATION */ -/**************************************/ -type Subscriber = Option>>; - -/// An owned zenoh subscriber. Destroying the subscriber cancels the subscription. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_subscriber_t([u64; 1]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_subscriber_t([u32; 1]); - -impl_guarded_transmute!(Subscriber, z_owned_subscriber_t); +#[allow(non_camel_case_types, clippy::upper_case_acronyms)] +#[repr(C)] +#[derive(Clone, Copy)] +pub enum z_reliability_t { + BEST_EFFORT, + RELIABLE, +} -impl z_owned_subscriber_t { - pub fn new(sub: zenoh::subscriber::Subscriber<'static, ()>) -> Self { - Some(Box::new(sub)).into() - } - pub fn null() -> Self { - None.into() +impl From for z_reliability_t { +#[inline] + fn from(r: Reliability) -> Self { + match r { + Reliability::BestEffort => z_reliability_t::BEST_EFFORT, + Reliability::Reliable => z_reliability_t::RELIABLE, + } } } -/// Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type -#[no_mangle] -pub extern "C" fn z_subscriber_null() -> z_owned_subscriber_t { - z_owned_subscriber_t::null() +impl From for Reliability { +#[inline] + fn from(val: z_reliability_t) -> Self { + match val { + z_reliability_t::BEST_EFFORT => Reliability::BestEffort, + z_reliability_t::RELIABLE => Reliability::Reliable, + } + } } -/// A loaned zenoh subscriber. -#[allow(non_camel_case_types)] -#[derive(Clone, Copy)] -#[repr(C)] -pub struct z_subscriber_t(*const z_owned_subscriber_t); +pub use crate::opaque_types::z_owned_subscriber_t; +pub use crate::opaque_types::z_subscriber_t; -impl AsRef for z_subscriber_t { - fn as_ref(&self) -> &Subscriber { - unsafe { &(*self.0) } - } +decl_transmute_owned!(Option>, z_owned_subscriber_t); +decl_transmute_handle!(Subscriber<'static, ()>, z_subscriber_t); + +/// Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type +#[no_mangle] +pub extern "C" fn z_subscriber_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); } -/// Returns a :c:type:`z_subscriber_t` loaned from `p`. +/// Returns a :c:type:`z_subscriber_t` loaned from `this`. #[no_mangle] -pub extern "C" fn z_subscriber_loan(p: &z_owned_subscriber_t) -> z_subscriber_t { - z_subscriber_t(p) +pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> z_subscriber_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } /// Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. @@ -122,15 +91,14 @@ pub extern "C" fn z_subscriber_loan(p: &z_owned_subscriber_t) -> z_subscriber_t #[allow(non_camel_case_types)] #[repr(C)] pub struct z_subscriber_options_t { - // pub reliability: z_reliability_t, + pub reliability: z_reliability_t, } /// Constructs the default value for :c:type:`z_subscriber_options_t`. #[no_mangle] pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { - // let info = SubInfo::default(); z_subscriber_options_t { - // reliability: info.reliability.into(), + reliability: Reliability::BestEffort.into() } } @@ -138,7 +106,7 @@ pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression to subscribe. +/// key_expr: The key expression to subscribe. /// callback: The callback function that will be called each time a data matching the subscribed expression is received. /// opts: The options to be passed to describe the options to be passed to the subscriber declaration. /// @@ -168,34 +136,33 @@ pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_subscriber( + this: *mut MaybeUninit, session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - opts: Option<&z_subscriber_options_t>, -) -> z_owned_subscriber_t { + options: z_subscriber_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); - - match session.upgrade() { - Some(s) => { - let mut res = s.declare_subscriber(keyexpr).callback(move |sample| { - let sample = z_sample_t::new(&sample); - z_closure_sample_call(&closure, &sample) - }); - if let Some(opts) = opts { - // res = res.reliability(opts.reliability.into()) - } - match res.res() { - Ok(sub) => z_owned_subscriber_t::new(sub), - Err(e) => { - log::debug!("{}", e); - z_owned_subscriber_t::null() - } - } - } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - z_owned_subscriber_t::null() + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + let subscriber + = session.declare_subscriber(key_expr).callback(move |sample| { + let sample = sample.transmute_handle(); + z_closure_sample_call(&closure, sample) + }); + + let subscriber = subscriber.reliability(options.reliability.into()); + match subscriber.res() { + Ok(sub) => { + Inplace::init(this, Some(sub)); + errors::Z_OK + }, + Err(e) => { + log::error!("{}", e); + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -203,30 +170,27 @@ pub extern "C" fn z_declare_subscriber( /// Returns the key expression of the subscriber. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_owned_keyexpr_t { - if let Some(p) = subscriber.as_ref() { - p.key_expr().clone().into() - } else { - z_keyexpr_t::null().into() - } +pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_keyexpr_t { + let subscriber = subscriber.transmute_ref(); + subscriber.key_expr().transmute_handle() } /// Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_subscriber(sub: &mut z_owned_subscriber_t) -> i8 { - if let Some(s) = sub.take() { +pub extern "C" fn z_undeclare_subscriber(subscriber: &mut z_owned_subscriber_t) -> errors::ZCError { + if let Some(s) = subscriber.transmute_mut().extract().take() { if let Err(e) = s.undeclare().res_sync() { - log::warn!("{}", e); - return e.errno().get(); + log::error!("{}", e); + return errors::Z_EGENERIC } } - 0 + errors::Z_OK } /// Returns ``true`` if `sub` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_subscriber_check(sub: &z_owned_subscriber_t) -> bool { - sub.as_ref().is_some() +pub extern "C" fn z_subscriber_check(subscriber: &z_owned_subscriber_t) -> bool { + subscriber.transmute_ref().is_some() } diff --git a/src/transmute.rs b/src/transmute.rs index 4aaa3d157..cafe930ea 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -92,27 +92,24 @@ impl Inplace for T { macro_rules! validate_equivalence { ($type_a:ty, $type_b:ty) => { const _: () = { - let align_a = std::mem::align_of::<$type_a>(); - let align_b = std::mem::align_of::<$type_b>(); - if align_a != align_b { - panic!( - "Alingment mismatch: type `{}` has align {}, type `{}` has align {}", - stringify!($type_a), - align_a, - stringify!($type_b), - align_b - ); + use const_format::concatcp; + const TYPE_NAME_A: &str = stringify!($type_a); + const TYPE_NAME_B: &str = stringify!($type_b); + const ALIGN_A: usize = std::mem::align_of::<$type_a>(); + const ALIGN_B: usize = std::mem::align_of::<$type_b>(); + if ALIGN_A != ALIGN_B { + const ERR_MESSAGE: &str = concatcp!( + "Alingment mismatch: type ", TYPE_NAME_A, " has alignment ", ALIGN_A, + " while type ", TYPE_NAME_B, " has alignment ", ALIGN_B); + panic!("{}", ERR_MESSAGE); } - let size_a = std::mem::size_of::<$type_a>(); - let size_b = std::mem::size_of::<$type_b>(); - if size_a != size_b { - panic!( - "Size mismatch: type `{}` has size {}, type `{}` has size {}", - stringify!($type_a), - size_a, - stringify!($type_b), - size_b - ); + const SIZE_A: usize = std::mem::size_of::<$type_a>(); + const SIZE_B: usize = std::mem::size_of::<$type_b>(); + if SIZE_A != SIZE_B { + const ERR_MESSAGE: &str = concatcp!( + "Size mismatch: type ", TYPE_NAME_A, " has size ", SIZE_A, + " while type ", TYPE_NAME_B, " has size ", SIZE_B); + panic!("{}", ERR_MESSAGE); } }; }; From 6a92b922e09df8e9da77ddf1977fb6b5f8454dc1 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 09:38:34 +0200 Subject: [PATCH 049/377] fixes --- build.rs | 4 +- include/zenoh-gen.h | 2845 ------------------------------------ include/zenoh_commons.h | 2390 ++++++++++++++++++++++++++++++ include/zenoh_concrete.h | 67 + src/commons.rs | 10 +- src/get.rs | 4 +- src/info.rs | 8 +- src/keyexpr.rs | 4 +- src/liveliness.rs | 6 +- src/payload.rs | 39 +- src/publication_cache.rs | 2 +- src/publisher.rs | 15 +- src/put.rs | 4 +- src/queryable.rs | 4 +- src/querying_subscriber.rs | 4 +- src/session.rs | 22 +- src/subscriber.rs | 4 +- 17 files changed, 2526 insertions(+), 2906 deletions(-) delete mode 100644 include/zenoh-gen.h diff --git a/build.rs b/build.rs index 120b308f7..83eabc4f8 100644 --- a/build.rs +++ b/build.rs @@ -40,8 +40,8 @@ fn main() { configure(); let split_guide = SplitGuide::from_yaml(SPLITGUIDE_PATH); - // split_bindings(&split_guide).unwrap(); - // text_replace(split_guide.rules.iter().map(|(name, _)| name.as_str())); + split_bindings(&split_guide).unwrap(); + text_replace(split_guide.rules.iter().map(|(name, _)| name.as_str())); fs_extra::copy_items( &["include"], diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h deleted file mode 100644 index 19b3fc6c9..000000000 --- a/include/zenoh-gen.h +++ /dev/null @@ -1,2845 +0,0 @@ -#include -#include -#include -#include -#include - - - - -#define DEFAULT_SCOUTING_TIMEOUT 1000 - -/** - * The kind of congestion control. - * - * - **BLOCK** - * - **DROP** - */ -typedef enum z_congestion_control_t { - Z_CONGESTION_CONTROL_T_BLOCK, - Z_CONGESTION_CONTROL_T_DROP, -} z_congestion_control_t; - -/** - * Consolidation mode values. - * - * - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector - * If the selector contains time range properties, consolidation mode `NONE` is used. - * Otherwise the `LATEST` consolidation mode is used. - * - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. - * - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time - * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple - * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp - * ts2 > ts1. It optimizes latency. - * - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. - * It optimizes bandwidth. - */ -typedef enum z_consolidation_mode_t { - Z_CONSOLIDATION_MODE_T_AUTO = -1, - Z_CONSOLIDATION_MODE_T_NONE = 0, - Z_CONSOLIDATION_MODE_T_MONOTONIC = 1, - Z_CONSOLIDATION_MODE_T_LATEST = 2, -} z_consolidation_mode_t; - -/** - * A :c:type:`z_keyexpr_intersection_level_t`. - * - * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** - */ -typedef enum z_keyexpr_intersection_level_t { - Z_KEYEXPR_INTERSECTION_LEVEL_T_DISJOINT = 0, - Z_KEYEXPR_INTERSECTION_LEVEL_T_INTERSECTS = 1, - Z_KEYEXPR_INTERSECTION_LEVEL_T_INCLUDES = 2, - Z_KEYEXPR_INTERSECTION_LEVEL_T_EQUALS = 3, -} z_keyexpr_intersection_level_t; - -/** - * The priority of zenoh messages. - * - * - **REAL_TIME** - * - **INTERACTIVE_HIGH** - * - **INTERACTIVE_LOW** - * - **DATA_HIGH** - * - **DATA** - * - **DATA_LOW** - * - **BACKGROUND** - */ -typedef enum z_priority_t { - Z_PRIORITY_T_REAL_TIME = 1, - Z_PRIORITY_T_INTERACTIVE_HIGH = 2, - Z_PRIORITY_T_INTERACTIVE_LOW = 3, - Z_PRIORITY_T_DATA_HIGH = 4, - Z_PRIORITY_T_DATA = 5, - Z_PRIORITY_T_DATA_LOW = 6, - Z_PRIORITY_T_BACKGROUND = 7, -} z_priority_t; - -/** - * The Queryables that should be target of a :c:func:`z_get`. - * - * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. - * - **ALL_COMPLETE**: All complete queryables. - * - **ALL**: All matching queryables. - */ -typedef enum z_query_target_t { - Z_QUERY_TARGET_T_BEST_MATCHING, - Z_QUERY_TARGET_T_ALL, - Z_QUERY_TARGET_T_ALL_COMPLETE, -} z_query_target_t; - -/** - * The subscription reliability. - * - * - **Z_RELIABILITY_BEST_EFFORT** - * - **Z_RELIABILITY_RELIABLE** - */ -typedef enum z_reliability_t { - Z_RELIABILITY_T_BEST_EFFORT, - Z_RELIABILITY_T_RELIABLE, -} z_reliability_t; - -typedef enum z_sample_kind_t { - Z_SAMPLE_KIND_T_PUT = 0, - Z_SAMPLE_KIND_T_DELETE = 1, -} z_sample_kind_t; - -typedef enum zcu_locality_t { - ZCU_LOCALITY_T_ANY = 0, - ZCU_LOCALITY_T_SESSION_LOCAL = 1, - ZCU_LOCALITY_T_REMOTE = 2, -} zcu_locality_t; - -typedef enum zcu_reply_keyexpr_t { - ZCU_REPLY_KEYEXPR_T_ANY = 0, - ZCU_REPLY_KEYEXPR_T_MATCHING_QUERY = 1, -} zcu_reply_keyexpr_t; - -/** - * A split buffer that owns all of its data. - * - * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - */ -typedef struct ALIGN(8) z_owned_bytes_t { - uint8_t _0[40]; -} z_owned_bytes_t; - -typedef int8_t ZCError; - -/** - * A loaned payload. - */ -typedef struct ALIGN(8) z_bytes_t { - uint8_t _0[8]; -} z_bytes_t; - -typedef struct z_owned_slice_t { - uint8_t *start; - size_t len; -} z_owned_slice_t; - -/** - * A map of maybe-owned vector of bytes to maybe-owned vector of bytes. - * - * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher - */ -typedef struct ALIGN(8) z_owned_slice_map_t { - uint8_t _0[48]; -} z_owned_slice_map_t; - -/** - * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` - * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with - * `z_check` and `z_str_check` correspondently - */ -typedef struct z_owned_str_t { - char *_cstr; -} z_owned_str_t; - -/** - * A contiguous view of bytes owned by some other entity. - * - * `start` being `null` is considered a gravestone value, - * and empty slices are represented using a possibly dangling pointer for `start`. - */ -typedef struct z_slice_t { - const uint8_t *start; - size_t len; -} z_slice_t; - -typedef struct ALIGN(8) z_slice_map_t { - uint8_t _0[8]; -} z_slice_map_t; - -/** - * A reader for payload data. - */ -typedef struct ALIGN(8) z_owned_bytes_t_reader_t { - uint8_t _0[24]; -} z_owned_bytes_t_reader_t; - -typedef struct ALIGN(8) z_bytes_reader_t { - uint8_t _0[8]; -} z_bytes_reader_t; - -/** - * Clock - * Uses monotonic clock - */ -typedef struct z_clock_t { - uint64_t t; - const void *t_base; -} z_clock_t; - -/** - * An owned zenoh session. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_session_t { - uint8_t _0[8]; -} z_owned_session_t; - -/** - * Represents a Zenoh ID. - * - * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. - */ -typedef struct ALIGN(1) z_id_t { - uint8_t _0[16]; -} z_id_t; - -/** - * An owned array of owned, zenoh allocated, NULL terminated strings. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_str_array_t { - char **val; - size_t len; -} z_owned_str_array_t; - -/** - * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct z_owned_hello_t { - unsigned int _whatami; - struct z_id_t _pid; - struct z_owned_str_array_t _locators; -} z_owned_hello_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_hello_t { - void *context; - void (*call)(struct z_owned_hello_t*, void*); - void (*drop)(void*); -} z_owned_closure_hello_t; - -/** - * - * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. - * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. - */ -typedef struct ALIGN(8) z_owned_query_t { - uint8_t _0[16]; -} z_owned_query_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_owned_query_t { - void *context; - void (*call)(struct z_owned_query_t*, void *context); - void (*drop)(void*); -} z_owned_closure_owned_query_t; - -typedef struct ALIGN(8) z_query_t { - uint8_t _0[8]; -} z_query_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_query_t { - void *context; - void (*call)(struct z_query_t, void *context); - void (*drop)(void*); -} z_owned_closure_query_t; - -typedef struct ALIGN(8) z_reply_t { - uint8_t _0[8]; -} z_reply_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_reply_t { - void *context; - void (*call)(struct z_reply_t, void*); - void (*drop)(void*); -} z_owned_closure_reply_t; - -typedef struct ALIGN(8) z_sample_t { - uint8_t _0[8]; -} z_sample_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_sample_t { - void *context; - void (*call)(struct z_sample_t, void *context); - void (*drop)(void*); -} z_owned_closure_sample_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_zid_t { - void *context; - void (*call)(const struct z_id_t*, void*); - void (*drop)(void*); -} z_owned_closure_zid_t; - -typedef struct ALIGN(8) z_owned_condvar_t { - uint8_t _0[24]; -} z_owned_condvar_t; - -typedef struct ALIGN(8) z_condvar_t { - uint8_t _0[8]; -} z_condvar_t; - -typedef struct ALIGN(8) z_mutex_t { - uint8_t _0[8]; -} z_mutex_t; - -/** - * An owned zenoh configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_config_t { - uint8_t _0[8]; -} z_owned_config_t; - -/** - * A loaned zenoh configuration. - */ -typedef struct ALIGN(8) z_config_t { - uint8_t _0[8]; -} z_config_t; - -/** - * A zenoh-allocated key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` - * for wire and computation efficiency. - * - * A `key expression `_ can be either: - * - A plain string expression. - * - A pure numerical id. - * - The combination of a numerical prefix and a string suffix. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_keyexpr_t { - uint8_t _0[32]; -} z_owned_keyexpr_t; - -typedef struct ALIGN(8) z_session_t { - uint8_t _0[8]; -} z_session_t; - -/** - * A loaned key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, - * both for local processing and network-wise. - */ -typedef struct ALIGN(8) z_keyexpr_t { - uint8_t _0[8]; -} z_keyexpr_t; - -/** - * Options passed to the :c:func:`z_declare_publisher` function. - * - * Members: - * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. - * z_priority_t priority: The priority of messages from this publisher. - */ -typedef struct z_publisher_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_publisher_options_t; - -/** - * An owned zenoh publisher. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_publisher_t { - uint8_t _0[56]; -} z_owned_publisher_t; - -/** - * Options passed to the :c:func:`z_declare_queryable` function. - * - * Members: - * bool complete: The completeness of the Queryable. - */ -typedef struct z_queryable_options_t { - bool complete; -} z_queryable_options_t; - -/** - * An owned zenoh queryable. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_queryable_t { - uint8_t _0[32]; -} z_owned_queryable_t; - -/** - * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_subscriber_t { - uint8_t _0[32]; -} z_owned_subscriber_t; - -/** - * Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - */ -typedef struct z_subscriber_options_t { - enum z_reliability_t reliability; -} z_subscriber_options_t; - -/** - * Options passed to the :c:func:`z_delete` function. - */ -typedef struct z_delete_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_delete_options_t; - -typedef struct ALIGN(8) z_owned_encoding_t { - uint8_t _0[48]; -} z_owned_encoding_t; - -/** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. - */ -typedef struct ALIGN(8) z_encoding_t { - uint8_t _0[8]; -} z_encoding_t; - -/** - * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. - */ -typedef struct z_query_consolidation_t { - enum z_consolidation_mode_t mode; -} z_query_consolidation_t; - -/** - * Options passed to the :c:func:`z_get` function. - * - * Members: - * z_query_target_t target: The Queryables that should be target of the query. - * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. - * z_value_t value: An optional value to attach to the query. - * z_bytes_t attachment: The attachment to attach to the query. - * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. - */ -typedef struct z_get_options_t { - enum z_query_target_t target; - struct z_query_consolidation_t consolidation; - struct z_owned_bytes_t *payload; - struct z_owned_encoding_t *encoding; - struct z_owned_bytes_t *attachment; - uint64_t timeout_ms; -} z_get_options_t; - -/** - * An borrowed array of borrowed, zenoh allocated, NULL terminated strings. - */ -typedef struct z_str_array_t { - size_t len; - const char *const *val; -} z_str_array_t; - -/** - * A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct z_hello_t { - unsigned int whatami; - struct z_id_t pid; - struct z_str_array_t locators; -} z_hello_t; - -typedef struct ALIGN(8) z_owned_mutex_t { - uint8_t _0[32]; -} z_owned_mutex_t; - -typedef struct ALIGN(8) z_publisher_t { - uint8_t _0[8]; -} z_publisher_t; - -/** - * Represents the set of options that can be applied to the delete operation by a previously declared publisher, - * whenever issued via :c:func:`z_publisher_delete`. - */ -typedef struct z_publisher_delete_options_t { - uint8_t __dummy; -} z_publisher_delete_options_t; - -/** - * Options passed to the :c:func:`z_publisher_put` function. - * - * Members: - * z_owned_encoding_t encoding: The encoding of the payload. - * z_owned_bytes_t attachment: The attachment to attach to the publication. - */ -typedef struct z_publisher_put_options_t { - struct z_owned_encoding_t *encoding; - struct z_owned_bytes_t *attachment; -} z_publisher_put_options_t; - -/** - * Options passed to the :c:func:`z_put` function. - * - * Members: - * z_encoding_t encoding: The encoding of the payload. - * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. - * z_priority_t priority: The priority of this message. - * z_bytes_t attachment: The attachment to this message. - */ -typedef struct z_put_options_t { - struct z_owned_encoding_t *encoding; - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; - struct z_owned_bytes_t *attachment; -} z_put_options_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - `this` is a pointer to an arbitrary state. - * - `call` is the typical callback function. `this` will be passed as its last argument. - * - `drop` allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * We guarantee that: - * - `call` will never be called once `drop` has started. - * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_query_channel_closure_t { - void *context; - bool (*call)(struct z_owned_query_t*, void*); - void (*drop)(void*); -} z_owned_query_channel_closure_t; - -/** - * A pair of closures - */ -typedef struct z_owned_query_channel_t { - struct z_owned_closure_query_t send; - struct z_owned_query_channel_closure_t recv; -} z_owned_query_channel_t; - -/** - * Represents the set of options that can be applied to a query reply, - * sent via :c:func:`z_query_reply`. - * - * Members: - * z_owned_encoding_t encoding: The encoding of the payload. - * z_owned_bytes_t attachment: The attachment to this reply. - */ -typedef struct z_query_reply_options_t { - struct z_owned_encoding_t *encoding; - struct z_owned_bytes_t *attachment; -} z_query_reply_options_t; - -typedef struct ALIGN(8) z_value_t { - uint8_t _0[8]; -} z_value_t; - -/** - * An owned reply to a :c:func:`z_get`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_reply_t { - uint8_t _0[256]; -} z_owned_reply_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - `this` is a pointer to an arbitrary state. - * - `call` is the typical callback function. `this` will be passed as its last argument. - * - `drop` allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * We guarantee that: - * - `call` will never be called once `drop` has started. - * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_reply_channel_closure_t { - void *context; - bool (*call)(struct z_owned_reply_t*, void*); - void (*drop)(void*); -} z_owned_reply_channel_closure_t; - -/** - * A pair of closures, the `send` one accepting - */ -typedef struct z_owned_reply_channel_t { - struct z_owned_closure_reply_t send; - struct z_owned_reply_channel_closure_t recv; -} z_owned_reply_channel_t; - -typedef struct ALIGN(8) z_timestamp_t { - uint8_t _0[24]; -} z_timestamp_t; - -typedef struct z_owned_scouting_config_t { - struct z_owned_config_t _config; - unsigned long zc_timeout_ms; - uint8_t zc_what; -} z_owned_scouting_config_t; - -/** - * The body of a loop over a z_slice_map's key-value pairs. - * - * `key` and `value` are loaned to the body for the duration of a single call. - * `context` is passed transparently through the iteration driver. - * - * Returning `true` is treated as `continue`. - */ -typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); - -typedef struct ALIGN(8) z_subscriber_t { - uint8_t _0[8]; -} z_subscriber_t; - -typedef struct ALIGN(8) z_owned_task_t { - uint8_t _0[24]; -} z_owned_task_t; - -typedef struct z_task_attr_t { - size_t _0; -} z_task_attr_t; - -/** - * Time - * Uses system clock - */ -typedef struct z_time_t { - uint64_t t; -} z_time_t; - -/** - * The options for `zc_liveliness_declare_token` - */ -typedef struct zc_liveliness_declaration_options_t { - uint8_t _dummy; -} zc_liveliness_declaration_options_t; - -/** - * The options for :c:func:`zc_liveliness_declare_subscriber` - */ -typedef struct zc_liveliness_declare_subscriber_options_t { - uint8_t _dummy; -} zc_liveliness_declare_subscriber_options_t; - -/** - * A liveliness token that can be used to provide the network with information about connectivity to its - * declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key - * expressions. - * - * A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. - */ -typedef struct ALIGN(8) zc_owned_liveliness_token_t { - uint8_t _0[32]; -} zc_owned_liveliness_token_t; - -/** - * The options for :c:func:`zc_liveliness_declare_subscriber` - */ -typedef struct zc_liveliness_get_options_t { - uint32_t timeout_ms; -} zc_liveliness_get_options_t; - -/** - * An owned sample. - * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. - */ -typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[240]; -} zc_owned_sample_t; - -/** - * A struct that indicates if there exist Subscribers matching the Publisher's key expression. - * - * Members: - * bool matching: true if there exist Subscribers matching the Publisher's key expression. - */ -typedef struct zcu_matching_status_t { - bool matching; -} zcu_matching_status_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct zcu_owned_closure_matching_status_t { - void *context; - void (*call)(const struct zcu_matching_status_t*, void*); - void (*drop)(void*); -} zcu_owned_closure_matching_status_t; - -/** - * An owned zenoh matching listener. Destroying the matching listener cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) zcu_owned_matching_listener_t { - uint8_t _0[40]; -} zcu_owned_matching_listener_t; - -/** - * An owned zenoh publication_cache. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) ze_owned_publication_cache_t { - uint8_t _0[96]; -} ze_owned_publication_cache_t; - -/** - * Options passed to the :c:func:`ze_declare_publication_cache` function. - * - * Members: - * z_keyexpr_t queryable_prefix: The prefix used for queryable - * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this - * publication cache - * bool queryable_complete: the `complete` option for the queryable - * size_t history: The the history size - * size_t resources_limit: The limit number of cached resources - */ -typedef struct ze_publication_cache_options_t { - const struct z_keyexpr_t *queryable_prefix; - enum zcu_locality_t queryable_origin; - bool queryable_complete; - size_t history; - size_t resources_limit; -} ze_publication_cache_options_t; - -/** - * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) ze_owned_querying_subscriber_t { - uint8_t _0[64]; -} ze_owned_querying_subscriber_t; - -/** - * Represents the set of options that can be applied to a querying subscriber, - * upon its declaration via :c:func:`ze_declare_querying_subscriber`. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - * zcu_locality_t allowed_origin: The restriction for the matching publications that will be - * receive by this subscriber. - * z_keyexpr_t query_selector: The selector to be used for queries. - * z_query_target_t query_target: The target to be used for queries. - * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. - * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. - * uint64_t query_timeout_ms: The timeout to be used for queries. - */ -typedef struct ze_querying_subscriber_options_t { - enum z_reliability_t reliability; - enum zcu_locality_t allowed_origin; - const struct z_keyexpr_t *query_selector; - enum z_query_target_t query_target; - struct z_query_consolidation_t query_consolidation; - enum zcu_reply_keyexpr_t query_accept_replies; - uint64_t query_timeout_ms; -} ze_querying_subscriber_options_t; - -typedef struct ALIGN(8) ze_querying_subscriber_t { - uint8_t _0[8]; -} ze_querying_subscriber_t; - -#define Z_OK 0 - -#define Z_EINVAL -1 - -#define Z_EPARSE -2 - -#define Z_EIO -3 - -#define Z_ENETWORK -4 - -#define Z_EBUSY_MUTEX -16 - -#define Z_EINVAL_MUTEX -22 - -#define Z_EAGAIN_MUTEX -11 - -#define Z_EPOISON_MUTEX -22 - -#define Z_EGENERIC INT8_MIN - -extern const unsigned int Z_ROUTER; - -extern const unsigned int Z_PEER; - -extern const unsigned int Z_CLIENT; - -extern const char *Z_CONFIG_MODE_KEY; - -extern const char *Z_CONFIG_CONNECT_KEY; - -extern const char *Z_CONFIG_LISTEN_KEY; - -extern const char *Z_CONFIG_USER_KEY; - -extern const char *Z_CONFIG_PASSWORD_KEY; - -extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; - -extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; - -extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; - -extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; - -extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; - -extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; - -/** - * Returns `true` if the payload is in a valid state. - */ -ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); - -/** - * Increments the payload's reference count, returning an owned version of it. - */ -ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_bytes_t *dst); - -/** - * Decodes payload into owned bytes - */ -ZENOHC_API ZCError z_bytes_decode_into_bytes(struct z_bytes_t payload, struct z_owned_slice_t *dst); - -/** - * Decodes payload into bytes map. - */ -ZENOHC_API -ZCError z_bytes_decode_into_bytes_map(struct z_bytes_t payload, - struct z_owned_slice_map_t *dst); - -/** - * Decodes payload into null-terminated string. - */ -ZENOHC_API ZCError z_bytes_decode_into_string(struct z_bytes_t payload, struct z_owned_str_t *dst); - -/** - * Decrements the payload's reference counter, destroying it if applicable. - * - * `this` will be reset to `z_buffer_null`, preventing UB on double-frees. - */ -ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); - -/** - * Encodes byte sequence by aliasing. - */ -ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, struct z_slice_t bytes); - -/** - * Encodes bytes map by copying. - */ -ZENOHC_API -void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, - struct z_slice_map_t bytes_map); - -/** - * Encodes a null-terminated string by aliasing. - */ -ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const char *cstr); - -/** - * Returns total number bytes in the payload. - */ -ZENOHC_API size_t z_bytes_len(struct z_bytes_t payload); - -/** - * Loans the payload, allowing you to call functions that only need a loan of it. - */ -ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); - -/** - * The gravestone value for `z_owned_bytes_t`. - */ -ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); - -ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_t_reader_t *reader); - -ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_t_reader_t *this_); - -ZENOHC_API -struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_t_reader_t *reader); - -/** - * Creates a reader for the specified `payload`. - * - * Returns 0 in case of success, -1 if `payload` is not valid. - */ -ZENOHC_API -void z_bytes_reader_new(struct z_bytes_t payload, - struct z_owned_bytes_t_reader_t *this_); - -ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_t_reader_t *this_); - -/** - * Reads data into specified destination. - * - * Will read at most `len` bytes. - * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. - */ -ZENOHC_API -size_t z_bytes_reader_read(struct z_bytes_reader_t reader, - uint8_t *dest, - size_t len); - -/** - * Sets the `reader` position indicator for the payload to the value pointed to by offset. - * The new position is exactly offset bytes measured from the beginning of the payload if origin is SEEK_SET, - * from the current reader position if origin is SEEK_CUR, and from the end of the payload if origin is SEEK_END. - * Return ​0​ upon success, negative error code otherwise. - */ -ZENOHC_API -ZCError z_bytes_reader_seek(struct z_bytes_reader_t reader, - int64_t offset, - int origin); - -/** - * Returns the read position indicator. - * Returns read position indicator on success or -1L if failure occurs. - */ -ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t reader); - -ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); - -ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); - -ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); - -ZENOHC_API struct z_clock_t z_clock_now(void); - -/** - * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. - * - * Returns a negative value if an error occured while closing the session. - * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. - */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_hello_call(const struct z_owned_closure_hello_t *closure, - struct z_owned_hello_t *hello); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_hello_drop(struct z_owned_closure_hello_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type - */ -ZENOHC_API struct z_owned_closure_hello_t z_closure_hello_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_owned_query_call(const struct z_owned_closure_owned_query_t *closure, - struct z_owned_query_t *query); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_owned_query_drop(struct z_owned_closure_owned_query_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type - */ -ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_query_call(const struct z_owned_closure_query_t *closure, - struct z_query_t query); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_query_drop(struct z_owned_closure_query_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type - */ -ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, - struct z_reply_t reply); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_reply_drop(struct z_owned_closure_reply_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type - */ -ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - struct z_sample_t sample); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_sample_drop(struct z_owned_closure_sample_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type - */ -ZENOHC_API struct z_owned_closure_sample_t z_closure_sample_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_zid_call(const struct z_owned_closure_zid_t *closure, - const struct z_id_t *sample); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type - */ -ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); - -ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); - -ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); - -ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); - -ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); - -ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); - -ZENOHC_API ZCError z_condvar_signal(struct z_condvar_t this_); - -ZENOHC_API ZCError z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); - -/** - * Returns ``true`` if `config` is valid. - */ -ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); - -/** - * Constructs a default, zenoh-allocated, client mode configuration. - * If `peer` is not null, it is added to the configuration as remote peer. - */ -ZENOHC_API -ZCError z_config_client(const char *const *peers, - size_t n_peers, - struct z_owned_config_t *this_); - -/** - * Clones the config. - */ -ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); - -/** - * Frees `config`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); - -/** - * Returns a :c:type:`z_config_t` loaned from `s`. - */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); - -/** - * Return a new, zenoh-allocated, empty configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -void z_config_new(struct z_owned_config_t *this_); - -/** - * Constructs a null safe-to-drop value of 'z_owned_config_t' type - */ -ZENOHC_API void z_config_null(struct z_owned_config_t *this_); - -/** - * Constructs a default, zenoh-allocated, peer mode configuration. - */ -ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); - -/** - * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. - * - * This numerical id will be used on the network to save bandwidth and - * ease the retrieval of the concerned resource in the routing tables. - */ -ZENOHC_API -ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr); - -/** - * Declares a publisher for the given key expression. - * - * Data can be put and deleted with this publisher with the help of the - * :c:func:`z_publisher_put` and :c:func:`z_publisher_delete` functions. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression to publish. - * options: additional options for the publisher. - * - * Returns: - * A :c:type:`z_owned_publisherr_t`. - * - * To check if the publisher decalration succeeded and if the publisher is still valid, - * you may use `z_publisher_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a publisher passing `NULL` for the options: - * - * .. code-block:: C - * - * z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(expr), NULL); - * - * is equivalent to initializing and passing the default publisher options: - * - * .. code-block:: C - * - * z_publisher_options_t opts = z_publisher_options_default(); - * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); - */ -ZENOHC_API -ZCError z_declare_publisher(struct z_session_t session, - struct z_keyexpr_t key_expr, - const struct z_publisher_options_t *options, - struct z_owned_publisher_t *this_); - -/** - * Creates a Queryable for the given key expression. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression the Queryable will reply to. - * callback: The callback function that will be called each time a matching query is received. - * options: Options for the queryable. - * - * Returns: - * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. - */ -ZENOHC_API -ZCError z_declare_queryable(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_query_t *callback, - const struct z_queryable_options_t *options, - struct z_owned_queryable_t *this_); - -/** - * Declare a subscriber for a given key expression. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression to subscribe. - * callback: The callback function that will be called each time a data matching the subscribed expression is received. - * opts: The options to be passed to describe the options to be passed to the subscriber declaration. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the subscriber is still valid, - * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing `NULL` for the options: - * - * .. code-block:: C - * - * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct z_subscriber_options_t options); - -/** - * Delete data. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression to delete. - * options: The put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -ZCError z_delete(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_delete_options_t opts); - -/** - * Constructs the default value for :c:type:`z_put_options_t`. - */ -ZENOHC_API struct z_delete_options_t z_delete_options_default(void); - -/** - * Returns ``true`` if `encoding` is valid. - */ -ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); - -/** - * Constructs a default :c:type:`z_encoding_t`. - */ -ZENOHC_API struct z_encoding_t z_encoding_default(void); - -/** - * Frees `encoding`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); - -/** - * Constructs a specific :c:type:`z_encoding_t`. - */ -ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); - -/** - * Returns a :c:type:`z_encoding_t` loaned from `encoding`. - */ -ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); - -/** - * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type - */ -ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); - -/** - * Query data from the matching queryables in the system. - * Replies are provided through a callback function. - * - * Returns a negative value upon failure. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression matching resources to query. - * parameters: The query's parameters, similar to a url's query segment. - * callback: The callback function that will be called on reception of replies for this query. - * Note that the `reply` parameter of the callback is passed by mutable reference, - * but **will** be dropped once your callback exits to help you avoid memory leaks. - * If you'd rather take ownership, please refer to the documentation of :c:func:`z_reply_null` - * options: additional options for the get. - */ -ZENOHC_API -ZCError z_get(struct z_session_t session, - struct z_keyexpr_t key_expr, - const char *parameters, - struct z_owned_closure_reply_t *callback, - struct z_get_options_t options); - -ZENOHC_API struct z_get_options_t z_get_options_default(void); - -/** - * Returns ``true`` if `hello` is valid. - */ -ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *hello); - -/** - * Frees `hello`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); - -/** - * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. - */ -ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); - -/** - * Constructs a gravestone value for hello, useful to steal one from a callback - */ -ZENOHC_API struct z_owned_hello_t z_hello_null(void); - -/** - * Fetches the Zenoh IDs of all connected peers. - * - * `callback` will be called once for each ID, is guaranteed to never be called concurrently, - * and is guaranteed to be dropped before this function exits. - * - * Retuns 0 on success, negative values on failure - */ -ZENOHC_API -ZCError z_info_peers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); - -/** - * Fetches the Zenoh IDs of all connected routers. - * - * `callback` will be called once for each ID, is guaranteed to never be called concurrently, - * and is guaranteed to be dropped before this function exits. - * - * Retuns 0 on success, negative values on failure. - */ -ZENOHC_API -ZCError z_info_routers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); - -/** - * Returns the local Zenoh ID. - * - * Unless the `session` is invalid, that ID is guaranteed to be non-zero. - * In other words, this function returning an array of 16 zeros means you failed - * to pass it a valid session. - */ -ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API ZCError z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); - -/** - * Returns the key expression's internal string by aliasing it. - * - * Currently exclusive to zenoh-c - */ -ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. - * 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 -ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, - char *name); - -/** - * Canonizes the passed string in place, possibly shortening it by modifying `len`. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -ZCError z_keyexpr_canonize(char *start, - size_t *len); - -/** - * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -ZCError z_keyexpr_canonize_null_terminated(char *start); - -/** - * Returns ``true`` if `keyexpr` is valid. - */ -ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); - -/** - * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - * - * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. - * - * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, - * as this would extremely likely cause bugs. - */ -ZENOHC_API -ZCError z_keyexpr_concat(struct z_keyexpr_t left, - const char *right_start, - size_t right_len, - struct z_owned_keyexpr_t *this_); - -/** - * Frees `keyexpr` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); - -/** - * Returns ``0`` if both ``left`` and ``right`` are equal. - */ -ZENOHC_API bool z_keyexpr_equals(struct z_keyexpr_t left, struct z_keyexpr_t right); - -/** - * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set - * defined by ``right``. - */ -ZENOHC_API -bool z_keyexpr_includes(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the - * sets defined by ``left`` and ``right``. - */ -ZENOHC_API -bool z_keyexpr_intersects(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if the passed string is a valid (and canon) key expression. - * Otherwise returns error value - */ -ZENOHC_API ZCError z_keyexpr_is_canon(const char *start, size_t len); - -/** - * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - */ -ZENOHC_API -ZCError z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right, - struct z_owned_keyexpr_t *this_); - -/** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. - */ -ZENOHC_API ZCError z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. - */ -ZENOHC_API -ZCError z_keyexpr_new_autocanonize(const char *name, - struct z_owned_keyexpr_t *this_); - -/** - * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type - */ -ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); - -/** - * Returns the relation between `left` and `right` from `left`'s point of view. - * - * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. - */ -ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. - * The user is responsible of droping the returned string using `z_drop` - */ -ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: - * - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. - * - any instance of `**` may only be lead or followed by `/`. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, - const char *name); - -ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); - -ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); - -ZENOHC_API ZCError z_mutex_init(struct z_owned_mutex_t *this_); - -ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); - -ZENOHC_API ZCError z_mutex_lock(struct z_mutex_t this_); - -ZENOHC_API ZCError z_mutex_try_lock(struct z_mutex_t this_); - -ZENOHC_API ZCError z_mutex_unlock(struct z_mutex_t this_); - -/** - * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. - * Config value is always consumed upon function return. - */ -ZENOHC_API -ZCError z_open(struct z_owned_session_t *this_, - struct z_owned_config_t *config); - -/** - * Returns ``true`` if `pub` is valid. - */ -ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); - -/** - * Sends a `DELETE` message onto the publisher's key expression. - * - * Returns: - * ``0`` in case of success, ``1`` in case of failure. - */ -ZENOHC_API -ZCError z_publisher_delete(struct z_publisher_t publisher, - struct z_publisher_delete_options_t _options); - -/** - * Constructs the default values for the delete operation via a publisher entity. - * - * Returns: - * Returns the constructed :c:type:`z_publisher_delete_options_t`. - */ -ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); - -/** - * Returns the key expression of the publisher - */ -ZENOHC_API struct z_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); - -/** - * Returns a :c:type:`z_publisher_t` loaned from `p`. - */ -ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); - -/** - * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type - */ -ZENOHC_API void z_publisher_null(struct z_owned_publisher_t *this_); - -/** - * Constructs the default value for :c:type:`z_publisher_options_t`. - */ -ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); - -/** - * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload and all owned options fields are consumed upon function return. - * - * Parameters: - * session: The zenoh session. - * payload: The value to put. - * options: The publisher put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -ZCError z_publisher_put(struct z_publisher_t publisher, - struct z_owned_bytes_t *payload, - struct z_publisher_put_options_t options); - -/** - * Constructs the default value for :c:type:`z_publisher_put_options_t`. - */ -ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); - -/** - * Put data, transfering its ownership. - * - * - * The payload's encoding and attachment can be sepcified through the options. These values are consumed upon function - * return. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression to put. - * payload: The value to put (consumed upon function return). - * options: The put options. - * Returns: - * ``0`` in case of success, negative error values in case of failure. - */ -ZENOHC_API -ZCError z_put(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_bytes_t *payload, - struct z_put_options_t options); - -/** - * Constructs the default value for :c:type:`z_put_options_t`. - */ -ZENOHC_API struct z_put_options_t z_put_options_default(void); - -/** - * Gets the attachment to the query by aliasing. - * - * Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. - */ -ZENOHC_API struct z_bytes_t z_query_attachment(struct z_query_t query); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -bool z_query_channel_closure_call(const struct z_owned_query_channel_closure_t *closure, - struct z_owned_query_t *query); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_query_channel_closure_drop(struct z_owned_query_channel_closure_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type - */ -ZENOHC_API struct z_owned_query_channel_closure_t z_query_channel_closure_null(void); - -ZENOHC_API void z_query_channel_drop(struct z_owned_query_channel_t *channel); - -/** - * Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type - */ -ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); - -/** - * Returns `false` if `this` is in a gravestone state, `true` otherwise. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -bool z_query_check(const struct z_owned_query_t *query); - -/** - * Clones the query, allowing to keep it in an "open" state past the callback's return. - * - * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). - */ -ZENOHC_API -void z_query_clone(struct z_owned_query_t *this_, - struct z_query_t query); - -/** - * Automatic query consolidation strategy selection. - * - * A query consolidation strategy will automatically be selected depending the query selector. - * If the selector contains time range properties, no consolidation is performed. - * Otherwise the :c:func:`z_query_consolidation_latest` strategy is used. - * - * Returns: - * Returns the constructed :c:type:`z_query_consolidation_t`. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_auto(void); - -/** - * Creates a default :c:type:`z_query_consolidation_t` (consolidation mode AUTO). - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_default(void); - -/** - * Latest value consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_latest(void); - -/** - * Monotonic consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_monotonic(void); - -/** - * Disable consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); - -/** - * Destroys the query, setting `this` to its gravestone value to prevent double-frees. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -void z_query_drop(struct z_owned_query_t *this_); - -/** - * Get a query's key by aliasing it. - */ -ZENOHC_API struct z_keyexpr_t z_query_keyexpr(struct z_query_t query); - -/** - * Aliases the query. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -struct z_query_t z_query_loan(const struct z_owned_query_t *this_); - -/** - * The gravestone value of `z_owned_query_t`. - */ -ZENOHC_API void z_query_null(struct z_owned_query_t *this_); - -/** - * Get a query's `value selector `_ by aliasing it. - */ -ZENOHC_API -struct z_slice_t z_query_parameters(struct z_query_t query); - -/** - * Send a reply to a query. - * - * This function must be called inside of a Queryable callback passing the - * query received as parameters of the callback function. This function can - * be called multiple times to send multiple replies to a query. The reply - * will be considered complete when the Queryable callback returns. - * - * Parameters: - * query: The query to reply to. - * key_expr: The key of this reply. - * payload: The value of this reply. - * options: The options of this reply. - * - * The payload and all owned options fields are consumed upon function return. - */ -ZENOHC_API -ZCError z_query_reply(struct z_query_t query, - struct z_keyexpr_t key_expr, - struct z_owned_bytes_t *payload, - struct z_query_reply_options_t options); - -/** - * Constructs the default value for :c:type:`z_query_reply_options_t`. - */ -ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); - -/** - * Create a default :c:type:`z_query_target_t`. - */ -ZENOHC_API enum z_query_target_t z_query_target_default(void); - -/** - * Gets a query's `payload value `_ by aliasing it. - * - * **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** - * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. - */ -ZENOHC_API -struct z_value_t z_query_value(struct z_query_t query); - -/** - * Returns ``true`` if `qable` is valid. - */ -ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); - -/** - * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type - */ -ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); - -/** - * Constructs the default value for :c:type:`z_query_reply_options_t`. - */ -ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); - -ZENOHC_API void z_random_fill(void *buf, size_t len); - -ZENOHC_API uint16_t z_random_u16(void); - -ZENOHC_API uint32_t z_random_u32(void); - -ZENOHC_API uint64_t z_random_u64(void); - -ZENOHC_API uint8_t z_random_u8(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -bool z_reply_channel_closure_call(const struct z_owned_reply_channel_closure_t *closure, - struct z_owned_reply_t *reply); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_reply_channel_closure_drop(struct z_owned_reply_channel_closure_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type - */ -ZENOHC_API struct z_owned_reply_channel_closure_t z_reply_channel_closure_null(void); - -ZENOHC_API void z_reply_channel_drop(struct z_owned_reply_channel_t *channel); - -/** - * Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type - */ -ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); - -/** - * Returns ``true`` if `reply` is valid. - */ -ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); - -ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, struct z_reply_t reply); - -/** - * Frees `reply`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); - -/** - * Yields the contents of the reply by asserting it indicates a failure. - * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. - */ -ZENOHC_API -struct z_value_t z_reply_err(struct z_reply_t reply); - -/** - * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. - * - * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. - */ -ZENOHC_API -bool z_reply_is_ok(struct z_reply_t reply); - -/** - * Returns an invalidated :c:type:`z_owned_reply_t`. - * - * This is useful when you wish to take ownership of a value from a callback to :c:func:`z_get`: - * - * - copy the value of the callback's argument's pointee, - * - overwrite the pointee with this function's return value, - * - you are now responsible for dropping your copy of the reply. - */ -ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); - -/** - * Yields the contents of the reply by asserting it indicates a success. - * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. - */ -ZENOHC_API -struct z_sample_t z_reply_ok(struct z_reply_t reply); - -/** - * Gets sample's attachment. - * - * Before calling this function, ensure that `zc_sample_has_attachment` returns true - */ -ZENOHC_API struct z_bytes_t z_sample_attachment(struct z_sample_t sample); - -/** - * The encoding of the payload. - */ -ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); - -/** - * The qos with which the sample was received. - * TODO: split to methods (priority, congestion_control, express) - * Checks if sample contains an attachment. - */ -ZENOHC_API bool z_sample_has_attachment(struct z_sample_t sample); - -/** - * The Key Expression of the sample. - * - * `sample` is aliased by its return value. - */ -ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); - -/** - * The sample's kind (put or delete). - */ -ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); - -/** - * The sample's data, the return value aliases the sample. - * - */ -ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); - -/** - * The samples timestamp - * - * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. - */ -ZENOHC_API -bool z_sample_timestamp(const struct z_sample_t *sample, - struct z_timestamp_t *timestamp_out); - -/** - * Scout for routers and/or peers. - * - * Parameters: - * what: A whatami bitmask of zenoh entities kind to scout for. - * config: A set of properties to configure the scouting. - * timeout: The time (in milliseconds) that should be spent scouting. - * - * Returns 0 if successful, negative values upon failure. - */ -ZENOHC_API -ZCError z_scout(struct z_owned_scouting_config_t *config, - struct z_owned_closure_hello_t *callback); - -ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); - -ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); - -ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); - -ZENOHC_API -void z_scouting_config_from(struct z_config_t config, - struct z_owned_scouting_config_t *this_); - -ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); - -/** - * Returns ``true`` if `session` is valid. - */ -ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); - -/** - * Returns a :c:type:`z_session_t` loaned from `s`. - * - * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. - * - * # Safety - * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, - * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) - * have been destroyed is UB (likely SEGFAULT) - */ -ZENOHC_API -struct z_session_t z_session_loan(const struct z_owned_session_t *s); - -/** - * Constructs a null safe-to-drop value of 'z_owned_session_t' type - */ -ZENOHC_API void z_session_null(struct z_owned_session_t *s); - -ZENOHC_API int8_t z_sleep_ms(size_t time); - -ZENOHC_API int8_t z_sleep_s(size_t time); - -ZENOHC_API int8_t z_sleep_us(size_t time); - -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); - -ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); - -/** - * Returns the gravestone value for `z_slice_t` - */ -ZENOHC_API struct z_slice_t z_slice_empty(void); - -/** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_slice_empty()` - */ -ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); - -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *b); - -ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); - -/** - * Returns `true` if the map is not in its gravestone state - */ -ZENOHC_API bool z_slice_map_check(const struct z_owned_slice_map_t *map); - -/** - * Destroys the map, resetting `this` to its gravestone value. - * - * This function is double-free safe, passing a pointer to the gravestone value will have no effect. - */ -ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); - -/** - * Returns the value associated with `key`, returning a gravestone value if: - * - `key` is in gravestone state. - */ -ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z_slice_t key); - -/** - * Associates `value` to `key` in the map, aliasing them. - * - * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. - * - * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. - */ -ZENOHC_API -ZCError z_slice_map_insert_by_alias(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); - -/** - * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. - * - * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. - */ -ZENOHC_API -ZCError z_slice_map_insert_by_copy(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); - -/** - * Returns true if the map is empty, false otherwise. - */ -ZENOHC_API bool z_slice_map_is_empty(struct z_slice_map_t this_); - -ZENOHC_API -void z_slice_map_iterate(const struct z_slice_map_t *this_, - z_slice_map_iter_body_t body, - void *context); - -/** - * Returns number of key-value pairs in the map. - */ -ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); - -/** - * Constructs a new empty map. - */ -ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); - -/** - * Constructs the gravestone value for `z_owned_slice_map_t` - */ -ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); - -/** - * Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_slice_empty()` - */ -ZENOHC_API -struct z_slice_t z_slice_new(const char *str); - -/** - * Returns the gravestone value for `z_owned_slice_t` - */ -ZENOHC_API struct z_owned_slice_t z_slice_null(void); - -/** - * Constructs a `len` bytes long view starting at `start`. - */ -ZENOHC_API struct z_slice_t z_slice_wrap(const uint8_t *start, size_t len); - -/** - * Returns ``true`` if `strs` is valid. - */ -ZENOHC_API bool z_str_array_check(const struct z_owned_str_array_t *strs); - -/** - * Frees `strs` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); - -/** - * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. - */ -ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); - -/** - * Returns ``true`` if `s` is a valid string - */ -ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); - -/** - * Frees `z_owned_str_t`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_str_drop(struct z_owned_str_t *s); - -/** - * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. - */ -ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); - -/** - * Returns undefined `z_owned_str_t` - */ -ZENOHC_API struct z_owned_str_t z_str_null(void); - -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber); - -/** - * Returns the key expression of the subscriber. - */ -ZENOHC_API struct z_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); - -/** - * Returns a :c:type:`z_subscriber_t` loaned from `this`. - */ -ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *this_); - -/** - * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type - */ -ZENOHC_API void z_subscriber_null(struct z_owned_subscriber_t *this_); - -/** - * Constructs the default value for :c:type:`z_subscriber_options_t`. - */ -ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); - -ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); - -/** - * Detaches the task and releases all allocated resources. - */ -ZENOHC_API void z_task_detach(struct z_owned_task_t *this_); - -ZENOHC_API -ZCError z_task_init(struct z_owned_task_t *this_, - const struct z_task_attr_t *_attr, - void (*fun)(void *arg), - void *arg); - -/** - * Joins the task and releases all allocated resources - */ -ZENOHC_API ZCError z_task_join(struct z_owned_task_t *this_); - -ZENOHC_API void z_task_null(struct z_owned_task_t *this_); - -ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); - -ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); - -ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); - -ZENOHC_API struct z_time_t z_time_now(void); - -ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); - -ZENOHC_API struct z_id_t z_timestamp_get_id(const struct z_timestamp_t *timestamp); - -ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); - -/** - * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. - * The keyxpr is consumed. - */ -ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); - -/** - * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); - -/** - * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. - * - * Parameters: - * qable: The :c:type:`z_owned_queryable_t` to undeclare. - */ -ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); - -/** - * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -ZCError z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); - -/** - * 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. - */ -ZENOHC_API -ZCError zc_config_from_file(const char *path, - struct z_owned_config_t *this_); - -/** - * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. - * - * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). - */ -ZENOHC_API -ZCError zc_config_from_str(const char *s, - struct z_owned_config_t *this_); - -/** - * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. - * Use `z_drop` to safely deallocate this string - */ -ZENOHC_API -struct z_owned_str_t zc_config_get(struct z_config_t config, - const char *key); - -/** - * Inserts a JSON-serialized `value` at the `key` position of the configuration. - * - * Returns 0 if successful, a negative value otherwise. - */ -ZENOHC_API -int8_t zc_config_insert_json(struct z_config_t config, - const char *key, - const char *value); - -/** - * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. - */ -ZENOHC_API -struct z_owned_str_t zc_config_to_string(struct z_config_t config); - -/** - * Initialises the zenoh runtime logger. - * - * Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, - * this will be performed automatically by `z_open` and `z_scout`. - */ -ZENOHC_API void zc_init_logger(void); - -/** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. - */ -ZENOHC_API -ZCError zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, - const char *name, - size_t len); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. - * 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 -ZCError zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, - char *name, - size_t *len); - -/** - * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. - * - any instance of ``**`` may only be lead or followed by ``/``. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, - const char *start, - size_t len); - -ZENOHC_API -struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_default(void); - -/** - * Declares a subscriber on liveliness tokens that intersect `key`. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t key_expr: The key expression to subscribe. - * z_owned_closure_sample_t callback: The callback function that will be called each time a - * liveliness token status changed. - * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the subscriber is still valid, - * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct zc_liveliness_declare_subscriber_options_t _options); - -/** - * Constructs and declares a liveliness token on the network. - * - * Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity - * is achieved, and a DELETE sample if it's lost. - * - * Passing `NULL` as options is valid and equivalent to a pointer to the default options. - */ -ZENOHC_API -ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct zc_liveliness_declaration_options_t _options); - -/** - * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. - * - * Note that the same "value stealing" tricks apply as with a normal :c:func:`z_get` - * - * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. - */ -ZENOHC_API -ZCError zc_liveliness_get(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_reply_t *callback, - struct zc_liveliness_get_options_t options); - -/** - * The gravestone value for `zc_liveliness_get_options_t` - */ -ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); - -ZENOHC_API -struct zc_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_default(void); - -/** - * Returns `true` unless the token is at its gravestone value. - */ -ZENOHC_API bool zc_liveliness_token_check(const struct zc_owned_liveliness_token_t *this_); - -/** - * The gravestone value for liveliness tokens. - */ -ZENOHC_API void zc_liveliness_token_null(struct zc_owned_liveliness_token_t *this_); - -/** - * Destroys a liveliness token, notifying subscribers of its destruction. - */ -ZENOHC_API ZCError zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); - -/** - * Creates a new blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, - * which it will then return; or until the `send` closure is dropped and all queries have been consumed, - * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); - -/** - * Creates a new non-blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, - * which it will then return; or until the `send` closure is dropped and all queries have been consumed, - * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); - -/** - * Creates a new blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, - * which it will then return; or until the `send` closure is dropped and all replies have been consumed, - * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); - -/** - * Creates a new non-blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, - * which it will then return; or until the `send` closure is dropped and all replies have been consumed, - * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); - -/** - * Returns `true` if `sample` is valid. - * - * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed - * unless the value has been dropped already. - */ -ZENOHC_API -bool zc_sample_check(const struct zc_owned_sample_t *sample); - -/** - * Clone a sample in the cheapest way available. - */ -ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); - -/** - * Destroy the sample. - */ -ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); - -/** - * Borrow the sample, allowing calling its accessor methods. - * - * Calling this function using a dropped sample is undefined behaviour. - */ -ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); - -ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); - -/** - * Increments the session's reference count, returning a new owning handle. - */ -ZENOHC_API -int8_t zc_session_rcinc(struct z_owned_session_t *dst, - const struct z_owned_session_t *src); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void zcu_closure_matching_status_call(const struct zcu_owned_closure_matching_status_t *closure, - const struct zcu_matching_status_t *sample); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API -void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t *closure); - -/** - * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type - */ -ZENOHC_API struct zcu_owned_closure_matching_status_t zcu_closure_matching_status_null(void); - -ZENOHC_API enum zcu_locality_t zcu_locality_default(void); - -/** - * Register callback for notifying subscribers matching. - */ -ZENOHC_API -ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, - struct zcu_owned_closure_matching_status_t *callback, - struct zcu_owned_matching_listener_t *this_); - -ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); - -/** - * Declares a Publication Cache. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t key_expr: The key expression to publish. - * ze_publication_cache_options_t options: Additional options for the publication_cache. - * - * Returns: - * :c:type:`ze_owned_publication_cache_t`. - * - * - * Example: - * Declaring a publication cache `NULL` for the options: - * - * .. code-block:: C - * - * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), NULL); - * - * is equivalent to initializing and passing the default publication cache options: - * - * .. code-block:: C - * - * ze_publication_cache_options_t opts = ze_publication_cache_options_default(); - * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); - */ -ZENOHC_API -ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct ze_publication_cache_options_t options); - -/** - * Declares a Querying Subscriber for a given key expression. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to subscribe. - * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. - * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. - * - * Returns: - * :c:type:`ze_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the querying subscriber is still valid, - * you may use `ze_querying_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing ``NULL`` for the options: - * - * .. code-block:: C - * - * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -ZCError ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct ze_querying_subscriber_options_t options); - -/** - * Returns ``true`` if `pub_cache` is valid. - */ -ZENOHC_API bool ze_publication_cache_check(const struct ze_owned_publication_cache_t *this_); - -/** - * Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type - */ -ZENOHC_API void ze_publication_cache_null(struct ze_owned_publication_cache_t *this_); - -/** - * Constructs the default value for :c:type:`ze_publication_cache_options_t`. - */ -ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); - -/** - * Returns ``true`` if `this` is valid. - */ -ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subscriber_t *this_); - -/** - * Make a :c:type:`ze_owned_querying_subscriber_t` to perform an additional query on a specified selector. - * The queried samples will be merged with the received publications and made available in the subscriber callback. - */ -ZENOHC_API -ZCError ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, - struct z_keyexpr_t selector, - const struct z_get_options_t *options); - -/** - * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. - */ -ZENOHC_API -struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); - -/** - * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type - */ -ZENOHC_API void ze_querying_subscriber_null(struct ze_owned_querying_subscriber_t *this_); - -/** - * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. - */ -ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); - -/** - * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -ZCError ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); - -/** - * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -ZCError ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 9ef5cb4e1..08906c0be 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -15,3 +15,2393 @@ #define ALIGN(n) #define ZENOHC_API #endif +/** + * The kind of congestion control. + * + * - **BLOCK** + * - **DROP** + */ +typedef enum z_congestion_control_t { + Z_CONGESTION_CONTROL_BLOCK, + Z_CONGESTION_CONTROL_DROP, +} z_congestion_control_t; +/** + * Consolidation mode values. + * + * - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector + * If the selector contains time range properties, consolidation mode `NONE` is used. + * Otherwise the `LATEST` consolidation mode is used. + * - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. + * - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time + * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple + * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp + * ts2 > ts1. It optimizes latency. + * - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. + * It optimizes bandwidth. + */ +typedef enum z_consolidation_mode_t { + Z_CONSOLIDATION_MODE_AUTO = -1, + Z_CONSOLIDATION_MODE_NONE = 0, + Z_CONSOLIDATION_MODE_MONOTONIC = 1, + Z_CONSOLIDATION_MODE_LATEST = 2, +} z_consolidation_mode_t; +/** + * A :c:type:`z_keyexpr_intersection_level_t`. + * + * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** + */ +typedef enum z_keyexpr_intersection_level_t { + Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT = 0, + Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS = 1, + Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, + Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, +} z_keyexpr_intersection_level_t; +/** + * The priority of zenoh messages. + * + * - **REAL_TIME** + * - **INTERACTIVE_HIGH** + * - **INTERACTIVE_LOW** + * - **DATA_HIGH** + * - **DATA** + * - **DATA_LOW** + * - **BACKGROUND** + */ +typedef enum z_priority_t { + Z_PRIORITY_REAL_TIME = 1, + Z_PRIORITY_INTERACTIVE_HIGH = 2, + Z_PRIORITY_INTERACTIVE_LOW = 3, + Z_PRIORITY_DATA_HIGH = 4, + Z_PRIORITY_DATA = 5, + Z_PRIORITY_DATA_LOW = 6, + Z_PRIORITY_BACKGROUND = 7, +} z_priority_t; +/** + * The Queryables that should be target of a :c:func:`z_get`. + * + * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. + * - **ALL_COMPLETE**: All complete queryables. + * - **ALL**: All matching queryables. + */ +typedef enum z_query_target_t { + Z_QUERY_TARGET_BEST_MATCHING, + Z_QUERY_TARGET_ALL, + Z_QUERY_TARGET_ALL_COMPLETE, +} z_query_target_t; +/** + * The subscription reliability. + * + * - **Z_RELIABILITY_BEST_EFFORT** + * - **Z_RELIABILITY_RELIABLE** + */ +typedef enum z_reliability_t { + Z_RELIABILITY_BEST_EFFORT, + Z_RELIABILITY_RELIABLE, +} z_reliability_t; +typedef enum z_sample_kind_t { + Z_SAMPLE_KIND_PUT = 0, + Z_SAMPLE_KIND_DELETE = 1, +} z_sample_kind_t; +typedef enum zcu_locality_t { + ZCU_LOCALITY_ANY = 0, + ZCU_LOCALITY_SESSION_LOCAL = 1, + ZCU_LOCALITY_REMOTE = 2, +} zcu_locality_t; +typedef enum zcu_reply_keyexpr_t { + ZCU_REPLY_KEYEXPR_ANY = 0, + ZCU_REPLY_KEYEXPR_MATCHING_QUERY = 1, +} zcu_reply_keyexpr_t; +/** + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + */ +typedef struct ALIGN(8) z_owned_bytes_t { + uint8_t _0[40]; +} z_owned_bytes_t; +typedef int8_t ZCError; +/** + * A loaned payload. + */ +typedef struct ALIGN(8) z_bytes_t { + uint8_t _0[8]; +} z_bytes_t; +typedef struct z_owned_slice_t { + uint8_t *start; + size_t len; +} z_owned_slice_t; +/** + * A map of maybe-owned vector of bytes to maybe-owned vector of bytes. + * + * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher + */ +typedef struct ALIGN(8) z_owned_slice_map_t { + uint8_t _0[48]; +} z_owned_slice_map_t; +/** + * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` + * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with + * `z_check` and `z_str_check` correspondently + */ +typedef struct z_owned_str_t { + char *_cstr; +} z_owned_str_t; +/** + * A contiguous view of bytes owned by some other entity. + * + * `start` being `null` is considered a gravestone value, + * and empty slices are represented using a possibly dangling pointer for `start`. + */ +typedef struct z_slice_t { + const uint8_t *start; + size_t len; +} z_slice_t; +typedef struct ALIGN(8) z_slice_map_t { + uint8_t _0[8]; +} z_slice_map_t; +/** + * A reader for payload data. + */ +typedef struct ALIGN(8) z_owned_bytes_t_reader_t { + uint8_t _0[24]; +} z_owned_bytes_t_reader_t; +typedef struct ALIGN(8) z_bytes_reader_t { + uint8_t _0[8]; +} z_bytes_reader_t; +/** + * Clock + * Uses monotonic clock + */ +typedef struct z_clock_t { + uint64_t t; + const void *t_base; +} z_clock_t; +/** + * Represents a Zenoh ID. + * + * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. + */ +typedef struct ALIGN(1) z_id_t { + uint8_t _0[16]; +} z_id_t; +/** + * An owned array of owned, zenoh allocated, NULL terminated strings. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct z_owned_str_array_t { + char **val; + size_t len; +} z_owned_str_array_t; +/** + * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. + * + * Members: + * unsigned int whatami: The kind of zenoh entity. + * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). + * z_owned_str_array_t locators: The locators of the scouted entity. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct z_owned_hello_t { + unsigned int _whatami; + struct z_id_t _pid; + struct z_owned_str_array_t _locators; +} z_owned_hello_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_hello_t { + void *context; + void (*call)(struct z_owned_hello_t*, void*); + void (*drop)(void*); +} z_owned_closure_hello_t; +/** + * + * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. + * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. + */ +typedef struct ALIGN(8) z_owned_query_t { + uint8_t _0[16]; +} z_owned_query_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_owned_query_t { + void *context; + void (*call)(struct z_owned_query_t*, void *context); + void (*drop)(void*); +} z_owned_closure_owned_query_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_query_t { + void *context; + void (*call)(struct z_query_t, void *context); + void (*drop)(void*); +} z_owned_closure_query_t; +typedef struct ALIGN(8) z_reply_t { + uint8_t _0[8]; +} z_reply_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_reply_t { + void *context; + void (*call)(struct z_reply_t, void*); + void (*drop)(void*); +} z_owned_closure_reply_t; +typedef struct ALIGN(8) z_sample_t { + uint8_t _0[8]; +} z_sample_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_sample_t { + void *context; + void (*call)(struct z_sample_t, void *context); + void (*drop)(void*); +} z_owned_closure_sample_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_zid_t { + void *context; + void (*call)(const struct z_id_t*, void*); + void (*drop)(void*); +} z_owned_closure_zid_t; +typedef struct ALIGN(8) z_owned_condvar_t { + uint8_t _0[24]; +} z_owned_condvar_t; +typedef struct ALIGN(8) z_condvar_t { + uint8_t _0[8]; +} z_condvar_t; +typedef struct ALIGN(8) z_mutex_t { + uint8_t _0[8]; +} z_mutex_t; +/** + * An owned zenoh configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_config_t { + uint8_t _0[8]; +} z_owned_config_t; +/** + * A loaned zenoh configuration. + */ +typedef struct ALIGN(8) z_config_t { + uint8_t _0[8]; +} z_config_t; +/** + * A zenoh-allocated key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` + * for wire and computation efficiency. + * + * A `key expression `_ can be either: + * - A plain string expression. + * - A pure numerical id. + * - The combination of a numerical prefix and a string suffix. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_keyexpr_t { + uint8_t _0[32]; +} z_owned_keyexpr_t; +/** + * A loaned key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, + * both for local processing and network-wise. + */ +typedef struct ALIGN(8) z_keyexpr_t { + uint8_t _0[8]; +} z_keyexpr_t; +/** + * Options passed to the :c:func:`z_declare_publisher` function. + * + * Members: + * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. + * z_priority_t priority: The priority of messages from this publisher. + */ +typedef struct z_publisher_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_publisher_options_t; +/** + * An owned zenoh publisher. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_publisher_t { + uint8_t _0[56]; +} z_owned_publisher_t; +/** + * Options passed to the :c:func:`z_declare_queryable` function. + * + * Members: + * bool complete: The completeness of the Queryable. + */ +typedef struct z_queryable_options_t { + bool complete; +} z_queryable_options_t; +/** + * Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. + * + * Members: + * z_reliability_t reliability: The subscription reliability. + */ +typedef struct z_subscriber_options_t { + enum z_reliability_t reliability; +} z_subscriber_options_t; +/** + * Options passed to the :c:func:`z_delete` function. + */ +typedef struct z_delete_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_delete_options_t; +typedef struct ALIGN(8) z_owned_encoding_t { + uint8_t _0[48]; +} z_owned_encoding_t; +/** + * The encoding of a payload, in a MIME-like format. + * + * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + */ +typedef struct ALIGN(8) z_encoding_t { + uint8_t _0[8]; +} z_encoding_t; +/** + * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. + */ +typedef struct z_query_consolidation_t { + enum z_consolidation_mode_t mode; +} z_query_consolidation_t; +/** + * Options passed to the :c:func:`z_get` function. + * + * Members: + * z_query_target_t target: The Queryables that should be target of the query. + * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. + * z_value_t value: An optional value to attach to the query. + * z_bytes_t attachment: The attachment to attach to the query. + * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. + */ +typedef struct z_get_options_t { + enum z_query_target_t target; + struct z_query_consolidation_t consolidation; + struct z_owned_bytes_t *payload; + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; + uint64_t timeout_ms; +} z_get_options_t; +/** + * An borrowed array of borrowed, zenoh allocated, NULL terminated strings. + */ +typedef struct z_str_array_t { + size_t len; + const char *const *val; +} z_str_array_t; +/** + * A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. + * + * Members: + * unsigned int whatami: The kind of zenoh entity. + * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). + * z_owned_str_array_t locators: The locators of the scouted entity. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct z_hello_t { + unsigned int whatami; + struct z_id_t pid; + struct z_str_array_t locators; +} z_hello_t; +typedef struct ALIGN(8) z_owned_mutex_t { + uint8_t _0[32]; +} z_owned_mutex_t; +typedef struct ALIGN(8) z_publisher_t { + uint8_t _0[8]; +} z_publisher_t; +/** + * Represents the set of options that can be applied to the delete operation by a previously declared publisher, + * whenever issued via :c:func:`z_publisher_delete`. + */ +typedef struct z_publisher_delete_options_t { + uint8_t __dummy; +} z_publisher_delete_options_t; +/** + * Options passed to the :c:func:`z_publisher_put` function. + * + * Members: + * z_owned_encoding_t encoding: The encoding of the payload. + * z_owned_bytes_t attachment: The attachment to attach to the publication. + */ +typedef struct z_publisher_put_options_t { + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; +} z_publisher_put_options_t; +/** + * Options passed to the :c:func:`z_put` function. + * + * Members: + * z_encoding_t encoding: The encoding of the payload. + * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. + * z_priority_t priority: The priority of this message. + * z_bytes_t attachment: The attachment to this message. + */ +typedef struct z_put_options_t { + struct z_owned_encoding_t *encoding; + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; + struct z_owned_bytes_t *attachment; +} z_put_options_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * - `this` is a pointer to an arbitrary state. + * - `call` is the typical callback function. `this` will be passed as its last argument. + * - `drop` allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * We guarantee that: + * - `call` will never be called once `drop` has started. + * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_query_channel_closure_t { + void *context; + bool (*call)(struct z_owned_query_t*, void*); + void (*drop)(void*); +} z_owned_query_channel_closure_t; +/** + * A pair of closures + */ +typedef struct z_owned_query_channel_t { + struct z_owned_closure_query_t send; + struct z_owned_query_channel_closure_t recv; +} z_owned_query_channel_t; +/** + * Represents the set of options that can be applied to a query reply, + * sent via :c:func:`z_query_reply`. + * + * Members: + * z_owned_encoding_t encoding: The encoding of the payload. + * z_owned_bytes_t attachment: The attachment to this reply. + */ +typedef struct z_query_reply_options_t { + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; +} z_query_reply_options_t; +typedef struct ALIGN(8) z_value_t { + uint8_t _0[8]; +} z_value_t; +/** + * An owned reply to a :c:func:`z_get`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_reply_t { + uint8_t _0[256]; +} z_owned_reply_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * - `this` is a pointer to an arbitrary state. + * - `call` is the typical callback function. `this` will be passed as its last argument. + * - `drop` allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * We guarantee that: + * - `call` will never be called once `drop` has started. + * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_reply_channel_closure_t { + void *context; + bool (*call)(struct z_owned_reply_t*, void*); + void (*drop)(void*); +} z_owned_reply_channel_closure_t; +/** + * A pair of closures, the `send` one accepting + */ +typedef struct z_owned_reply_channel_t { + struct z_owned_closure_reply_t send; + struct z_owned_reply_channel_closure_t recv; +} z_owned_reply_channel_t; +typedef struct ALIGN(8) z_timestamp_t { + uint8_t _0[24]; +} z_timestamp_t; +typedef struct z_owned_scouting_config_t { + struct z_owned_config_t _config; + unsigned long zc_timeout_ms; + uint8_t zc_what; +} z_owned_scouting_config_t; +/** + * The body of a loop over a z_slice_map's key-value pairs. + * + * `key` and `value` are loaned to the body for the duration of a single call. + * `context` is passed transparently through the iteration driver. + * + * Returning `true` is treated as `continue`. + */ +typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); +typedef struct ALIGN(8) z_subscriber_t { + uint8_t _0[8]; +} z_subscriber_t; +typedef struct ALIGN(8) z_owned_task_t { + uint8_t _0[24]; +} z_owned_task_t; +typedef struct z_task_attr_t { + size_t _0; +} z_task_attr_t; +/** + * Time + * Uses system clock + */ +typedef struct z_time_t { + uint64_t t; +} z_time_t; +/** + * The options for `zc_liveliness_declare_token` + */ +typedef struct zc_liveliness_declaration_options_t { + uint8_t _dummy; +} zc_liveliness_declaration_options_t; +/** + * The options for :c:func:`zc_liveliness_declare_subscriber` + */ +typedef struct zc_liveliness_declare_subscriber_options_t { + uint8_t _dummy; +} zc_liveliness_declare_subscriber_options_t; +/** + * A liveliness token that can be used to provide the network with information about connectivity to its + * declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key + * expressions. + * + * A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. + */ +typedef struct ALIGN(8) zc_owned_liveliness_token_t { + uint8_t _0[32]; +} zc_owned_liveliness_token_t; +/** + * The options for :c:func:`zc_liveliness_declare_subscriber` + */ +typedef struct zc_liveliness_get_options_t { + uint32_t timeout_ms; +} zc_liveliness_get_options_t; +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[240]; +} zc_owned_sample_t; +/** + * A struct that indicates if there exist Subscribers matching the Publisher's key expression. + * + * Members: + * bool matching: true if there exist Subscribers matching the Publisher's key expression. + */ +typedef struct zcu_matching_status_t { + bool matching; +} zcu_matching_status_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct zcu_owned_closure_matching_status_t { + void *context; + void (*call)(const struct zcu_matching_status_t*, void*); + void (*drop)(void*); +} zcu_owned_closure_matching_status_t; +/** + * An owned zenoh matching listener. Destroying the matching listener cancels the subscription. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) zcu_owned_matching_listener_t { + uint8_t _0[40]; +} zcu_owned_matching_listener_t; +/** + * An owned zenoh publication_cache. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_publication_cache_t { + uint8_t _0[96]; +} ze_owned_publication_cache_t; +/** + * Options passed to the :c:func:`ze_declare_publication_cache` function. + * + * Members: + * z_keyexpr_t queryable_prefix: The prefix used for queryable + * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this + * publication cache + * bool queryable_complete: the `complete` option for the queryable + * size_t history: The the history size + * size_t resources_limit: The limit number of cached resources + */ +typedef struct ze_publication_cache_options_t { + const struct z_keyexpr_t *queryable_prefix; + enum zcu_locality_t queryable_origin; + bool queryable_complete; + size_t history; + size_t resources_limit; +} ze_publication_cache_options_t; +/** + * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. + * + * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_querying_subscriber_t { + uint8_t _0[64]; +} ze_owned_querying_subscriber_t; +/** + * Represents the set of options that can be applied to a querying subscriber, + * upon its declaration via :c:func:`ze_declare_querying_subscriber`. + * + * Members: + * z_reliability_t reliability: The subscription reliability. + * zcu_locality_t allowed_origin: The restriction for the matching publications that will be + * receive by this subscriber. + * z_keyexpr_t query_selector: The selector to be used for queries. + * z_query_target_t query_target: The target to be used for queries. + * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. + * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. + * uint64_t query_timeout_ms: The timeout to be used for queries. + */ +typedef struct ze_querying_subscriber_options_t { + enum z_reliability_t reliability; + enum zcu_locality_t allowed_origin; + const struct z_keyexpr_t *query_selector; + enum z_query_target_t query_target; + struct z_query_consolidation_t query_consolidation; + enum zcu_reply_keyexpr_t query_accept_replies; + uint64_t query_timeout_ms; +} ze_querying_subscriber_options_t; +typedef struct ALIGN(8) ze_querying_subscriber_t { + uint8_t _0[8]; +} ze_querying_subscriber_t; +ZENOHC_API extern const unsigned int Z_ROUTER; +ZENOHC_API extern const unsigned int Z_PEER; +ZENOHC_API extern const unsigned int Z_CLIENT; +ZENOHC_API extern const char *Z_CONFIG_MODE_KEY; +ZENOHC_API extern const char *Z_CONFIG_CONNECT_KEY; +ZENOHC_API extern const char *Z_CONFIG_LISTEN_KEY; +ZENOHC_API extern const char *Z_CONFIG_USER_KEY; +ZENOHC_API extern const char *Z_CONFIG_PASSWORD_KEY; +ZENOHC_API extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; +ZENOHC_API extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; +ZENOHC_API extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; +ZENOHC_API extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; +ZENOHC_API extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; +ZENOHC_API extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; +/** + * Returns `true` if the payload is in a valid state. + */ +ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); +/** + * Increments the payload's reference count, returning an owned version of it. + */ +ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_bytes_t *dst); +/** + * Decodes payload into owned bytes + */ +ZENOHC_API ZCError z_bytes_decode_into_bytes(struct z_bytes_t payload, struct z_owned_slice_t *dst); +/** + * Decodes payload into bytes map. + */ +ZENOHC_API +ZCError z_bytes_decode_into_bytes_map(struct z_bytes_t payload, + struct z_owned_slice_map_t *dst); +/** + * Decodes payload into null-terminated string. + */ +ZENOHC_API ZCError z_bytes_decode_into_string(struct z_bytes_t payload, struct z_owned_str_t *dst); +/** + * Decrements the payload's reference counter, destroying it if applicable. + * + * `this` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ +ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); +/** + * Encodes byte sequence by aliasing. + */ +ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, struct z_slice_t bytes); +/** + * Encodes bytes map by copying. + */ +ZENOHC_API +void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, + struct z_slice_map_t bytes_map); +/** + * Encodes a null-terminated string by aliasing. + */ +ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const char *cstr); +/** + * Returns total number bytes in the payload. + */ +ZENOHC_API size_t z_bytes_len(struct z_bytes_t payload); +/** + * Loans the payload, allowing you to call functions that only need a loan of it. + */ +ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); +/** + * The gravestone value for `z_owned_bytes_t`. + */ +ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); +ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_t_reader_t *this_); +ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_t_reader_t *this_); +ZENOHC_API +struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_t_reader_t *reader); +/** + * Creates a reader for the specified `payload`. + * + * Returns 0 in case of success, -1 if `payload` is not valid. + */ +ZENOHC_API +void z_bytes_reader_new(struct z_bytes_t payload, + struct z_owned_bytes_t_reader_t *this_); +ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_t_reader_t *this_); +/** + * Reads data into specified destination. + * + * Will read at most `len` bytes. + * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. + */ +ZENOHC_API +size_t z_bytes_reader_read(struct z_bytes_reader_t this_, + uint8_t *dest, + size_t len); +/** + * Sets the `reader` position indicator for the payload to the value pointed to by offset. + * The new position is exactly offset bytes measured from the beginning of the payload if origin is SEEK_SET, + * from the current reader position if origin is SEEK_CUR, and from the end of the payload if origin is SEEK_END. + * Return ​0​ upon success, negative error code otherwise. + */ +ZENOHC_API +ZCError z_bytes_reader_seek(struct z_bytes_reader_t this_, + int64_t offset, + int origin); +/** + * Returns the read position indicator. + * Returns read position indicator on success or -1L if failure occurs. + */ +ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t this_); +ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); +ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); +ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); +ZENOHC_API struct z_clock_t z_clock_now(void); +/** + * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * + * Returns a negative value if an error occured while closing the session. + * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + */ +ZENOHC_API int8_t z_close(struct z_owned_session_t *session); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_hello_call(const struct z_owned_closure_hello_t *closure, + struct z_owned_hello_t *hello); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_hello_drop(struct z_owned_closure_hello_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type + */ +ZENOHC_API struct z_owned_closure_hello_t z_closure_hello_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_owned_query_call(const struct z_owned_closure_owned_query_t *closure, + struct z_owned_query_t *query); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_owned_query_drop(struct z_owned_closure_owned_query_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type + */ +ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_query_call(const struct z_owned_closure_query_t *closure, + struct z_query_t query); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_query_drop(struct z_owned_closure_query_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type + */ +ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, + struct z_reply_t reply); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_reply_drop(struct z_owned_closure_reply_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type + */ +ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, + struct z_sample_t sample); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_sample_drop(struct z_owned_closure_sample_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type + */ +ZENOHC_API struct z_owned_closure_sample_t z_closure_sample_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_zid_call(const struct z_owned_closure_zid_t *closure, + const struct z_id_t *sample); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type + */ +ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); +ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); +ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); +ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); +ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); +ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); +ZENOHC_API ZCError z_condvar_signal(struct z_condvar_t this_); +ZENOHC_API ZCError z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); +/** + * Returns ``true`` if `config` is valid. + */ +ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); +/** + * Constructs a default, zenoh-allocated, client mode configuration. + * If `peer` is not null, it is added to the configuration as remote peer. + */ +ZENOHC_API +ZCError z_config_client(const char *const *peers, + size_t n_peers, + struct z_owned_config_t *this_); +/** + * Clones the config. + */ +ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); +/** + * Return a new, zenoh-allocated, empty configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +void z_config_new(struct z_owned_config_t *this_); +/** + * Constructs a null safe-to-drop value of 'z_owned_config_t' type + */ +ZENOHC_API void z_config_null(struct z_owned_config_t *this_); +/** + * Constructs a default, zenoh-allocated, peer mode configuration. + */ +ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); +/** + * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. + * + * This numerical id will be used on the network to save bandwidth and + * ease the retrieval of the concerned resource in the routing tables. + */ +ZENOHC_API +ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr); +/** + * Declares a publisher for the given key expression. + * + * Data can be put and deleted with this publisher with the help of the + * :c:func:`z_publisher_put` and :c:func:`z_publisher_delete` functions. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to publish. + * options: additional options for the publisher. + * + * Returns: + * A :c:type:`z_owned_publisherr_t`. + * + * To check if the publisher decalration succeeded and if the publisher is still valid, + * you may use `z_publisher_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a publisher passing `NULL` for the options: + * + * .. code-block:: C + * + * z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(expr), NULL); + * + * is equivalent to initializing and passing the default publisher options: + * + * .. code-block:: C + * + * z_publisher_options_t opts = z_publisher_options_default(); + * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); + */ +ZENOHC_API +ZCError z_declare_publisher(struct z_session_t session, + struct z_keyexpr_t key_expr, + const struct z_publisher_options_t *options, + struct z_owned_publisher_t *this_); +/** + * Creates a Queryable for the given key expression. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression the Queryable will reply to. + * callback: The callback function that will be called each time a matching query is received. + * options: Options for the queryable. + * + * Returns: + * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. + */ +ZENOHC_API +ZCError z_declare_queryable(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_query_t *callback, + const struct z_queryable_options_t *options, + struct z_owned_queryable_t *this_); +/** + * Declare a subscriber for a given key expression. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to subscribe. + * callback: The callback function that will be called each time a data matching the subscribed expression is received. + * opts: The options to be passed to describe the options to be passed to the subscriber declaration. + * + * Returns: + * A :c:type:`z_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the subscriber is still valid, + * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a subscriber passing `NULL` for the options: + * + * .. code-block:: C + * + * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); + * + * is equivalent to initializing and passing the default subscriber options: + * + * .. code-block:: C + * + * z_subscriber_options_t opts = z_subscriber_options_default(); + * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); + */ +ZENOHC_API +ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct z_subscriber_options_t options); +/** + * Delete data. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to delete. + * options: The put options. + * Returns: + * ``0`` in case of success, negative values in case of failure. + */ +ZENOHC_API +ZCError z_delete(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_delete_options_t opts); +/** + * Constructs the default value for :c:type:`z_put_options_t`. + */ +ZENOHC_API struct z_delete_options_t z_delete_options_default(void); +/** + * Returns ``true`` if `encoding` is valid. + */ +ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); +/** + * Constructs a default :c:type:`z_encoding_t`. + */ +ZENOHC_API struct z_encoding_t z_encoding_default(void); +/** + * Frees `encoding`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); +/** + * Constructs a specific :c:type:`z_encoding_t`. + */ +ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); +/** + * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + */ +ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); +/** + * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type + */ +ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); +/** + * Query data from the matching queryables in the system. + * Replies are provided through a callback function. + * + * Returns a negative value upon failure. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression matching resources to query. + * parameters: The query's parameters, similar to a url's query segment. + * callback: The callback function that will be called on reception of replies for this query. + * Note that the `reply` parameter of the callback is passed by mutable reference, + * but **will** be dropped once your callback exits to help you avoid memory leaks. + * If you'd rather take ownership, please refer to the documentation of :c:func:`z_reply_null` + * options: additional options for the get. + */ +ZENOHC_API +ZCError z_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + const char *parameters, + struct z_owned_closure_reply_t *callback, + struct z_get_options_t options); +ZENOHC_API struct z_get_options_t z_get_options_default(void); +/** + * Returns ``true`` if `hello` is valid. + */ +ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *hello); +/** + * Frees `hello`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); +/** + * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. + */ +ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); +/** + * Constructs a gravestone value for hello, useful to steal one from a callback + */ +ZENOHC_API struct z_owned_hello_t z_hello_null(void); +/** + * Fetches the Zenoh IDs of all connected peers. + * + * `callback` will be called once for each ID, is guaranteed to never be called concurrently, + * and is guaranteed to be dropped before this function exits. + * + * Retuns 0 on success, negative values on failure + */ +ZENOHC_API +ZCError z_info_peers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); +/** + * Fetches the Zenoh IDs of all connected routers. + * + * `callback` will be called once for each ID, is guaranteed to never be called concurrently, + * and is guaranteed to be dropped before this function exits. + * + * Retuns 0 on success, negative values on failure. + */ +ZENOHC_API +ZCError z_info_routers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); +/** + * Returns the local Zenoh ID. + * + * Unless the `session` is invalid, that ID is guaranteed to be non-zero. + * In other words, this function returning an array of 16 zeros means you failed + * to pass it a valid session. + */ +ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API ZCError z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); +/** + * Returns the key expression's internal string by aliasing it. + * + * Currently exclusive to zenoh-c + */ +ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * 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 +ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, + char *name); +/** + * Canonizes the passed string in place, possibly shortening it by modifying `len`. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_canonize(char *start, + size_t *len); +/** + * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_canonize_null_terminated(char *start); +/** + * Returns ``true`` if `keyexpr` is valid. + */ +ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); +/** + * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + * + * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. + * + * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, + * as this would extremely likely cause bugs. + */ +ZENOHC_API +ZCError z_keyexpr_concat(struct z_keyexpr_t left, + const char *right_start, + size_t right_len, + struct z_owned_keyexpr_t *this_); +/** + * Frees `keyexpr` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); +/** + * Returns ``0`` if both ``left`` and ``right`` are equal. + */ +ZENOHC_API bool z_keyexpr_equals(struct z_keyexpr_t left, struct z_keyexpr_t right); +/** + * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set + * defined by ``right``. + */ +ZENOHC_API +bool z_keyexpr_includes(struct z_keyexpr_t left, + struct z_keyexpr_t right); +/** + * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the + * sets defined by ``left`` and ``right``. + */ +ZENOHC_API +bool z_keyexpr_intersects(struct z_keyexpr_t left, + struct z_keyexpr_t right); +/** + * Returns ``0`` if the passed string is a valid (and canon) key expression. + * Otherwise returns error value + */ +ZENOHC_API ZCError z_keyexpr_is_canon(const char *start, size_t len); +/** + * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + */ +ZENOHC_API +ZCError z_keyexpr_join(struct z_keyexpr_t left, + struct z_keyexpr_t right, + struct z_owned_keyexpr_t *this_); +/** + * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + */ +ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. + */ +ZENOHC_API ZCError z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. + */ +ZENOHC_API +ZCError z_keyexpr_new_autocanonize(const char *name, + struct z_owned_keyexpr_t *this_); +/** + * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type + */ +ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); +/** + * Returns the relation between `left` and `right` from `left`'s point of view. + * + * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. + */ +ZENOHC_API +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, + struct z_keyexpr_t right); +/** + * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. + * The user is responsible of droping the returned string using `z_drop` + */ +ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * + * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. + * - any instance of `**` may only be lead or followed by `/`. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, + const char *name); +ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); +ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); +ZENOHC_API ZCError z_mutex_init(struct z_owned_mutex_t *this_); +ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); +ZENOHC_API ZCError z_mutex_lock(struct z_mutex_t this_); +ZENOHC_API ZCError z_mutex_try_lock(struct z_mutex_t this_); +ZENOHC_API ZCError z_mutex_unlock(struct z_mutex_t this_); +/** + * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + * Config value is always consumed upon function return. + */ +ZENOHC_API +ZCError z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); +/** + * Returns ``true`` if `pub` is valid. + */ +ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); +/** + * Sends a `DELETE` message onto the publisher's key expression. + * + * Returns: + * ``0`` in case of success, ``1`` in case of failure. + */ +ZENOHC_API +ZCError z_publisher_delete(struct z_publisher_t publisher, + struct z_publisher_delete_options_t _options); +/** + * Constructs the default values for the delete operation via a publisher entity. + * + * Returns: + * Returns the constructed :c:type:`z_publisher_delete_options_t`. + */ +ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); +/** + * Returns the key expression of the publisher + */ +ZENOHC_API struct z_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); +/** + * Returns a :c:type:`z_publisher_t` loaned from `p`. + */ +ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); +/** + * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type + */ +ZENOHC_API void z_publisher_null(struct z_owned_publisher_t *this_); +/** + * Constructs the default value for :c:type:`z_publisher_options_t`. + */ +ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); +/** + * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` + * + * The payload and all owned options fields are consumed upon function return. + * + * Parameters: + * session: The zenoh session. + * payload: The value to put. + * options: The publisher put options. + * Returns: + * ``0`` in case of success, negative values in case of failure. + */ +ZENOHC_API +ZCError z_publisher_put(struct z_publisher_t publisher, + struct z_owned_bytes_t *payload, + struct z_publisher_put_options_t options); +/** + * Constructs the default value for :c:type:`z_publisher_put_options_t`. + */ +ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); +/** + * Put data, transfering its ownership. + * + * + * The payload's encoding and attachment can be sepcified through the options. These values are consumed upon function + * return. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to put. + * payload: The value to put (consumed upon function return). + * options: The put options. + * Returns: + * ``0`` in case of success, negative error values in case of failure. + */ +ZENOHC_API +ZCError z_put(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_put_options_t options); +/** + * Constructs the default value for :c:type:`z_put_options_t`. + */ +ZENOHC_API struct z_put_options_t z_put_options_default(void); +/** + * Gets the attachment to the query by aliasing. + * + * Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. + */ +ZENOHC_API struct z_bytes_t z_query_attachment(struct z_query_t query); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +bool z_query_channel_closure_call(const struct z_owned_query_channel_closure_t *closure, + struct z_owned_query_t *query); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_query_channel_closure_drop(struct z_owned_query_channel_closure_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type + */ +ZENOHC_API struct z_owned_query_channel_closure_t z_query_channel_closure_null(void); +ZENOHC_API void z_query_channel_drop(struct z_owned_query_channel_t *channel); +/** + * Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type + */ +ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); +/** + * Returns `false` if `this` is in a gravestone state, `true` otherwise. + * + * This function may not be called with the null pointer, but can be called with the gravestone value. + */ +ZENOHC_API +bool z_query_check(const struct z_owned_query_t *query); +/** + * Clones the query, allowing to keep it in an "open" state past the callback's return. + * + * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). + */ +ZENOHC_API +void z_query_clone(struct z_owned_query_t *this_, + struct z_query_t query); +/** + * Automatic query consolidation strategy selection. + * + * A query consolidation strategy will automatically be selected depending the query selector. + * If the selector contains time range properties, no consolidation is performed. + * Otherwise the :c:func:`z_query_consolidation_latest` strategy is used. + * + * Returns: + * Returns the constructed :c:type:`z_query_consolidation_t`. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_auto(void); +/** + * Creates a default :c:type:`z_query_consolidation_t` (consolidation mode AUTO). + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_default(void); +/** + * Latest value consolidation. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_latest(void); +/** + * Monotonic consolidation. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_monotonic(void); +/** + * Disable consolidation. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); +/** + * Destroys the query, setting `this` to its gravestone value to prevent double-frees. + * + * This function may not be called with the null pointer, but can be called with the gravestone value. + */ +ZENOHC_API +void z_query_drop(struct z_owned_query_t *this_); +/** + * Get a query's key by aliasing it. + */ +ZENOHC_API struct z_keyexpr_t z_query_keyexpr(struct z_query_t query); +/** + * Aliases the query. + * + * This function may not be called with the null pointer, but can be called with the gravestone value. + */ +ZENOHC_API +struct z_query_t z_query_loan(const struct z_owned_query_t *this_); +/** + * The gravestone value of `z_owned_query_t`. + */ +ZENOHC_API void z_query_null(struct z_owned_query_t *this_); +/** + * Get a query's `value selector `_ by aliasing it. + */ +ZENOHC_API +struct z_slice_t z_query_parameters(struct z_query_t query); +/** + * Send a reply to a query. + * + * This function must be called inside of a Queryable callback passing the + * query received as parameters of the callback function. This function can + * be called multiple times to send multiple replies to a query. The reply + * will be considered complete when the Queryable callback returns. + * + * Parameters: + * query: The query to reply to. + * key_expr: The key of this reply. + * payload: The value of this reply. + * options: The options of this reply. + * + * The payload and all owned options fields are consumed upon function return. + */ +ZENOHC_API +ZCError z_query_reply(struct z_query_t query, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_query_reply_options_t options); +/** + * Constructs the default value for :c:type:`z_query_reply_options_t`. + */ +ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); +/** + * Create a default :c:type:`z_query_target_t`. + */ +ZENOHC_API enum z_query_target_t z_query_target_default(void); +/** + * Gets a query's `payload value `_ by aliasing it. + * + * **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** + * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. + */ +ZENOHC_API +struct z_value_t z_query_value(struct z_query_t query); +/** + * Returns ``true`` if `qable` is valid. + */ +ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); +/** + * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type + */ +ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); +/** + * Constructs the default value for :c:type:`z_query_reply_options_t`. + */ +ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); +ZENOHC_API void z_random_fill(void *buf, size_t len); +ZENOHC_API uint16_t z_random_u16(void); +ZENOHC_API uint32_t z_random_u32(void); +ZENOHC_API uint64_t z_random_u64(void); +ZENOHC_API uint8_t z_random_u8(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +bool z_reply_channel_closure_call(const struct z_owned_reply_channel_closure_t *closure, + struct z_owned_reply_t *reply); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_reply_channel_closure_drop(struct z_owned_reply_channel_closure_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type + */ +ZENOHC_API struct z_owned_reply_channel_closure_t z_reply_channel_closure_null(void); +ZENOHC_API void z_reply_channel_drop(struct z_owned_reply_channel_t *channel); +/** + * Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type + */ +ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); +/** + * Returns ``true`` if `reply` is valid. + */ +ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); +ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, struct z_reply_t reply); +/** + * Frees `reply`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); +/** + * Yields the contents of the reply by asserting it indicates a failure. + * + * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. + */ +ZENOHC_API +struct z_value_t z_reply_err(struct z_reply_t reply); +/** + * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. + * + * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. + */ +ZENOHC_API +bool z_reply_is_ok(struct z_reply_t reply); +/** + * Returns an invalidated :c:type:`z_owned_reply_t`. + * + * This is useful when you wish to take ownership of a value from a callback to :c:func:`z_get`: + * + * - copy the value of the callback's argument's pointee, + * - overwrite the pointee with this function's return value, + * - you are now responsible for dropping your copy of the reply. + */ +ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); +/** + * Yields the contents of the reply by asserting it indicates a success. + * + * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. + */ +ZENOHC_API +struct z_sample_t z_reply_ok(struct z_reply_t reply); +/** + * Gets sample's attachment. + * + * Before calling this function, ensure that `zc_sample_has_attachment` returns true + */ +ZENOHC_API struct z_bytes_t z_sample_attachment(struct z_sample_t sample); +/** + * The encoding of the payload. + */ +ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); +/** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) + * Checks if sample contains an attachment. + */ +ZENOHC_API bool z_sample_has_attachment(struct z_sample_t sample); +/** + * The Key Expression of the sample. + * + * `sample` is aliased by its return value. + */ +ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); +/** + * The sample's kind (put or delete). + */ +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); +/** + * The sample's data, the return value aliases the sample. + * + */ +ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +/** + * The samples timestamp + * + * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. + */ +ZENOHC_API +bool z_sample_timestamp(const struct z_sample_t *sample, + struct z_timestamp_t *timestamp_out); +/** + * Scout for routers and/or peers. + * + * Parameters: + * what: A whatami bitmask of zenoh entities kind to scout for. + * config: A set of properties to configure the scouting. + * timeout: The time (in milliseconds) that should be spent scouting. + * + * Returns 0 if successful, negative values upon failure. + */ +ZENOHC_API +ZCError z_scout(struct z_owned_scouting_config_t *config, + struct z_owned_closure_hello_t *callback); +ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); +ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); +ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); +ZENOHC_API +void z_scouting_config_from(struct z_config_t config, + struct z_owned_scouting_config_t *this_); +ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); +/** + * Returns ``true`` if `session` is valid. + */ +ZENOHC_API bool z_session_check(const struct z_owned_session_t *this_); +/** + * Returns a :c:type:`z_session_t` loaned from `s`. + * + * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. + * + * # Safety + * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, + * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) + * have been destroyed is UB (likely SEGFAULT) + */ +ZENOHC_API +struct z_session_t z_session_loan(const struct z_owned_session_t *this_); +/** + * Constructs a null safe-to-drop value of 'z_owned_session_t' type + */ +ZENOHC_API void z_session_null(struct z_owned_session_t *this_); +ZENOHC_API int8_t z_sleep_ms(size_t time); +ZENOHC_API int8_t z_sleep_s(size_t time); +ZENOHC_API int8_t z_sleep_us(size_t time); +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); +ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); +/** + * Returns the gravestone value for `z_slice_t` + */ +ZENOHC_API struct z_slice_t z_slice_empty(void); +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_slice_empty()` + */ +ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *b); +ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); +/** + * Returns `true` if the map is not in its gravestone state + */ +ZENOHC_API bool z_slice_map_check(const struct z_owned_slice_map_t *map); +/** + * Destroys the map, resetting `this` to its gravestone value. + * + * This function is double-free safe, passing a pointer to the gravestone value will have no effect. + */ +ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); +/** + * Returns the value associated with `key`, returning a gravestone value if: + * - `key` is in gravestone state. + */ +ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z_slice_t key); +/** + * Associates `value` to `key` in the map, aliasing them. + * + * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. + * + * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + */ +ZENOHC_API +ZCError z_slice_map_insert_by_alias(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); +/** + * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. + * + * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + */ +ZENOHC_API +ZCError z_slice_map_insert_by_copy(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); +/** + * Returns true if the map is empty, false otherwise. + */ +ZENOHC_API bool z_slice_map_is_empty(struct z_slice_map_t this_); +ZENOHC_API +void z_slice_map_iterate(const struct z_slice_map_t *this_, + z_slice_map_iter_body_t body, + void *context); +/** + * Returns number of key-value pairs in the map. + */ +ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); +/** + * Constructs a new empty map. + */ +ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); +/** + * Constructs the gravestone value for `z_owned_slice_map_t` + */ +ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); +/** + * Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_slice_empty()` + */ +ZENOHC_API +struct z_slice_t z_slice_new(const char *str); +/** + * Returns the gravestone value for `z_owned_slice_t` + */ +ZENOHC_API struct z_owned_slice_t z_slice_null(void); +/** + * Constructs a `len` bytes long view starting at `start`. + */ +ZENOHC_API struct z_slice_t z_slice_wrap(const uint8_t *start, size_t len); +/** + * Returns ``true`` if `strs` is valid. + */ +ZENOHC_API bool z_str_array_check(const struct z_owned_str_array_t *strs); +/** + * Frees `strs` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); +/** + * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. + */ +ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); +/** + * Returns ``true`` if `s` is a valid string + */ +ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); +/** + * Frees `z_owned_str_t`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_str_drop(struct z_owned_str_t *s); +/** + * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. + */ +ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); +/** + * Returns undefined `z_owned_str_t` + */ +ZENOHC_API struct z_owned_str_t z_str_null(void); +/** + * Returns ``true`` if `sub` is valid. + */ +ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber); +/** + * Returns the key expression of the subscriber. + */ +ZENOHC_API struct z_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); +/** + * Returns a :c:type:`z_subscriber_t` loaned from `this`. + */ +ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *this_); +/** + * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type + */ +ZENOHC_API void z_subscriber_null(struct z_owned_subscriber_t *this_); +/** + * Constructs the default value for :c:type:`z_subscriber_options_t`. + */ +ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); +ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); +/** + * Detaches the task and releases all allocated resources. + */ +ZENOHC_API void z_task_detach(struct z_owned_task_t *this_); +ZENOHC_API +ZCError z_task_init(struct z_owned_task_t *this_, + const struct z_task_attr_t *_attr, + void (*fun)(void *arg), + void *arg); +/** + * Joins the task and releases all allocated resources + */ +ZENOHC_API ZCError z_task_join(struct z_owned_task_t *this_); +ZENOHC_API void z_task_null(struct z_owned_task_t *this_); +ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); +ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); +ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); +ZENOHC_API struct z_time_t z_time_now(void); +ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); +ZENOHC_API struct z_id_t z_timestamp_get_id(const struct z_timestamp_t *timestamp); +ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); +/** + * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. + * The keyxpr is consumed. + */ +ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); +/** + * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); +/** + * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. + * + * Parameters: + * qable: The :c:type:`z_owned_queryable_t` to undeclare. + */ +ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); +/** + * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); +/** + * 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. + */ +ZENOHC_API +ZCError zc_config_from_file(const char *path, + struct z_owned_config_t *this_); +/** + * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. + * + * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). + */ +ZENOHC_API +ZCError zc_config_from_str(const char *s, + struct z_owned_config_t *this_); +/** + * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. + * Use `z_drop` to safely deallocate this string + */ +ZENOHC_API +struct z_owned_str_t zc_config_get(struct z_config_t config, + const char *key); +/** + * Inserts a JSON-serialized `value` at the `key` position of the configuration. + * + * Returns 0 if successful, a negative value otherwise. + */ +ZENOHC_API +int8_t zc_config_insert_json(struct z_config_t config, + const char *key, + const char *value); +/** + * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. + */ +ZENOHC_API +struct z_owned_str_t zc_config_to_string(struct z_config_t config); +/** + * Initialises the zenoh runtime logger. + * + * Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, + * this will be performed automatically by `z_open` and `z_scout`. + */ +ZENOHC_API void zc_init_logger(void); +/** + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + */ +ZENOHC_API +ZCError zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, + const char *name, + size_t len); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * 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 +ZCError zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, + char *name, + size_t *len); +/** + * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. + * - any instance of ``**`` may only be lead or followed by ``/``. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, + const char *start, + size_t len); +ZENOHC_API +struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_default(void); +/** + * Declares a subscriber on liveliness tokens that intersect `key`. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t key_expr: The key expression to subscribe. + * z_owned_closure_sample_t callback: The callback function that will be called each time a + * liveliness token status changed. + * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. + * + * Returns: + * A :c:type:`z_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the subscriber is still valid, + * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct zc_liveliness_declare_subscriber_options_t _options); +/** + * Constructs and declares a liveliness token on the network. + * + * Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity + * is achieved, and a DELETE sample if it's lost. + * + * Passing `NULL` as options is valid and equivalent to a pointer to the default options. + */ +ZENOHC_API +ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct zc_liveliness_declaration_options_t _options); +/** + * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. + * + * Note that the same "value stealing" tricks apply as with a normal :c:func:`z_get` + * + * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. + */ +ZENOHC_API +ZCError zc_liveliness_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_reply_t *callback, + struct zc_liveliness_get_options_t options); +/** + * The gravestone value for `zc_liveliness_get_options_t` + */ +ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); +ZENOHC_API +struct zc_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_default(void); +/** + * Returns `true` unless the token is at its gravestone value. + */ +ZENOHC_API bool zc_liveliness_token_check(const struct zc_owned_liveliness_token_t *this_); +/** + * The gravestone value for liveliness tokens. + */ +ZENOHC_API void zc_liveliness_token_null(struct zc_owned_liveliness_token_t *this_); +/** + * Destroys a liveliness token, notifying subscribers of its destruction. + */ +ZENOHC_API ZCError zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); +/** + * Creates a new blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, + * which it will then return; or until the `send` closure is dropped and all queries have been consumed, + * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. + */ +ZENOHC_API +struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); +/** + * Creates a new non-blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, + * which it will then return; or until the `send` closure is dropped and all queries have been consumed, + * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. + */ +ZENOHC_API +struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); +/** + * Creates a new blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, + * which it will then return; or until the `send` closure is dropped and all replies have been consumed, + * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. + */ +ZENOHC_API +struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); +/** + * Creates a new non-blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, + * which it will then return; or until the `send` closure is dropped and all replies have been consumed, + * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. + */ +ZENOHC_API +struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); +/** + * Returns `true` if `sample` is valid. + * + * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * unless the value has been dropped already. + */ +ZENOHC_API +bool zc_sample_check(const struct zc_owned_sample_t *sample); +/** + * Clone a sample in the cheapest way available. + */ +ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); +/** + * Destroy the sample. + */ +ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); +/** + * Borrow the sample, allowing calling its accessor methods. + * + * Calling this function using a dropped sample is undefined behaviour. + */ +ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); +ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); +/** + * Increments the session's reference count, returning a new owning handle. + */ +ZENOHC_API +int8_t zc_session_rcinc(struct z_owned_session_t *dst, + const struct z_owned_session_t *src); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void zcu_closure_matching_status_call(const struct zcu_owned_closure_matching_status_t *closure, + const struct zcu_matching_status_t *sample); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API +void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t *closure); +/** + * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type + */ +ZENOHC_API struct zcu_owned_closure_matching_status_t zcu_closure_matching_status_null(void); +ZENOHC_API enum zcu_locality_t zcu_locality_default(void); +/** + * Register callback for notifying subscribers matching. + */ +ZENOHC_API +ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, + struct zcu_owned_closure_matching_status_t *callback, + struct zcu_owned_matching_listener_t *this_); +ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); +/** + * Declares a Publication Cache. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t key_expr: The key expression to publish. + * ze_publication_cache_options_t options: Additional options for the publication_cache. + * + * Returns: + * :c:type:`ze_owned_publication_cache_t`. + * + * + * Example: + * Declaring a publication cache `NULL` for the options: + * + * .. code-block:: C + * + * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), NULL); + * + * is equivalent to initializing and passing the default publication cache options: + * + * .. code-block:: C + * + * ze_publication_cache_options_t opts = ze_publication_cache_options_default(); + * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); + */ +ZENOHC_API +ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct ze_publication_cache_options_t options); +/** + * Declares a Querying Subscriber for a given key expression. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t keyexpr: The key expression to subscribe. + * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. + * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. + * + * Returns: + * :c:type:`ze_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the querying subscriber is still valid, + * you may use `ze_querying_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a subscriber passing ``NULL`` for the options: + * + * .. code-block:: C + * + * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); + * + * is equivalent to initializing and passing the default subscriber options: + * + * .. code-block:: C + * + * z_subscriber_options_t opts = z_subscriber_options_default(); + * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); + */ +ZENOHC_API +ZCError ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct ze_querying_subscriber_options_t options); +/** + * Returns ``true`` if `pub_cache` is valid. + */ +ZENOHC_API bool ze_publication_cache_check(const struct ze_owned_publication_cache_t *this_); +/** + * Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type + */ +ZENOHC_API void ze_publication_cache_null(struct ze_owned_publication_cache_t *this_); +/** + * Constructs the default value for :c:type:`ze_publication_cache_options_t`. + */ +ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); +/** + * Returns ``true`` if `this` is valid. + */ +ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subscriber_t *this_); +/** + * Make a :c:type:`ze_owned_querying_subscriber_t` to perform an additional query on a specified selector. + * The queried samples will be merged with the received publications and made available in the subscriber callback. + */ +ZENOHC_API +ZCError ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, + struct z_keyexpr_t selector, + const struct z_get_options_t *options); +/** + * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. + */ +ZENOHC_API +struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); +/** + * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type + */ +ZENOHC_API void ze_querying_subscriber_null(struct ze_owned_querying_subscriber_t *this_); +/** + * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. + */ +ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); +/** + * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); +/** + * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 9ef5cb4e1..764cf399a 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -15,3 +15,70 @@ #define ALIGN(n) #define ZENOHC_API #endif +#include +#include +#include +#include +#include +#define DEFAULT_SCOUTING_TIMEOUT 1000 +/** + * An owned zenoh session. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_session_t { + uint8_t _0[8]; +} z_owned_session_t; +typedef struct ALIGN(8) z_query_t { + uint8_t _0[8]; +} z_query_t; +typedef struct ALIGN(8) z_session_t { + uint8_t _0[8]; +} z_session_t; +/** + * An owned zenoh queryable. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_queryable_t { + uint8_t _0[32]; +} z_owned_queryable_t; +/** + * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_subscriber_t { + uint8_t _0[32]; +} z_owned_subscriber_t; +#define Z_OK 0 +#define Z_EINVAL -1 +#define Z_EPARSE -2 +#define Z_EIO -3 +#define Z_ENETWORK -4 +#define Z_EBUSY_MUTEX -16 +#define Z_EINVAL_MUTEX -22 +#define Z_EAGAIN_MUTEX -11 +#define Z_EPOISON_MUTEX -22 +#define Z_EGENERIC INT8_MIN diff --git a/src/commons.rs b/src/commons.rs index fb245e40b..9b8b17c86 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -102,7 +102,7 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { let sample = sample.transmute_ref(); - sample.encoding().transmute_copy() + sample.encoding().transmute_handle() } /// The sample's data, the return value aliases the sample. /// @@ -192,7 +192,7 @@ pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { } pub use crate::opaque_types::z_encoding_t; -decl_transmute_copy!(&'static Encoding, z_encoding_t); +decl_transmute_handle!(Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -233,7 +233,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - (&Encoding::ZENOH_BYTES).transmute_copy() + (&Encoding::ZENOH_BYTES).transmute_handle() } /// Frees `encoding`, invalidating it for double-drop safety. @@ -254,14 +254,14 @@ pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> boo #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_encoding_t { - encoding.transmute_ref().transmute_copy() + encoding.transmute_ref().transmute_handle() } pub use crate::opaque_types::z_owned_value_t; decl_transmute_owned!(Value, z_owned_value_t); pub use crate::opaque_types::z_value_t; -decl_transmute_copy!(&'static Value, z_value_t); +decl_transmute_handle!(Value, z_value_t); #[repr(C)] #[derive(Clone, Copy, Debug)] diff --git a/src/get.rs b/src/get.rs index 9a6855559..c6e6f8b42 100644 --- a/src/get.rs +++ b/src/get.rs @@ -72,7 +72,7 @@ pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_err(reply: z_reply_t) -> z_value_t { let reply = reply.transmute_ref(); - reply.result().expect_err("Reply does not contain error").transmute_copy() + reply.result().expect_err("Reply does not contain error").transmute_handle() } /// Returns an invalidated :c:type:`z_owned_reply_t`. @@ -151,7 +151,7 @@ pub unsafe extern "C" fn z_get( } else { CStr::from_ptr(parameters).to_str().unwrap() }; - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let mut get = session.get(key_expr.clone().with_parameters(p)); diff --git a/src/info.rs b/src/info.rs index 6a2558a66..c63fe91c0 100644 --- a/src/info.rs +++ b/src/info.rs @@ -1,4 +1,4 @@ -use crate::transmute::TransmuteCopy; +use crate::transmute::{TransmuteCopy, TransmuteFromHandle}; // // Copyright (c) 2017, 2022 ZettaScale Technology. // @@ -35,7 +35,7 @@ impl From<[u8;16]> for z_id_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { - let session = session.transmute_copy(); + let session = session.transmute_ref(); session.info().zid().res_sync().transmute_copy() } @@ -53,7 +53,7 @@ pub unsafe extern "C" fn z_info_peers_zid( ) -> errors::ZCError { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); - let session = session.transmute_copy(); + let session = session.transmute_ref(); for id in session.info().peers_zid().res_sync() { z_closure_zid_call(&closure, &id.transmute_copy()); } @@ -74,7 +74,7 @@ pub unsafe extern "C" fn z_info_routers_zid( ) -> errors::ZCError { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); - let session = session.transmute_copy(); + let session = session.transmute_ref(); for id in session.info().routers_zid().res_sync() { z_closure_zid_call(&closure, &id.transmute_copy()); } diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 9d4cc194b..0d0c3fbdb 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -390,7 +390,7 @@ pub extern "C" fn z_declare_keyexpr( ) -> ZCError { let this = this.transmute_uninit_ptr(); let key_expr = key_expr.transmute_ref(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); match session.declare_keyexpr(key_expr).res_sync() { Ok(id) => { Inplace::init(this, Some(id.into_owned())); @@ -413,7 +413,7 @@ pub extern "C" fn z_undeclare_keyexpr(session: z_session_t, kexpr: &mut z_owned_ log::debug!("Attempted to undeclare dropped keyexpr"); return i8::MIN; }; - let session = session.transmute_copy(); + let session = session.transmute_ref(); match session.undeclare(kexpr).res() { Ok(()) => errors::Z_OK, Err(e) => { diff --git a/src/liveliness.rs b/src/liveliness.rs index ec50a7798..256002c7c 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -66,7 +66,7 @@ pub extern "C" fn zc_liveliness_declare_token( _options: zc_liveliness_declaration_options_t, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); match session.liveliness().declare_token(key_expr).res() { Ok(token) => { @@ -129,7 +129,7 @@ pub extern "C" fn zc_liveliness_declare_subscriber( _options: zc_liveliness_declare_subscriber_options_t, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_sample_t::empty()); let key_expr = key_expr.transmute_ref(); match session @@ -177,7 +177,7 @@ pub extern "C" fn zc_liveliness_get( callback: &mut z_owned_closure_reply_t, options: zc_liveliness_get_options_t, ) -> errors::ZCError { - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_reply_t::empty()); let liveliness: Liveliness<'static> = session.liveliness(); diff --git a/src/payload.rs b/src/payload.rs index 2dd56c7d9..58db5c147 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -72,9 +72,14 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( let len = z_bytes_len(payload); let cstr = z_owned_str_t::preallocate(len); let payload = payload.transmute_ref(); - payload.reader().read(from_raw_parts_mut(cstr._cstr as *mut u8, len)); - Inplace::init(dst, cstr); - errors::Z_OK + if let Err(e) = payload.reader().read(from_raw_parts_mut(cstr._cstr as *mut u8, len)) { + log::error!("Failed to read the payload: {}", e); + Inplace::empty(dst); + errors::Z_EIO + } else { + Inplace::init(dst, cstr); + errors::Z_OK + } } /// Decodes payload into bytes map. @@ -105,9 +110,14 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes( let len = z_bytes_len(payload); let b = z_owned_slice_t::preallocate(len); let payload = payload.transmute_ref(); - payload.reader().read(from_raw_parts_mut(b.start, len)); - Inplace::init(dst, b); - errors::Z_OK + if let Err(e) = payload.reader().read(from_raw_parts_mut(b.start, len)) { + log::error!("Failed to read the payload: {}", e); + Inplace::empty(dst); + errors::Z_EIO + } else { + Inplace::init(dst, b); + errors::Z_OK + } } unsafe impl Send for z_slice_t {} @@ -194,9 +204,8 @@ pub unsafe extern "C" fn z_bytes_reader_null(this: *mut MaybeUninit bool { - let reader = reader.transmute_ref(); - reader.as_ref().is_some() +pub unsafe extern "C" fn z_bytes_reader_check(this: &z_owned_bytes_t_reader_t) -> bool { + this.transmute_ref().is_some() } #[no_mangle] @@ -219,11 +228,11 @@ extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_t_reader_t) -> #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_read( - reader: z_bytes_reader_t, + this: z_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { - let reader = reader.transmute_mut(); + let reader = this.transmute_mut(); let buf = unsafe { from_raw_parts_mut(dest, len) }; reader.read(buf).unwrap_or(0) } @@ -234,8 +243,8 @@ pub unsafe extern "C" fn z_bytes_reader_read( /// Return ​0​ upon success, negative error code otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_seek(reader: z_bytes_reader_t, offset: i64, origin: libc::c_int) -> ZCError { - let reader = reader.transmute_mut(); +pub unsafe extern "C" fn z_bytes_reader_seek(this: z_bytes_reader_t, offset: i64, origin: libc::c_int) -> ZCError { + let reader = this.transmute_mut(); let pos = match origin { libc::SEEK_SET => offset.try_into().map(|r| SeekFrom::Start(r)), libc::SEEK_CUR => Ok(SeekFrom::Current(offset)), @@ -252,8 +261,8 @@ pub unsafe extern "C" fn z_bytes_reader_seek(reader: z_bytes_reader_t, offset: i /// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_tell(reader: z_bytes_reader_t) -> i64 { - let reader = reader.transmute_mut(); +pub unsafe extern "C" fn z_bytes_reader_tell(this: z_bytes_reader_t) -> i64 { + let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } diff --git a/src/publication_cache.rs b/src/publication_cache.rs index dadc91cc3..0868b5ce1 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -91,7 +91,7 @@ pub extern "C" fn ze_declare_publication_cache( options: ze_publication_cache_options_t, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let mut p = session.declare_publication_cache(key_expr); p = p.history(options.history); diff --git a/src/publisher.rs b/src/publisher.rs index 2ebf4c410..274b5a52c 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -67,7 +67,7 @@ pub extern "C" fn z_publisher_options_default() -> z_publisher_options_t { pub use crate::opaque_types::z_owned_publisher_t; decl_transmute_owned!(Option>, z_owned_publisher_t); pub use crate::opaque_types::z_publisher_t; -decl_transmute_copy!(&'static Publisher<'static>, z_publisher_t); +decl_transmute_handle!(Publisher<'static>, z_publisher_t); /// Declares a publisher for the given key expression. /// @@ -111,7 +111,7 @@ pub extern "C" fn z_declare_publisher( this: *mut MaybeUninit, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref().clone().into_owned(); let mut p = session.declare_publisher(key_expr); if let Some(options) = options { @@ -152,7 +152,7 @@ pub extern "C" fn z_publisher_check(pbl: &'static z_owned_publisher_t) -> bool { pub extern "C" fn z_publisher_loan(p: &'static z_owned_publisher_t) -> z_publisher_t { let p = p.transmute_ref(); let p = unwrap_ref_unchecked(p); - p.transmute_copy() + p.transmute_handle() } /// Options passed to the :c:func:`z_publisher_put` function. @@ -197,7 +197,7 @@ pub unsafe extern "C" fn z_publisher_put( payload: &mut z_owned_bytes_t, options: z_publisher_put_options_t, ) -> errors::ZCError { - let publisher = publisher.transmute_copy(); + let publisher = publisher.transmute_ref(); let payload = match payload.transmute_mut().extract() { Some(p) => p, None => { @@ -251,8 +251,7 @@ pub extern "C" fn z_publisher_delete( publisher: z_publisher_t, _options: z_publisher_delete_options_t, ) -> errors::ZCError { - let publisher = publisher.transmute_copy(); - + let publisher = publisher.transmute_ref(); if let Err(e) = publisher.delete().res_sync() { log::error!("{}", e); errors::Z_EGENERIC @@ -265,7 +264,7 @@ pub extern "C" fn z_publisher_delete( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_keyexpr_t { - let publisher = publisher.transmute_copy(); + let publisher = publisher.transmute_ref(); publisher.key_expr().transmute_handle() } @@ -293,7 +292,7 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); std::mem::swap(callback, &mut closure); - let publisher = publisher.transmute_copy(); + let publisher = publisher.transmute_ref(); let listener = publisher .matching_listener() .callback_mut(move |matching_status| { diff --git a/src/put.rs b/src/put.rs index 5457dd522..d9b3a9165 100644 --- a/src/put.rs +++ b/src/put.rs @@ -82,7 +82,7 @@ pub extern "C" fn z_put( payload: &mut z_owned_bytes_t, options: z_put_options_t, ) -> errors::ZCError { - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let payload = match payload.transmute_mut().extract() { Some(p) => p, @@ -144,7 +144,7 @@ pub extern "C" fn z_delete( key_expr: z_keyexpr_t, opts: z_delete_options_t, ) -> errors::ZCError { - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let del = session.delete(key_expr) diff --git a/src/queryable.rs b/src/queryable.rs index 875918cab..f3f9aa6c5 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -146,7 +146,7 @@ pub extern "C" fn z_declare_queryable( let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut closure, callback); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let keyexpr = key_expr.transmute_ref(); let mut builder = session.declare_queryable(keyexpr); if let Some(options) = options { @@ -275,7 +275,7 @@ pub extern "C" fn z_query_has_attachment(query: z_query_t) -> bool { /// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { - query.transmute_ref().value().expect("Query does not contain a value").transmute_copy() + query.transmute_ref().value().expect("Query does not contain a value").transmute_handle() } /// Gets the attachment to the query by aliasing. diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 4ab406708..ce8bba2f5 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -83,7 +83,7 @@ pub struct ze_querying_subscriber_options_t { #[no_mangle] pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscriber_options_t { ze_querying_subscriber_options_t { - reliability: Reliability::BestEffort.into(), + reliability: Reliability::DEFAULT.into(), allowed_origin: zcu_locality_default(), query_selector: null(), query_target: z_query_target_default(), @@ -136,7 +136,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let mut sub = session.declare_subscriber(key_expr.transmute_ref()).querying(); sub = sub .reliability(options.reliability.into()) diff --git a/src/session.rs b/src/session.rs index 86682da16..fb4903bb4 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh team, // -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr}; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}; use crate::{errors, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; use std::sync::Arc; @@ -25,7 +25,7 @@ decl_transmute_owned!(Option>, z_owned_session_t); /// A loaned zenoh session. use crate::opaque_types::z_session_t; -decl_transmute_copy!(&'static Session, z_session_t); +decl_transmute_handle!(Session, z_session_t); /// Returns a :c:type:`z_session_t` loaned from `s`. /// @@ -36,18 +36,18 @@ decl_transmute_copy!(&'static Session, z_session_t); /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(s: &'static z_owned_session_t) -> z_session_t { - let s = s.transmute_ref(); - let s = unwrap_ref_unchecked(s); - let s = s.as_ref(); - s.transmute_copy() +pub extern "C" fn z_session_loan(this: &'static z_owned_session_t) -> z_session_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + let this = this.as_ref(); + this.transmute_handle() } /// Constructs a null safe-to-drop value of 'z_owned_session_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_session_null(s: *mut MaybeUninit) { - Inplace::empty(s.transmute_uninit_ptr()); +pub extern "C" fn z_session_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } /// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. @@ -86,8 +86,8 @@ pub extern "C" fn z_open( /// Returns ``true`` if `session` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_session_check(session: &z_owned_session_t) -> bool { - session.transmute_ref().is_some() +pub extern "C" fn z_session_check(this: &z_owned_session_t) -> bool { + this.transmute_ref().is_some() } /// Closes a zenoh session. This drops and invalidates `session` for double-drop safety. diff --git a/src/subscriber.rs b/src/subscriber.rs index ceab769cf..f431fdb6c 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -98,7 +98,7 @@ pub struct z_subscriber_options_t { #[no_mangle] pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { z_subscriber_options_t { - reliability: Reliability::BestEffort.into() + reliability: Reliability::DEFAULT.into() } } @@ -145,7 +145,7 @@ pub extern "C" fn z_declare_subscriber( let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let subscriber = session.declare_subscriber(key_expr).callback(move |sample| { From e6497a83ee522ad9a728879bdeb8475c6c6056f9 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 09:39:27 +0200 Subject: [PATCH 050/377] fmt --- src/closures/query_channel.rs | 19 +++++--- src/closures/reply_closure.rs | 10 +---- src/closures/response_channel.rs | 18 +++++--- src/collections.rs | 32 ++++++++----- src/commons.rs | 19 ++++---- src/config.rs | 3 +- src/errors.rs | 2 +- src/get.rs | 40 ++++++++++------- src/info.rs | 6 +-- src/keyexpr.rs | 77 ++++++++++++++++++++------------ src/lib.rs | 2 +- src/liveliness.rs | 25 +++++++---- src/payload.rs | 25 ++++++++--- src/platform/synchronization.rs | 29 +++++++----- src/publication_cache.rs | 13 +++--- src/publisher.rs | 28 +++++------- src/put.rs | 10 ++--- src/queryable.rs | 40 +++++++++++------ src/querying_subscriber.rs | 70 ++++++++++++++++------------- src/scouting.rs | 17 +++++-- src/session.rs | 5 ++- src/subscriber.rs | 23 +++++----- src/transmute.rs | 29 ++++++++---- 23 files changed, 329 insertions(+), 213 deletions(-) diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index 9860e926d..10ba68c0e 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -1,6 +1,12 @@ -use crate::{z_closure_query_drop, z_owned_closure_query_t, z_owned_query_t, z_query_clone, z_query_null, z_query_t}; +use crate::{ + z_closure_query_drop, z_owned_closure_query_t, z_owned_query_t, z_query_clone, z_query_null, + z_query_t, +}; use libc::c_void; -use std::{mem::MaybeUninit, sync::mpsc::{Receiver, TryRecvError}}; +use std::{ + mem::MaybeUninit, + sync::mpsc::{Receiver, TryRecvError}, +}; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// - `this` is a pointer to an arbitrary state. @@ -70,7 +76,6 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver } } - /// Creates a new blocking fifo channel, returned as a pair of closures. /// /// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. @@ -110,8 +115,8 @@ pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { send, - recv: From::from(move |this: *mut MaybeUninit| { - match rx.try_recv() { + recv: From::from( + move |this: *mut MaybeUninit| match rx.try_recv() { Ok(val) => { (*this).write(val); true @@ -124,8 +129,8 @@ pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned z_query_null(this); false } - } - }), + }, + ), } } diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index e7fdc721f..d05b63ab3 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -46,10 +46,7 @@ pub extern "C" fn z_closure_reply_null() -> z_owned_closure_reply_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_reply_call( - closure: &z_owned_closure_reply_t, - reply: z_reply_t, -) { +pub extern "C" fn z_closure_reply_call(closure: &z_owned_closure_reply_t, reply: z_reply_t) { match closure.call { Some(call) => call(reply, closure.context), None => { @@ -66,10 +63,7 @@ pub extern "C" fn z_closure_reply_drop(closure: &mut z_owned_closure_reply_t) { impl From for z_owned_closure_reply_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call( - response: z_reply_t, - this: *mut c_void, - ) { + extern "C" fn call(response: z_reply_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; this(response) } diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 8375a7e5e..e89b509ba 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -1,6 +1,12 @@ -use crate::{ z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t, z_reply_clone, z_reply_null, z_reply_t}; +use crate::{ + z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t, z_reply_clone, z_reply_null, + z_reply_t, +}; use libc::c_void; -use std::{mem::MaybeUninit, sync::mpsc::{Receiver, TryRecvError}}; +use std::{ + mem::MaybeUninit, + sync::mpsc::{Receiver, TryRecvError}, +}; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// - `this` is a pointer to an arbitrary state. /// - `call` is the typical callback function. `this` will be passed as its last argument. @@ -107,8 +113,8 @@ pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { send, - recv: From::from(move |this: *mut MaybeUninit| { - match rx.try_recv() { + recv: From::from( + move |this: *mut MaybeUninit| match rx.try_recv() { Ok(val) => { (*this).write(val); true @@ -121,8 +127,8 @@ pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned z_reply_null(this); false } - } - }), + }, + ), } } diff --git a/src/collections.rs b/src/collections.rs index b75ca2d63..6bf5622b5 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -20,7 +20,9 @@ use libc::{c_char, c_void, size_t}; use zenoh::prelude::ZenohId; use crate::errors; -use crate::transmute::{Inplace, InplaceDefault, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; +use crate::transmute::{ + Inplace, InplaceDefault, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr, +}; /// A contiguous view of bytes owned by some other entity. /// @@ -182,7 +184,7 @@ pub const extern "C" fn z_slice_loan(b: &z_owned_slice_t) -> z_slice_t { } #[no_mangle] -pub extern "C" fn z_slice_clone(b: &z_slice_t, ) -> z_owned_slice_t { +pub extern "C" fn z_slice_clone(b: &z_slice_t) -> z_owned_slice_t { if !z_slice_is_initialized(b) { z_slice_null() } else { @@ -244,7 +246,6 @@ impl From<&[u8]> for z_slice_t { impl InplaceDefault for z_owned_slice_t {} - /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` /// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with /// `z_check` and `z_str_check` correspondently @@ -331,7 +332,10 @@ pub use crate::opaque_types::z_slice_map_t; pub type ZHashMap = HashMap, Cow<'static, [u8]>>; pub use crate::opaque_types::z_config_t; -decl_transmute_handle!(HashMap, Cow<'static, [u8]>>, z_slice_map_t); +decl_transmute_handle!( + HashMap, Cow<'static, [u8]>>, + z_slice_map_t +); pub use crate::opaque_types::z_owned_config_t; decl_transmute_owned!(Option, z_owned_slice_map_t); @@ -390,7 +394,11 @@ pub type z_slice_map_iter_body_t = extern "C" fn(key: z_slice_t, value: z_slice_t, context: *mut c_void) -> bool; #[no_mangle] -pub extern "C" fn z_slice_map_iterate(this: &z_slice_map_t, body: z_slice_map_iter_body_t, context: *mut c_void) { +pub extern "C" fn z_slice_map_iterate( + this: &z_slice_map_t, + body: z_slice_map_iter_body_t, + context: *mut c_void, +) { let this = this.transmute_ref(); for (key, value) in this { if !body(key.as_ref().into(), value.as_ref().into(), context) { @@ -407,8 +415,10 @@ pub extern "C" fn z_slice_map_get(this: z_slice_map_t, key: z_slice_t) -> z_slic return z_slice_empty(); } let m = this.transmute_mut(); - let key = key.as_slice().unwrap(); - m.get(key).map(|s| s.as_ref().into()).unwrap_or( z_slice_empty()) + let key = key.as_slice().unwrap(); + m.get(key) + .map(|s| s.as_ref().into()) + .unwrap_or(z_slice_empty()) } /// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. @@ -421,8 +431,7 @@ pub extern "C" fn z_slice_map_insert_by_copy( value: z_slice_t, ) -> errors::ZCError { let this = this.transmute_mut(); - if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) - { + if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); errors::Z_OK } else { @@ -442,11 +451,10 @@ pub extern "C" fn z_slice_map_insert_by_alias( value: z_slice_t, ) -> errors::ZCError { let this = this.transmute_mut(); - if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) - { + if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { this.insert(Cow::Borrowed(key), Cow::Borrowed(value)); errors::Z_OK } else { errors::Z_EINVAL } -} \ No newline at end of file +} diff --git a/src/commons.rs b/src/commons.rs index 9b8b17c86..8e2b95cff 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -23,8 +23,8 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_id_t; use crate::z_bytes_t; +use crate::z_id_t; use crate::z_keyexpr_t; use libc::{c_char, c_ulong}; use unwrap_infallible::UnwrapInfallible; @@ -83,7 +83,6 @@ pub unsafe extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t timestamp.transmute_copy().get_id().to_le_bytes().into() } - /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. @@ -119,10 +118,13 @@ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { sample.kind().into() } /// The samples timestamp -/// +/// /// Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. #[no_mangle] -pub extern "C" fn z_sample_timestamp(sample: &z_sample_t, timestamp_out: &mut z_timestamp_t) -> bool { +pub extern "C" fn z_sample_timestamp( + sample: &z_sample_t, + timestamp_out: &mut z_timestamp_t, +) -> bool { let sample = sample.transmute_ref(); if let Some(t) = sample.timestamp() { *timestamp_out = t.transmute_copy(); @@ -147,7 +149,10 @@ pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { #[no_mangle] pub extern "C" fn z_sample_attachment(sample: z_sample_t) -> z_bytes_t { let sample = sample.transmute_ref(); - sample.attachment().expect("Sample does not have an attachment").transmute_handle() + sample + .attachment() + .expect("Sample does not have an attachment") + .transmute_handle() } pub use crate::opaque_types::zc_owned_sample_t; @@ -257,7 +262,6 @@ pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_en encoding.transmute_ref().transmute_handle() } - pub use crate::opaque_types::z_owned_value_t; decl_transmute_owned!(Value, z_owned_value_t); pub use crate::opaque_types::z_value_t; @@ -326,7 +330,6 @@ pub extern "C" fn zcu_reply_keyexpr_default() -> zcu_reply_keyexpr_t { ReplyKeyExpr::default().into() } - /// The Queryables that should be target of a :c:func:`z_get`. /// /// - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. @@ -503,4 +506,4 @@ impl From for CongestionControl { z_congestion_control_t::DROP => CongestionControl::Drop, } } -} \ No newline at end of file +} diff --git a/src/config.rs b/src/config.rs index 23ef45a88..f30abd036 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,7 +18,8 @@ use zenoh::config::{Config, ValidatedMap, WhatAmI}; use crate::errors::{ZCError, Z_EPARSE}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, }; use crate::{errors, z_owned_str_t, z_str_null}; diff --git a/src/errors.rs b/src/errors.rs index 298752442..72448026a 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -9,4 +9,4 @@ pub const Z_EBUSY_MUTEX: ZCError = -16; pub const Z_EINVAL_MUTEX: ZCError = -22; pub const Z_EAGAIN_MUTEX: ZCError = -11; pub const Z_EPOISON_MUTEX: ZCError = -22; // same as Z_EINVAL_MUTEX -pub const Z_EGENERIC: ZCError = i8::MIN; \ No newline at end of file +pub const Z_EGENERIC: ZCError = i8::MIN; diff --git a/src/get.rs b/src/get.rs index c6e6f8b42..d72471e1b 100644 --- a/src/get.rs +++ b/src/get.rs @@ -13,13 +13,13 @@ // use libc::c_char; -use zenoh::sample::SampleBuilderTrait; -use zenoh::sample::ValueBuilderTrait; +use std::ffi::CStr; use std::mem::MaybeUninit; use std::ptr::null_mut; -use std::ffi::CStr; +use zenoh::sample::SampleBuilderTrait; +use zenoh::sample::ValueBuilderTrait; -use zenoh::prelude::{ConsolidationMode, QueryTarget, Mode, QueryConsolidation, Reply}; +use zenoh::prelude::{ConsolidationMode, Mode, QueryConsolidation, QueryTarget, Reply}; use crate::errors; use crate::transmute::Inplace; @@ -29,15 +29,12 @@ use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; use crate::z_consolidation_mode_t; +use crate::z_owned_bytes_t; use crate::z_owned_encoding_t; use crate::z_query_target_t; use crate::z_sample_t; -use crate::z_owned_bytes_t; use crate::z_value_t; -use crate::{ - z_closure_reply_call, z_keyexpr_t, - z_owned_closure_reply_t, z_session_t, -}; +use crate::{z_closure_reply_call, z_keyexpr_t, z_owned_closure_reply_t, z_session_t}; use zenoh::prelude::SyncResolve; pub use crate::opaque_types::z_owned_reply_t; @@ -62,7 +59,10 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: z_reply_t) -> bool { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { let reply = reply.transmute_ref(); - reply.result().expect("Reply does not contain a sample").transmute_handle() + reply + .result() + .expect("Reply does not contain a sample") + .transmute_handle() } /// Yields the contents of the reply by asserting it indicates a failure. @@ -72,7 +72,10 @@ pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_err(reply: z_reply_t) -> z_value_t { let reply = reply.transmute_ref(); - reply.result().expect_err("Reply does not contain error").transmute_handle() + reply + .result() + .expect_err("Reply does not contain error") + .transmute_handle() } /// Returns an invalidated :c:type:`z_owned_reply_t`. @@ -89,7 +92,10 @@ pub extern "C" fn z_reply_null(this: *mut MaybeUninit) { #[no_mangle] pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: z_reply_t) { - Inplace::init(this.transmute_uninit_ptr(), Some(reply.transmute_ref().clone())); + Inplace::init( + this.transmute_uninit_ptr(), + Some(reply.transmute_ref().clone()), + ); } /// Options passed to the :c:func:`z_get` function. @@ -169,12 +175,12 @@ pub unsafe extern "C" fn z_get( get = get.attachment(attachment); } - get = get.consolidation(options.consolidation) - .timeout(std::time::Duration::from_millis(options.timeout_ms)) - .target(options.target.into()); + get = get + .consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .target(options.target.into()); match get - .callback(move |response| { - z_closure_reply_call(&closure, response.transmute_handle()) }) + .callback(move |response| z_closure_reply_call(&closure, response.transmute_handle())) .res_sync() { Ok(()) => errors::Z_OK, diff --git a/src/info.rs b/src/info.rs index c63fe91c0..c2604d84a 100644 --- a/src/info.rs +++ b/src/info.rs @@ -12,8 +12,8 @@ use crate::transmute::{TransmuteCopy, TransmuteFromHandle}; // Contributors: // ZettaScale Zenoh team, // -use std::mem::MaybeUninit; use crate::{errors, z_closure_zid_call, z_owned_closure_zid_t, z_session_t}; +use std::mem::MaybeUninit; use zenoh::config::ZenohId; use zenoh::prelude::sync::SyncResolve; use zenoh::session::SessionDeclarations; @@ -21,8 +21,8 @@ use zenoh::session::SessionDeclarations; pub use crate::opaque_types::z_id_t; decl_transmute_copy!(ZenohId, z_id_t); -impl From<[u8;16]> for z_id_t { - fn from(value: [u8;16]) -> Self { +impl From<[u8; 16]> for z_id_t { + fn from(value: [u8; 16]) -> Self { unsafe { std::mem::transmute(value) } } } diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 0d0c3fbdb..e64933366 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -24,15 +24,15 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_slice_t; use crate::z_owned_str_t; use crate::z_session_t; +use crate::z_slice_t; use libc::c_char; +use std::error::Error; use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; -use std::error::Error; pub use crate::opaque_types::z_owned_keyexpr_t; decl_transmute_owned!(Option>, z_owned_keyexpr_t); @@ -44,7 +44,11 @@ pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } -fn keyexpr_create_inner(name: &'static mut str, should_auto_canonize: bool, should_copy: bool) -> Result, Box> { +fn keyexpr_create_inner( + name: &'static mut str, + should_auto_canonize: bool, + should_copy: bool, +) -> Result, Box> { if should_copy { let s = name.to_owned(); match should_auto_canonize { @@ -61,17 +65,17 @@ fn keyexpr_create_inner(name: &'static mut str, should_auto_canonize: bool, shou #[allow(clippy::missing_safety_doc)] #[no_mangle] -unsafe fn keyexpr_create(name: &'static mut [u8], should_auto_canonize: bool, should_copy: bool) -> Result, errors::ZCError> { +unsafe fn keyexpr_create( + name: &'static mut [u8], + should_auto_canonize: bool, + should_copy: bool, +) -> Result, errors::ZCError> { match std::str::from_utf8_mut(name) { - Ok(name) => { - match keyexpr_create_inner(name, should_auto_canonize, should_copy) { - Ok(v) => { - Ok(v) - } - Err(e) => { - log::error!("Couldn't construct a keyexpr: {}", e); - Err(errors::Z_EINVAL) - } + Ok(name) => match keyexpr_create_inner(name, should_auto_canonize, should_copy) { + Ok(v) => Ok(v), + Err(e) => { + log::error!("Couldn't construct a keyexpr: {}", e); + Err(errors::Z_EINVAL) } }, Err(e) => { @@ -80,8 +84,6 @@ unsafe fn keyexpr_create(name: &'static mut [u8], should_auto_canonize: bool, sh } } } - - /// Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. #[allow(clippy::missing_safety_doc)] @@ -99,7 +101,7 @@ pub unsafe extern "C" fn z_keyexpr_new( Ok(ke) => { Inplace::init(this, Some(ke)); errors::Z_OK - }, + } Err(e) => { Inplace::empty(this); e @@ -123,7 +125,7 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize( Ok(ke) => { Inplace::init(this, Some(ke)); errors::Z_OK - }, + } Err(e) => { Inplace::empty(this); e @@ -219,7 +221,7 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) Ok(ke) => { *len = ke.len(); errors::Z_OK - }, + } Err(e) => e, } } @@ -227,19 +229,23 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) /// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_keyexpr_from_slice(this: *mut MaybeUninit, name: *const c_char, len: usize) -> ZCError { +pub unsafe extern "C" fn zc_keyexpr_from_slice( + this: *mut MaybeUninit, + name: *const c_char, + len: usize, +) -> ZCError { let this = this.transmute_uninit_ptr(); if name.is_null() { Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, len); - + match keyexpr_create(name, false, false) { Ok(ke) => { Inplace::init(this, Some(ke)); errors::Z_OK - }, + } Err(e) => { Inplace::empty(this); e @@ -263,13 +269,13 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); - + match keyexpr_create(name, true, false) { Ok(ke) => { *len = ke.len(); Inplace::init(this, Some(ke)); errors::Z_OK - }, + } Err(e) => { Inplace::empty(this); e @@ -281,7 +287,10 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr(this: *mut MaybeUninit, name: *const c_char) -> ZCError { +pub unsafe extern "C" fn z_keyexpr( + this: *mut MaybeUninit, + name: *const c_char, +) -> ZCError { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); return errors::Z_EINVAL; @@ -296,7 +305,10 @@ pub unsafe extern "C" fn z_keyexpr(this: *mut MaybeUninit, na /// 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(this: *mut MaybeUninit, name: *mut c_char) -> ZCError { +pub unsafe extern "C" fn z_keyexpr_autocanonize( + this: *mut MaybeUninit, + name: *mut c_char, +) -> ZCError { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); return errors::Z_EINVAL; @@ -343,7 +355,10 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_unchecked(this: *mut MaybeUninit, name: *const c_char) { +pub unsafe extern "C" fn z_keyexpr_unchecked( + this: *mut MaybeUninit, + name: *const c_char, +) { zc_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) } @@ -364,7 +379,7 @@ pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { let ke = ke.transmute_ref(); z_slice_t { start: ke.as_ptr(), - len: ke.len() + len: ke.len(), } } @@ -465,7 +480,7 @@ pub unsafe extern "C" fn z_keyexpr_concat( left: z_keyexpr_t, right_start: *const c_char, right_len: usize, - this: *mut MaybeUninit + this: *mut MaybeUninit, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); let left = left.transmute_ref(); @@ -500,7 +515,11 @@ pub unsafe extern "C" fn z_keyexpr_concat( #[no_mangle] /// Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. /// In case of error, the return value will be set to its invalidated state. -pub extern "C" fn z_keyexpr_join(left: z_keyexpr_t, right: z_keyexpr_t, this: *mut MaybeUninit) -> errors::ZCError { +pub extern "C" fn z_keyexpr_join( + left: z_keyexpr_t, + right: z_keyexpr_t, + this: *mut MaybeUninit, +) -> errors::ZCError { let left = left.transmute_ref(); let right = right.transmute_ref(); let this = this.transmute_uninit_ptr(); diff --git a/src/lib.rs b/src/lib.rs index 6e6f5843e..ed883ca71 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,8 +59,8 @@ pub use liveliness::*; mod publication_cache; pub use publication_cache::*; mod querying_subscriber; -pub use querying_subscriber::*; pub use platform::*; +pub use querying_subscriber::*; pub mod platform; // #[cfg(feature = "shared-memory")] // mod shm; diff --git a/src/liveliness.rs b/src/liveliness.rs index 256002c7c..7e9342677 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -15,17 +15,24 @@ use std::mem::MaybeUninit; use zenoh::prelude::SyncResolve; use zenoh::{ - liveliness::{Liveliness, LivelinessToken}, prelude::SessionDeclarations + liveliness::{Liveliness, LivelinessToken}, + prelude::SessionDeclarations, }; use crate::transmute::TransmuteIntoHandle; use crate::{ - errors, transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t + errors, + transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, + z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, + z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, }; -use crate::opaque_types::zc_owned_liveliness_token_t; use crate::opaque_types::zc_liveliness_token_t; -decl_transmute_owned!(Option>, zc_owned_liveliness_token_t); +use crate::opaque_types::zc_owned_liveliness_token_t; +decl_transmute_owned!( + Option>, + zc_owned_liveliness_token_t +); decl_transmute_handle!(LivelinessToken<'static>, zc_liveliness_token_t); /// The gravestone value for liveliness tokens. @@ -47,8 +54,8 @@ pub struct zc_liveliness_declaration_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_default( -) -> zc_liveliness_declaration_options_t { +pub extern "C" fn zc_liveliness_declaration_options_default() -> zc_liveliness_declaration_options_t +{ zc_liveliness_declaration_options_t { _dummy: 0 } } @@ -72,7 +79,7 @@ pub extern "C" fn zc_liveliness_declare_token( Ok(token) => { Inplace::init(this, Some(token)); errors::Z_OK - }, + } Err(e) => { log::error!("Failed to undeclare token: {e}"); Inplace::empty(this); @@ -83,7 +90,9 @@ pub extern "C" fn zc_liveliness_declare_token( /// Destroys a liveliness token, notifying subscribers of its destruction. #[no_mangle] -pub extern "C" fn zc_liveliness_undeclare_token(this: &mut zc_owned_liveliness_token_t) -> errors::ZCError { +pub extern "C" fn zc_liveliness_undeclare_token( + this: &mut zc_owned_liveliness_token_t, +) -> errors::ZCError { let this = this.transmute_mut(); if let Some(token) = this.extract().take() { if let Err(e) = token.undeclare().res() { diff --git a/src/payload.rs b/src/payload.rs index 58db5c147..194d66cc8 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,8 +1,11 @@ use crate::errors::{self, ZCError}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, +}; +use crate::{ + z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap, }; -use crate::{z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap}; use core::slice; use std::any::Any; use std::io::{Read, Seek, SeekFrom}; @@ -72,7 +75,10 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( let len = z_bytes_len(payload); let cstr = z_owned_str_t::preallocate(len); let payload = payload.transmute_ref(); - if let Err(e) = payload.reader().read(from_raw_parts_mut(cstr._cstr as *mut u8, len)) { + if let Err(e) = payload + .reader() + .read(from_raw_parts_mut(cstr._cstr as *mut u8, len)) + { log::error!("Failed to read the payload: {}", e); Inplace::empty(dst); errors::Z_EIO @@ -243,17 +249,23 @@ pub unsafe extern "C" fn z_bytes_reader_read( /// Return ​0​ upon success, negative error code otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_seek(this: z_bytes_reader_t, offset: i64, origin: libc::c_int) -> ZCError { +pub unsafe extern "C" fn z_bytes_reader_seek( + this: z_bytes_reader_t, + offset: i64, + origin: libc::c_int, +) -> ZCError { let reader = this.transmute_mut(); let pos = match origin { libc::SEEK_SET => offset.try_into().map(|r| SeekFrom::Start(r)), libc::SEEK_CUR => Ok(SeekFrom::Current(offset)), libc::SEEK_END => Ok(SeekFrom::End(offset)), - _ => { return errors::Z_EINVAL; } + _ => { + return errors::Z_EINVAL; + } }; match pos.map(|p| reader.seek(p)) { Ok(_) => 0, - Err(_) => errors::Z_EINVAL + Err(_) => errors::Z_EINVAL, } } @@ -265,4 +277,3 @@ pub unsafe extern "C" fn z_bytes_reader_tell(this: z_bytes_reader_t) -> i64 { let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } - diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index fa6523128..e592c4166 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -1,17 +1,27 @@ use std::{ - mem::MaybeUninit, sync::{Condvar, Mutex, MutexGuard}, thread::{self, JoinHandle} + mem::MaybeUninit, + sync::{Condvar, Mutex, MutexGuard}, + thread::{self, JoinHandle}, }; use libc::c_void; -use crate::{errors, transmute::{unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}}; -pub use crate::opaque_types::z_owned_mutex_t; pub use crate::opaque_types::z_mutex_t; +pub use crate::opaque_types::z_owned_mutex_t; +use crate::{ + errors, + transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, + }, +}; -decl_transmute_owned!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); +decl_transmute_owned!( + Option<(Mutex<()>, Option>)>, + z_owned_mutex_t +); decl_transmute_handle!((Mutex<()>, Option>), z_mutex_t); - #[no_mangle] pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::ZCError { let this = this.transmute_uninit_ptr(); @@ -37,7 +47,6 @@ pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { this.transmute_handle() } - #[no_mangle] pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::ZCError { let this = this.transmute_mut(); @@ -81,9 +90,8 @@ pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::ZCError { errors::Z_OK } - -pub use crate::opaque_types::z_owned_condvar_t; pub use crate::opaque_types::z_condvar_t; +pub use crate::opaque_types::z_owned_condvar_t; decl_transmute_owned!(Option, z_owned_condvar_t); decl_transmute_handle!(Condvar, z_condvar_t); @@ -181,7 +189,6 @@ pub extern "C" fn z_task_check(this: &z_owned_task_t) -> bool { this.transmute_ref().is_some() } - struct FunArgPair { fun: unsafe extern "C" fn(arg: *mut c_void), arg: *mut c_void, @@ -209,8 +216,8 @@ pub unsafe extern "C" fn z_task_init( match thread::Builder::new().spawn(move || fun_arg_pair.call()) { Ok(join_handle) => { Inplace::init(this, Some(join_handle)); - }, + } Err(_) => return errors::Z_EAGAIN_MUTEX, } errors::Z_OK -} \ No newline at end of file +} diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 0868b5ce1..2f6be1d73 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -13,15 +13,15 @@ // use std::mem::MaybeUninit; -use zenoh::prelude::SyncResolve; use std::ptr::null; +use zenoh::prelude::SyncResolve; use zenoh_ext::SessionExt; -use crate::transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; -use crate::{ - errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t +use crate::transmute::{ + Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr, }; +use crate::{errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t}; /// Options passed to the :c:func:`ze_declare_publication_cache` function. /// @@ -55,7 +55,10 @@ pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache pub use crate::opaque_types::ze_owned_publication_cache_t; pub use crate::opaque_types::ze_publication_cache_t; -decl_transmute_owned!(Option>, ze_owned_publication_cache_t); +decl_transmute_owned!( + Option>, + ze_owned_publication_cache_t +); decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); /// Declares a Publication Cache. diff --git a/src/publisher.rs b/src/publisher.rs index 274b5a52c..dd6012e51 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -31,18 +31,11 @@ use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; -use zenoh::{ - prelude::Priority, - publication::MatchingListener, - publication::Publisher, -}; +use zenoh::{prelude::Priority, publication::MatchingListener, publication::Publisher}; use zenoh::prelude::SyncResolve; -use crate::{ - z_congestion_control_t, z_keyexpr_t, - z_priority_t, z_session_t, z_owned_bytes_t -}; +use crate::{z_congestion_control_t, z_keyexpr_t, z_owned_bytes_t, z_priority_t, z_session_t}; /// Options passed to the :c:func:`z_declare_publisher` function. /// @@ -205,11 +198,11 @@ pub unsafe extern "C" fn z_publisher_put( return errors::Z_EINVAL; } }; - + let mut put = publisher.put(payload); if !options.encoding.is_null() { - let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); put = put.encoding(encoding); }; if !options.attachment.is_null() { @@ -252,7 +245,7 @@ pub extern "C" fn z_publisher_delete( _options: z_publisher_delete_options_t, ) -> errors::ZCError { let publisher = publisher.transmute_ref(); - if let Err(e) = publisher.delete().res_sync() { + if let Err(e) = publisher.delete().res_sync() { log::error!("{}", e); errors::Z_EGENERIC } else { @@ -269,7 +262,10 @@ pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_keyexpr_t { } pub use crate::opaque_types::zcu_owned_matching_listener_t; -decl_transmute_owned!(Option>, zcu_owned_matching_listener_t); +decl_transmute_owned!( + Option>, + zcu_owned_matching_listener_t +); /// A struct that indicates if there exist Subscribers matching the Publisher's key expression. /// @@ -287,7 +283,7 @@ pub struct zcu_matching_status_t { pub extern "C" fn zcu_publisher_matching_listener_callback( publisher: z_publisher_t, callback: &mut zcu_owned_closure_matching_status_t, - this: *mut MaybeUninit + this: *mut MaybeUninit, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); @@ -306,11 +302,11 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( Ok(_) => { Inplace::empty(this); errors::Z_OK - }, + } Err(e) => { log::error!("{}", e); errors::Z_EGENERIC - } + } } } diff --git a/src/put.rs b/src/put.rs index d9b3a9165..a4c93b9b9 100644 --- a/src/put.rs +++ b/src/put.rs @@ -91,11 +91,11 @@ pub extern "C" fn z_put( return errors::Z_EINVAL; } }; - + let mut put = session.put(key_expr, payload); if !options.encoding.is_null() { - let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); put = put.encoding(encoding); }; if !options.attachment.is_null() { @@ -146,11 +146,11 @@ pub extern "C" fn z_delete( ) -> errors::ZCError { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let del - = session.delete(key_expr) + let del = session + .delete(key_expr) .congestion_control(opts.congestion_control.into()) .priority(opts.priority.into()); - + match del.res_sync() { Err(e) => { log::error!("{}", e); diff --git a/src/queryable.rs b/src/queryable.rs index f3f9aa6c5..ecd052253 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -11,19 +11,23 @@ // Contributors: // ZettaScale Zenoh team, // -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}; +use crate::transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, + TransmuteRef, TransmuteUninitPtr, +}; use crate::{ - errors, z_slice_t, z_closure_query_call, z_keyexpr_t,z_owned_bytes_t, z_owned_closure_query_t, z_owned_encoding_t, z_session_t, z_value_t, z_bytes_t + errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, + z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, }; -use zenoh::sample::{SampleBuilderTrait, ValueBuilderTrait}; use std::mem::MaybeUninit; use std::ptr::null_mut; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::{Query, Queryable}; use zenoh::prelude::SyncResolve; +use zenoh::prelude::{Query, Queryable}; +use zenoh::sample::{SampleBuilderTrait, ValueBuilderTrait}; pub use crate::opaque_types::z_owned_queryable_t; -decl_transmute_owned!(Option>, z_owned_queryable_t); +decl_transmute_owned!(Option>, z_owned_queryable_t); /// Constructs a null safe-to-drop value of 'z_owned_queryable_t' type #[no_mangle] @@ -141,7 +145,7 @@ pub extern "C" fn z_declare_queryable( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_query_t, options: Option<&z_queryable_options_t>, - this: *mut MaybeUninit + this: *mut MaybeUninit, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); @@ -163,7 +167,7 @@ pub extern "C" fn z_declare_queryable( Err(e) => { log::error!("{}", e); errors::Z_EGENERIC - } + } } } @@ -201,7 +205,7 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { /// key_expr: The key of this reply. /// payload: The value of this reply. /// options: The options of this reply. -/// +/// /// The payload and all owned options fields are consumed upon function return. #[allow(clippy::missing_safety_doc)] #[no_mangle] @@ -213,7 +217,7 @@ pub unsafe extern "C" fn z_query_reply( ) -> errors::ZCError { let query = query.transmute_ref(); let key_expr = key_expr.transmute_ref(); - + let payload = match payload.transmute_mut().extract() { Some(p) => p, None => { @@ -221,15 +225,15 @@ pub unsafe extern "C" fn z_query_reply( return errors::Z_EINVAL; } }; - + let mut reply = query.reply(key_expr, payload); if !options.encoding.is_null() { - let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); reply = reply.encoding(encoding); }; if !options.attachment.is_null() { - let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); reply = reply.attachment(attachment); } @@ -275,7 +279,11 @@ pub extern "C" fn z_query_has_attachment(query: z_query_t) -> bool { /// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { - query.transmute_ref().value().expect("Query does not contain a value").transmute_handle() + query + .transmute_ref() + .value() + .expect("Query does not contain a value") + .transmute_handle() } /// Gets the attachment to the query by aliasing. @@ -283,5 +291,9 @@ pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { /// Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. #[no_mangle] pub extern "C" fn z_query_attachment(query: z_query_t) -> z_bytes_t { - query.transmute_ref().attachment().expect("Query does not contain an attachment").transmute_handle() + query + .transmute_ref() + .attachment() + .expect("Query does not contain an attachment") + .transmute_handle() } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index ce8bba2f5..e69f0e0f7 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -34,16 +34,22 @@ use crate::transmute::TransmuteUninitPtr; use crate::z_keyexpr_t; use crate::z_owned_closure_sample_t; use crate::z_reliability_t; -use crate::{z_closure_sample_call, z_get_options_t, - z_query_consolidation_none, z_query_consolidation_t, +use crate::{ + z_closure_sample_call, z_get_options_t, z_query_consolidation_none, z_query_consolidation_t, z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, - zcu_reply_keyexpr_default, zcu_reply_keyexpr_t + zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, }; use crate::opaque_types::ze_owned_querying_subscriber_t; use crate::opaque_types::ze_querying_subscriber_t; -decl_transmute_owned!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); -decl_transmute_handle!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); +decl_transmute_owned!( + Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, + ze_owned_querying_subscriber_t +); +decl_transmute_handle!( + (zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), + ze_querying_subscriber_t +); /// Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type #[no_mangle] @@ -137,7 +143,9 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); let session = session.transmute_ref(); - let mut sub = session.declare_subscriber(key_expr.transmute_ref()).querying(); + let mut sub = session + .declare_subscriber(key_expr.transmute_ref()) + .querying(); sub = sub .reliability(options.reliability.into()) .allowed_origin(options.allowed_origin.into()) @@ -149,16 +157,13 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( sub = sub.query_selector(query_selector) } if options.query_timeout_ms != 0 { - sub = sub - .query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); + sub = sub.query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); } - let sub = sub - .callback(move |sample| { + let sub = sub.callback(move |sample| { let sample = sample.transmute_handle(); z_closure_sample_call(&closure, sample); }); - match sub.res() - { + match sub.res() { Ok(sub) => { Inplace::init(this, Some((sub, session))); errors::Z_OK @@ -184,21 +189,22 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( let sub = sub.transmute_ref(); let session = sub.1; let selector = selector.transmute_ref().clone(); - if let Err(e) = sub.0 - .fetch({ - let selector = KeyExpr::try_from(selector).unwrap(); - move |cb| match options { - Some(options) => session - .get(selector) - .target(options.target.into()) - .consolidation(options.consolidation) - .timeout(std::time::Duration::from_millis(options.timeout_ms)) - .callback(cb) - .res_sync(), - None => session.get(selector).callback(cb).res_sync(), - } - }) - .res() + if let Err(e) = sub + .0 + .fetch({ + let selector = KeyExpr::try_from(selector).unwrap(); + move |cb| match options { + Some(options) => session + .get(selector) + .target(options.target.into()) + .consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .callback(cb) + .res_sync(), + None => session.get(selector).callback(cb).res_sync(), + } + }) + .res() { log::debug!("{}", e); return errors::Z_EGENERIC; @@ -209,11 +215,13 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( /// Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn ze_undeclare_querying_subscriber(this: &mut ze_owned_querying_subscriber_t) -> errors::ZCError { +pub extern "C" fn ze_undeclare_querying_subscriber( + this: &mut ze_owned_querying_subscriber_t, +) -> errors::ZCError { if let Some(s) = this.transmute_mut().extract().take() { if let Err(e) = s.0.close().res_sync() { log::error!("{}", e); - return errors::Z_EGENERIC + return errors::Z_EGENERIC; } } errors::Z_OK @@ -228,7 +236,9 @@ pub extern "C" fn ze_querying_subscriber_check(this: &ze_owned_querying_subscrib /// Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. #[no_mangle] -pub extern "C" fn ze_querying_subscriber_loan(this: &ze_owned_querying_subscriber_t,) -> ze_querying_subscriber_t { +pub extern "C" fn ze_querying_subscriber_loan( + this: &ze_owned_querying_subscriber_t, +) -> ze_querying_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/scouting.rs b/src/scouting.rs index 61cba7426..f1f2939c9 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -12,7 +12,11 @@ // ZettaScale Zenoh team, // use crate::{ - errors::{self, Z_OK}, transmute::{Inplace, TransmuteRef}, z_closure_hello_call, z_config_check, z_config_clone, z_config_drop, z_config_new, z_config_null, z_config_t, z_id_t, z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, CopyableToCArray + errors::{self, Z_OK}, + transmute::{Inplace, TransmuteRef}, + z_closure_hello_call, z_config_check, z_config_clone, z_config_drop, z_config_new, + z_config_null, z_config_t, z_id_t, 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}; @@ -203,7 +207,7 @@ pub extern "C" fn z_scouting_config_null(this: *mut MaybeUninit) { - let mut _config = MaybeUninit::::uninit(); + let mut _config = MaybeUninit::::uninit(); z_config_new(&mut _config as *mut MaybeUninit); let _config = unsafe { _config.assume_init() }; @@ -217,7 +221,10 @@ pub extern "C" fn z_scouting_config_default(this: *mut MaybeUninit) { +pub extern "C" fn z_scouting_config_from( + config: z_config_t, + this: *mut MaybeUninit, +) { let mut dst = MaybeUninit::uninit(); z_config_clone(&config, &mut dst as *mut _); let _config = unsafe { dst.assume_init() }; @@ -264,7 +271,9 @@ pub extern "C" fn z_scout( let timeout = config.zc_timeout_ms as u64; let config = match config._config.transmute_mut().extract().take() { Some(c) => c, - None => { return errors::Z_EINVAL ;} + None => { + return errors::Z_EINVAL; + } }; let mut closure = z_owned_closure_hello_t::empty(); std::mem::swap(&mut closure, callback); diff --git a/src/session.rs b/src/session.rs index fb4903bb4..87c6b46fd 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,7 +12,10 @@ // ZettaScale Zenoh team, // -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}; +use crate::transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, +}; use crate::{errors, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; use std::sync::Arc; diff --git a/src/subscriber.rs b/src/subscriber.rs index f431fdb6c..4356ce9d7 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -39,12 +39,12 @@ use zenoh::subscriber::Subscriber; #[repr(C)] #[derive(Clone, Copy)] pub enum z_reliability_t { - BEST_EFFORT, - RELIABLE, + BEST_EFFORT, + RELIABLE, } impl From for z_reliability_t { -#[inline] + #[inline] fn from(r: Reliability) -> Self { match r { Reliability::BestEffort => z_reliability_t::BEST_EFFORT, @@ -54,7 +54,7 @@ impl From for z_reliability_t { } impl From for Reliability { -#[inline] + #[inline] fn from(val: z_reliability_t) -> Self { match val { z_reliability_t::BEST_EFFORT => Reliability::BestEffort, @@ -98,7 +98,7 @@ pub struct z_subscriber_options_t { #[no_mangle] pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { z_subscriber_options_t { - reliability: Reliability::DEFAULT.into() + reliability: Reliability::DEFAULT.into(), } } @@ -147,18 +147,19 @@ pub extern "C" fn z_declare_subscriber( std::mem::swap(callback, &mut closure); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let subscriber - = session.declare_subscriber(key_expr).callback(move |sample| { + let subscriber = session + .declare_subscriber(key_expr) + .callback(move |sample| { let sample = sample.transmute_handle(); z_closure_sample_call(&closure, sample) }); - + let subscriber = subscriber.reliability(options.reliability.into()); match subscriber.res() { Ok(sub) => { Inplace::init(this, Some(sub)); errors::Z_OK - }, + } Err(e) => { log::error!("{}", e); Inplace::empty(this); @@ -182,7 +183,7 @@ pub extern "C" fn z_undeclare_subscriber(subscriber: &mut z_owned_subscriber_t) if let Some(s) = subscriber.transmute_mut().extract().take() { if let Err(e) = s.undeclare().res_sync() { log::error!("{}", e); - return errors::Z_EGENERIC + return errors::Z_EGENERIC; } } errors::Z_OK @@ -192,5 +193,5 @@ pub extern "C" fn z_undeclare_subscriber(subscriber: &mut z_owned_subscriber_t) #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_subscriber_check(subscriber: &z_owned_subscriber_t) -> bool { - subscriber.transmute_ref().is_some() + subscriber.transmute_ref().is_some() } diff --git a/src/transmute.rs b/src/transmute.rs index cafe930ea..97f24b978 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -99,16 +99,30 @@ macro_rules! validate_equivalence { const ALIGN_B: usize = std::mem::align_of::<$type_b>(); if ALIGN_A != ALIGN_B { const ERR_MESSAGE: &str = concatcp!( - "Alingment mismatch: type ", TYPE_NAME_A, " has alignment ", ALIGN_A, - " while type ", TYPE_NAME_B, " has alignment ", ALIGN_B); + "Alingment mismatch: type ", + TYPE_NAME_A, + " has alignment ", + ALIGN_A, + " while type ", + TYPE_NAME_B, + " has alignment ", + ALIGN_B + ); panic!("{}", ERR_MESSAGE); } const SIZE_A: usize = std::mem::size_of::<$type_a>(); const SIZE_B: usize = std::mem::size_of::<$type_b>(); if SIZE_A != SIZE_B { const ERR_MESSAGE: &str = concatcp!( - "Size mismatch: type ", TYPE_NAME_A, " has size ", SIZE_A, - " while type ", TYPE_NAME_B, " has size ", SIZE_B); + "Size mismatch: type ", + TYPE_NAME_A, + " has size ", + SIZE_A, + " while type ", + TYPE_NAME_B, + " has size ", + SIZE_B + ); panic!("{}", ERR_MESSAGE); } }; @@ -183,7 +197,6 @@ macro_rules! impl_transmute_uninit_ptr { }; } - macro_rules! impl_transmute_handle { ($c_type:ty, $zenoh_type:ty) => { impl $crate::transmute::TransmuteFromHandle<$zenoh_type> for $c_type { @@ -195,9 +208,9 @@ macro_rules! impl_transmute_handle { } } impl $crate::transmute::TransmuteIntoHandle<$c_type> for $zenoh_type { - fn transmute_handle(& self) -> $c_type { - unsafe { std::mem::transmute::<& $zenoh_type, $c_type>(self) } + fn transmute_handle(&self) -> $c_type { + unsafe { std::mem::transmute::<&$zenoh_type, $c_type>(self) } } } }; -} \ No newline at end of file +} From 70ac887acd513ed19facafa788a328c1b7ee595f Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 09:51:31 +0200 Subject: [PATCH 051/377] clippy --- build.rs | 9 ++++----- src/closures/query_channel.rs | 2 ++ src/closures/response_channel.rs | 2 ++ src/commons.rs | 4 ++-- src/config.rs | 2 +- src/get.rs | 1 - src/keyexpr.rs | 7 +++---- src/lib.rs | 2 -- src/liveliness.rs | 2 +- src/payload.rs | 2 +- src/publication_cache.rs | 4 +--- src/publisher.rs | 1 - src/put.rs | 8 +------- src/queryable.rs | 6 +++--- src/querying_subscriber.rs | 15 +++++---------- src/scouting.rs | 20 +++++++++++--------- src/session.rs | 3 +-- src/subscriber.rs | 1 - src/transmute.rs | 2 +- 19 files changed, 39 insertions(+), 54 deletions(-) diff --git a/build.rs b/build.rs index 83eabc4f8..50668d5a6 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,4 @@ use fs2::FileExt; -use fs_extra::dir::remove; use regex::Regex; use std::env; use std::io::{Read, Write}; @@ -107,9 +106,9 @@ pub struct {type_name} {{ }} " ); - let doc = docs.remove(type_name).expect(&format!( - "Failed to extract docs for opaque type: {type_name}" - )); + let doc = docs + .remove(type_name) + .unwrap_or_else(|| panic!("Failed to extract docs for opaque type: {type_name}")); for d in doc { data_out += &d; data_out += "\r\n"; @@ -125,7 +124,7 @@ pub struct {type_name} {{ fn get_opaque_type_docs() -> HashMap> { let current_folder = get_build_rs_path(); let path_in = current_folder.join("./build-resources/opaque-types/src/lib.rs"); - let re = Regex::new(r#"(?m)^\s*get_opaque_type_data!\(\s*(.*)\s*,\s*(\w+)\)"#).unwrap(); + let re = Regex::new(r"(?m)^\s*get_opaque_type_data!\(\s*(.*)\s*,\s*(\w+)\)").unwrap(); let mut comments = std::vec::Vec::::new(); let mut res = HashMap::>::new(); diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index 10ba68c0e..15264a470 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -86,6 +86,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver /// which it will then return; or until the `send` closure is dropped and all queries have been consumed, /// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { @@ -111,6 +112,7 @@ pub unsafe extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channe /// which it will then return; or until the `send` closure is dropped and all queries have been consumed, /// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned_query_channel_t { let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index e89b509ba..5cabdccdc 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -84,6 +84,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver /// which it will then return; or until the `send` closure is dropped and all replies have been consumed, /// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { @@ -109,6 +110,7 @@ pub unsafe extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channe /// which it will then return; or until the `send` closure is dropped and all replies have been consumed, /// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned_reply_channel_t { let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { diff --git a/src/commons.rs b/src/commons.rs index 8e2b95cff..650e230d6 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -79,7 +79,7 @@ pub extern "C" fn z_timestamp_npt64_time(timestamp: &z_timestamp_t) -> u64 { } #[no_mangle] -pub unsafe extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t { +pub extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t { timestamp.transmute_copy().get_id().to_le_bytes().into() } @@ -238,7 +238,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - (&Encoding::ZENOH_BYTES).transmute_handle() + Encoding::ZENOH_BYTES.transmute_handle() } /// Frees `encoding`, invalidating it for double-drop safety. diff --git a/src/config.rs b/src/config.rs index f30abd036..12ab9e087 100644 --- a/src/config.rs +++ b/src/config.rs @@ -179,7 +179,7 @@ pub unsafe extern "C" fn zc_config_from_str( let conf_str = CStr::from_ptr(s); let props: Option> = json5::from_str(&conf_str.to_string_lossy()) .ok() - .map(|v| Box::new(v)); + .map(Box::new); if props.is_none() { res = Z_EPARSE; } diff --git a/src/get.rs b/src/get.rs index d72471e1b..97c17bc52 100644 --- a/src/get.rs +++ b/src/get.rs @@ -23,7 +23,6 @@ use zenoh::prelude::{ConsolidationMode, Mode, QueryConsolidation, QueryTarget, R use crate::errors; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; diff --git a/src/keyexpr.rs b/src/keyexpr.rs index e64933366..b39eb6dfd 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -19,7 +19,6 @@ use crate::errors::ZCError; use crate::errors::Z_OK; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; @@ -293,7 +292,7 @@ pub unsafe extern "C" fn z_keyexpr( ) -> ZCError { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); - return errors::Z_EINVAL; + errors::Z_EINVAL } else { let len = libc::strlen(name); zc_keyexpr_from_slice(this, name, len) @@ -311,7 +310,7 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize( ) -> ZCError { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); - return errors::Z_EINVAL; + errors::Z_EINVAL } else { let mut len = libc::strlen(name); let res = zc_keyexpr_from_slice_autocanonize(this, name, &mut len); @@ -383,7 +382,7 @@ pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { } } -impl<'a> From<&'static KeyExpr<'static>> for z_keyexpr_t { +impl From<&'static KeyExpr<'static>> for z_keyexpr_t { fn from(key: &'static KeyExpr<'static>) -> Self { key.transmute_handle() } diff --git a/src/lib.rs b/src/lib.rs index ed883ca71..b7565306b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,8 +65,6 @@ pub mod platform; // #[cfg(feature = "shared-memory")] // mod shm; -pub(crate) const LOG_INVALID_SESSION: &str = "Invalid session"; - /// Initialises the zenoh runtime logger. /// /// Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, diff --git a/src/liveliness.rs b/src/liveliness.rs index 7e9342677..29fee985c 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -22,7 +22,7 @@ use zenoh::{ use crate::transmute::TransmuteIntoHandle; use crate::{ errors, - transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, + transmute::{Inplace, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, }; diff --git a/src/payload.rs b/src/payload.rs index 194d66cc8..a6bfdc927 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -256,7 +256,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( ) -> ZCError { let reader = this.transmute_mut(); let pos = match origin { - libc::SEEK_SET => offset.try_into().map(|r| SeekFrom::Start(r)), + libc::SEEK_SET => offset.try_into().map(SeekFrom::Start), libc::SEEK_CUR => Ok(SeekFrom::Current(offset)), libc::SEEK_END => Ok(SeekFrom::End(offset)), _ => { diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 2f6be1d73..18e0ce407 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -18,9 +18,7 @@ use zenoh::prelude::SyncResolve; use zenoh_ext::SessionExt; -use crate::transmute::{ - Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr, -}; +use crate::transmute::{Inplace, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; use crate::{errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t}; /// Options passed to the :c:func:`ze_declare_publication_cache` function. diff --git a/src/publisher.rs b/src/publisher.rs index dd6012e51..3ab7eb2d5 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -15,7 +15,6 @@ use crate::errors; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; diff --git a/src/put.rs b/src/put.rs index a4c93b9b9..8ba9c77c1 100644 --- a/src/put.rs +++ b/src/put.rs @@ -16,18 +16,12 @@ use std::ptr::null_mut; use crate::commons::*; use crate::errors; use crate::keyexpr::*; -use crate::session::*; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteRef; use crate::z_owned_bytes_t; use crate::z_session_t; -use crate::LOG_INVALID_SESSION; -use libc::c_void; -use zenoh::encoding; -use zenoh::key_expr; -use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; +use zenoh::prelude::{sync::SyncResolve, Priority}; use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; diff --git a/src/queryable.rs b/src/queryable.rs index ecd052253..ea1b7905e 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -12,8 +12,8 @@ // ZettaScale Zenoh team, // use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, - TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, }; use crate::{ errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, @@ -241,7 +241,7 @@ pub unsafe extern "C" fn z_query_reply( log::error!("{}", e); return errors::Z_EGENERIC; } - return errors::Z_OK; + errors::Z_OK } /// Get a query's key by aliasing it. diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index e69f0e0f7..aea07e03a 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -15,18 +15,9 @@ use std::mem::MaybeUninit; use std::ptr::null; -use zenoh::prelude::sync::SyncResolve; -use zenoh::prelude::KeyExpr; -use zenoh::prelude::SessionDeclarations; -use zenoh::session; -use zenoh::session::Session; -use zenoh::subscriber::Reliability; -use zenoh_ext::*; - use crate::errors; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; @@ -39,6 +30,11 @@ use crate::{ z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, }; +use zenoh::prelude::sync::SyncResolve; +use zenoh::prelude::SessionDeclarations; +use zenoh::session::Session; +use zenoh::subscriber::Reliability; +use zenoh_ext::*; use crate::opaque_types::ze_owned_querying_subscriber_t; use crate::opaque_types::ze_querying_subscriber_t; @@ -192,7 +188,6 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( if let Err(e) = sub .0 .fetch({ - let selector = KeyExpr::try_from(selector).unwrap(); move |cb| match options { Some(options) => session .get(selector) diff --git a/src/scouting.rs b/src/scouting.rs index f1f2939c9..22a61fb2e 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -191,50 +191,52 @@ pub const DEFAULT_SCOUTING_TIMEOUT: c_ulong = 1000; #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_scouting_config_null(this: *mut MaybeUninit) { +pub unsafe extern "C" fn z_scouting_config_null(this: *mut MaybeUninit) { let mut _config = MaybeUninit::::uninit(); z_config_null(&mut _config as *mut MaybeUninit); - let _config = unsafe { _config.assume_init() }; + let _config = _config.assume_init(); let config = z_owned_scouting_config_t { _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, }; - (unsafe { &mut *this }).write(config); + (*this).write(config); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_scouting_config_default(this: *mut MaybeUninit) { +pub unsafe extern "C" fn z_scouting_config_default( + this: *mut MaybeUninit, +) { let mut _config = MaybeUninit::::uninit(); z_config_new(&mut _config as *mut MaybeUninit); - let _config = unsafe { _config.assume_init() }; + let _config = _config.assume_init(); let config = z_owned_scouting_config_t { _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, }; - (unsafe { &mut *this }).write(config); + (*this).write(config); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_scouting_config_from( +pub unsafe extern "C" fn z_scouting_config_from( config: z_config_t, this: *mut MaybeUninit, ) { let mut dst = MaybeUninit::uninit(); z_config_clone(&config, &mut dst as *mut _); - let _config = unsafe { dst.assume_init() }; + let _config = dst.assume_init(); let config = z_owned_scouting_config_t { _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, }; - (unsafe { &mut *this }).write(config); + (*this).write(config); } #[no_mangle] diff --git a/src/session.rs b/src/session.rs index 87c6b46fd..c37d8b721 100644 --- a/src/session.rs +++ b/src/session.rs @@ -13,8 +13,7 @@ // use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteIntoHandle, TransmuteRef, - TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{errors, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; diff --git a/src/subscriber.rs b/src/subscriber.rs index 4356ce9d7..ea530d561 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -18,7 +18,6 @@ use crate::errors; use crate::keyexpr::*; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; diff --git a/src/transmute.rs b/src/transmute.rs index 97f24b978..5951a7137 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -63,7 +63,7 @@ pub(crate) trait Inplace: Sized { } // Move the object out of this, leaving it in empty state - fn extract(self: &mut Self) -> Self { + fn extract(&mut self) -> Self { let mut out: MaybeUninit = MaybeUninit::uninit(); Self::empty(&mut out); let mut out = unsafe { out.assume_init() }; From b6f05d56bbdc495fa01b67a7afa925b46455cfed Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 14:22:01 +0200 Subject: [PATCH 052/377] removed shm / pull subscriber; updated macros --- Cargo.toml.in | 3 + examples/z_pub_shm.c | 94 ----------- examples/z_pull.c | 86 ---------- include/zenoh_commons.h | 275 ++++++++++++++++---------------- include/zenoh_macros.h | 103 +++++++----- src/collections.rs | 4 +- src/config.rs | 8 +- src/errors.rs | 22 +-- src/get.rs | 2 +- src/info.rs | 4 +- src/keyexpr.rs | 28 ++-- src/liveliness.rs | 8 +- src/payload.rs | 10 +- src/platform/synchronization.rs | 21 ++- src/publication_cache.rs | 4 +- src/publisher.rs | 10 +- src/put.rs | 4 +- src/queryable.rs | 6 +- src/querying_subscriber.rs | 6 +- src/scouting.rs | 2 +- src/session.rs | 2 +- src/subscriber.rs | 6 +- 22 files changed, 281 insertions(+), 427 deletions(-) delete mode 100644 examples/z_pub_shm.c delete mode 100644 examples/z_pull.c diff --git a/Cargo.toml.in b/Cargo.toml.in index af0cd4fa0..b2ef20aa5 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -60,6 +60,9 @@ const_format = "0.2.32" zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} +zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } +zenoh-util = { path = "../zenoh/commons/zenoh-util" } + [build-dependencies] cbindgen = "0.26.0" diff --git a/examples/z_pub_shm.c b/examples/z_pub_shm.c deleted file mode 100644 index c7bb1684d..000000000 --- a/examples/z_pub_shm.c +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -#include -#include -#include -#include - -#include "zenoh.h" - -#define N 10 - -int main(int argc, char **argv) { - char *keyexpr = "demo/example/zenoh-c-pub-shm"; - char *value = "Pub from C!"; - - if (argc > 1) keyexpr = argv[1]; - if (argc > 2) value = argv[2]; - - z_owned_config_t config = z_config_default(); - // Enable shared memory - if (zc_config_insert_json(z_loan(config), "transport/shared_memory/enabled", "true") < 0) { - printf("Error enabling Shared Memory"); - exit(-1); - } - if (argc > 3) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { - printf( - "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " - "JSON-serialized list of strings\n", - argv[3], Z_CONFIG_CONNECT_KEY, Z_CONFIG_CONNECT_KEY); - exit(-1); - } - } - - printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - z_id_t id = z_info_zid(z_loan(s)); - char idstr[33]; - for (int i = 0; i < 16; i++) { - sprintf(idstr + 2 * i, "%02x", id.id[i]); - } - idstr[32] = 0; - zc_owned_shm_manager_t manager = zc_shm_manager_new(z_loan(s), idstr, N * 1000000); - if (!z_check(s)) { - printf("Unable to open session!\n"); - exit(-1); - } - - printf("Declaring Publisher on '%s'...\n", keyexpr); - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); - if (!z_check(pub)) { - printf("Unable to declare Publisher for key expression!\n"); - exit(-1); - } - - for (int idx = 0; true; ++idx) { - zc_owned_shmbuf_t shmbuf = zc_shm_alloc(&manager, 256); - if (!z_check(shmbuf)) { - zc_shm_gc(&manager); - shmbuf = zc_shm_alloc(&manager, 256); - if (!z_check(shmbuf)) { - printf("Failed to allocate a SHM buffer, even after GCing\n"); - exit(-1); - } - } - char *buf = (char *)zc_shmbuf_ptr(&shmbuf); - buf[256] = 0; - snprintf(buf, 255, "[%4d] %s", idx, value); - size_t len = strlen(buf); - zc_shmbuf_set_length(&shmbuf, len); - z_sleep_s(1); - printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_publisher_put_options_t options = z_publisher_put_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_owned_bytes_t payload = zc_shmbuf_into_payload(z_move(shmbuf)); - z_publisher_put(z_loan(pub), z_move(payload), &options); - } - - z_undeclare_publisher(z_move(pub)); - - z_close(z_move(s)); - return 0; -} diff --git a/examples/z_pull.c b/examples/z_pull.c deleted file mode 100644 index 8016da577..000000000 --- a/examples/z_pull.c +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -#include -#include "zenoh.h" - -const char *kind_to_str(z_sample_kind_t kind); - -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); - printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload_value)); - z_drop(z_move(payload_value)); - z_drop(z_move(keystr)); -} - -int main(int argc, char **argv) { - char *expr = "demo/example/**"; - if (argc > 1) { - expr = argv[1]; - } - - z_owned_config_t config = z_config_default(); - if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { - printf( - "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " - "JSON-serialized list of strings\n", - argv[2], Z_CONFIG_LISTEN_KEY, Z_CONFIG_LISTEN_KEY); - exit(-1); - } - } - - printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { - printf("Unable to open session!\n"); - exit(-1); - } - - z_owned_closure_sample_t callback = z_closure(data_handler); - printf("Declaring Subscriber on '%s'...\n", expr); - z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(expr), z_move(callback), NULL); - if (!z_check(sub)) { - printf("Unable to declare subscriber.\n"); - exit(-1); - } - - printf("Press to pull data...\n"); - char c = 0; - while (c != 'q') { - c = getchar(); - if (c == -1) { - z_sleep_s(1); - } else { - z_subscriber_pull(z_loan(sub)); - } - } - - z_undeclare_pull_subscriber(z_move(sub)); - z_close(z_move(s)); - return 0; -} - -const char *kind_to_str(z_sample_kind_t kind) { - switch (kind) { - case Z_SAMPLE_KIND_PUT: - return "PUT"; - case Z_SAMPLE_KIND_DELETE: - return "DELETE"; - default: - return "UNKNOWN"; - } -} \ No newline at end of file diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 08906c0be..fd817ec0b 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -122,7 +122,7 @@ typedef enum zcu_reply_keyexpr_t { typedef struct ALIGN(8) z_owned_bytes_t { uint8_t _0[40]; } z_owned_bytes_t; -typedef int8_t ZCError; +typedef int8_t z_error_t; /** * A loaned payload. */ @@ -875,17 +875,21 @@ ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_ /** * Decodes payload into owned bytes */ -ZENOHC_API ZCError z_bytes_decode_into_bytes(struct z_bytes_t payload, struct z_owned_slice_t *dst); +ZENOHC_API +z_error_t z_bytes_decode_into_bytes(struct z_bytes_t payload, + struct z_owned_slice_t *dst); /** * Decodes payload into bytes map. */ ZENOHC_API -ZCError z_bytes_decode_into_bytes_map(struct z_bytes_t payload, - struct z_owned_slice_map_t *dst); +z_error_t z_bytes_decode_into_bytes_map(struct z_bytes_t payload, + struct z_owned_slice_map_t *dst); /** * Decodes payload into null-terminated string. */ -ZENOHC_API ZCError z_bytes_decode_into_string(struct z_bytes_t payload, struct z_owned_str_t *dst); +ZENOHC_API +z_error_t z_bytes_decode_into_string(struct z_bytes_t payload, + struct z_owned_str_t *dst); /** * Decrements the payload's reference counter, destroying it if applicable. * @@ -948,9 +952,9 @@ size_t z_bytes_reader_read(struct z_bytes_reader_t this_, * Return ​0​ upon success, negative error code otherwise. */ ZENOHC_API -ZCError z_bytes_reader_seek(struct z_bytes_reader_t this_, - int64_t offset, - int origin); +z_error_t z_bytes_reader_seek(struct z_bytes_reader_t this_, + int64_t offset, + int origin); /** * Returns the read position indicator. * Returns read position indicator on success or -1L if failure occurs. @@ -1056,8 +1060,8 @@ ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); -ZENOHC_API ZCError z_condvar_signal(struct z_condvar_t this_); -ZENOHC_API ZCError z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); +ZENOHC_API z_error_t z_condvar_signal(struct z_condvar_t this_); +ZENOHC_API z_error_t z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); /** * Returns ``true`` if `config` is valid. */ @@ -1067,9 +1071,9 @@ ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); * If `peer` is not null, it is added to the configuration as remote peer. */ ZENOHC_API -ZCError z_config_client(const char *const *peers, - size_t n_peers, - struct z_owned_config_t *this_); +z_error_t z_config_client(const char *const *peers, + size_t n_peers, + struct z_owned_config_t *this_); /** * Clones the config. */ @@ -1111,9 +1115,9 @@ ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); * ease the retrieval of the concerned resource in the routing tables. */ ZENOHC_API -ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr); +z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr); /** * Declares a publisher for the given key expression. * @@ -1150,10 +1154,10 @@ ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); */ ZENOHC_API -ZCError z_declare_publisher(struct z_session_t session, - struct z_keyexpr_t key_expr, - const struct z_publisher_options_t *options, - struct z_owned_publisher_t *this_); +z_error_t z_declare_publisher(struct z_session_t session, + struct z_keyexpr_t key_expr, + const struct z_publisher_options_t *options, + struct z_owned_publisher_t *this_); /** * Creates a Queryable for the given key expression. * @@ -1167,11 +1171,11 @@ ZCError z_declare_publisher(struct z_session_t session, * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. */ ZENOHC_API -ZCError z_declare_queryable(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_query_t *callback, - const struct z_queryable_options_t *options, - struct z_owned_queryable_t *this_); +z_error_t z_declare_queryable(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_query_t *callback, + const struct z_queryable_options_t *options, + struct z_owned_queryable_t *this_); /** * Declare a subscriber for a given key expression. * @@ -1206,11 +1210,11 @@ ZCError z_declare_queryable(struct z_session_t session, * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); */ ZENOHC_API -ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct z_subscriber_options_t options); +z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct z_subscriber_options_t options); /** * Delete data. * @@ -1222,9 +1226,9 @@ ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -ZCError z_delete(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_delete_options_t opts); +z_error_t z_delete(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_delete_options_t opts); /** * Constructs the default value for :c:type:`z_put_options_t`. */ @@ -1270,11 +1274,11 @@ ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); * options: additional options for the get. */ ZENOHC_API -ZCError z_get(struct z_session_t session, - struct z_keyexpr_t key_expr, - const char *parameters, - struct z_owned_closure_reply_t *callback, - struct z_get_options_t options); +z_error_t z_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + const char *parameters, + struct z_owned_closure_reply_t *callback, + struct z_get_options_t options); ZENOHC_API struct z_get_options_t z_get_options_default(void); /** * Returns ``true`` if `hello` is valid. @@ -1301,8 +1305,8 @@ ZENOHC_API struct z_owned_hello_t z_hello_null(void); * Retuns 0 on success, negative values on failure */ ZENOHC_API -ZCError z_info_peers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); +z_error_t z_info_peers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); /** * Fetches the Zenoh IDs of all connected routers. * @@ -1312,8 +1316,8 @@ ZCError z_info_peers_zid(struct z_session_t session, * Retuns 0 on success, negative values on failure. */ ZENOHC_API -ZCError z_info_routers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); +z_error_t z_info_routers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); /** * Returns the local Zenoh ID. * @@ -1326,7 +1330,7 @@ ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); * Constructs a :c:type:`z_keyexpr_t` departing from a string. * It is a loaned key expression that aliases `name`. */ -ZENOHC_API ZCError z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); +ZENOHC_API z_error_t z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); /** * Returns the key expression's internal string by aliasing it. * @@ -1339,8 +1343,8 @@ ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ ZENOHC_API -ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, - char *name); +z_error_t z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, + char *name); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. * @@ -1351,8 +1355,8 @@ ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ ZENOHC_API -ZCError z_keyexpr_canonize(char *start, - size_t *len); +z_error_t z_keyexpr_canonize(char *start, + size_t *len); /** * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. * @@ -1363,7 +1367,7 @@ ZCError z_keyexpr_canonize(char *start, * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ ZENOHC_API -ZCError z_keyexpr_canonize_null_terminated(char *start); +z_error_t z_keyexpr_canonize_null_terminated(char *start); /** * Returns ``true`` if `keyexpr` is valid. */ @@ -1378,10 +1382,10 @@ ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); * as this would extremely likely cause bugs. */ ZENOHC_API -ZCError z_keyexpr_concat(struct z_keyexpr_t left, - const char *right_start, - size_t right_len, - struct z_owned_keyexpr_t *this_); +z_error_t z_keyexpr_concat(struct z_keyexpr_t left, + const char *right_start, + size_t right_len, + struct z_owned_keyexpr_t *this_); /** * Frees `keyexpr` and invalidates it for double-drop safety. */ @@ -1408,15 +1412,15 @@ bool z_keyexpr_intersects(struct z_keyexpr_t left, * Returns ``0`` if the passed string is a valid (and canon) key expression. * Otherwise returns error value */ -ZENOHC_API ZCError z_keyexpr_is_canon(const char *start, size_t len); +ZENOHC_API z_error_t z_keyexpr_is_canon(const char *start, size_t len); /** * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. * In case of error, the return value will be set to its invalidated state. */ ZENOHC_API -ZCError z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right, - struct z_owned_keyexpr_t *this_); +z_error_t z_keyexpr_join(struct z_keyexpr_t left, + struct z_keyexpr_t right, + struct z_owned_keyexpr_t *this_); /** * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. */ @@ -1424,13 +1428,13 @@ ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. */ -ZENOHC_API ZCError z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); +ZENOHC_API z_error_t z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. */ ZENOHC_API -ZCError z_keyexpr_new_autocanonize(const char *name, - struct z_owned_keyexpr_t *this_); +z_error_t z_keyexpr_new_autocanonize(const char *name, + struct z_owned_keyexpr_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type */ @@ -1465,18 +1469,19 @@ void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, const char *name); ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); -ZENOHC_API ZCError z_mutex_init(struct z_owned_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_init(struct z_owned_mutex_t *this_); ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); -ZENOHC_API ZCError z_mutex_lock(struct z_mutex_t this_); -ZENOHC_API ZCError z_mutex_try_lock(struct z_mutex_t this_); -ZENOHC_API ZCError z_mutex_unlock(struct z_mutex_t this_); +ZENOHC_API z_error_t z_mutex_lock(struct z_mutex_t this_); +ZENOHC_API void z_mutex_null(struct z_owned_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_try_lock(struct z_mutex_t this_); +ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t this_); /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. * Config value is always consumed upon function return. */ ZENOHC_API -ZCError z_open(struct z_owned_session_t *this_, - struct z_owned_config_t *config); +z_error_t z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); /** * Returns ``true`` if `pub` is valid. */ @@ -1488,8 +1493,8 @@ ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); * ``0`` in case of success, ``1`` in case of failure. */ ZENOHC_API -ZCError z_publisher_delete(struct z_publisher_t publisher, - struct z_publisher_delete_options_t _options); +z_error_t z_publisher_delete(struct z_publisher_t publisher, + struct z_publisher_delete_options_t _options); /** * Constructs the default values for the delete operation via a publisher entity. * @@ -1530,9 +1535,9 @@ ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -ZCError z_publisher_put(struct z_publisher_t publisher, - struct z_owned_bytes_t *payload, - struct z_publisher_put_options_t options); +z_error_t z_publisher_put(struct z_publisher_t publisher, + struct z_owned_bytes_t *payload, + struct z_publisher_put_options_t options); /** * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ @@ -1553,10 +1558,10 @@ ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void * ``0`` in case of success, negative error values in case of failure. */ ZENOHC_API -ZCError z_put(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_bytes_t *payload, - struct z_put_options_t options); +z_error_t z_put(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_put_options_t options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ @@ -1672,10 +1677,10 @@ struct z_slice_t z_query_parameters(struct z_query_t query); * The payload and all owned options fields are consumed upon function return. */ ZENOHC_API -ZCError z_query_reply(struct z_query_t query, - struct z_keyexpr_t key_expr, - struct z_owned_bytes_t *payload, - struct z_query_reply_options_t options); +z_error_t z_query_reply(struct z_query_t query, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_query_reply_options_t options); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ @@ -1818,8 +1823,8 @@ bool z_sample_timestamp(const struct z_sample_t *sample, * Returns 0 if successful, negative values upon failure. */ ZENOHC_API -ZCError z_scout(struct z_owned_scouting_config_t *config, - struct z_owned_closure_hello_t *callback); +z_error_t z_scout(struct z_owned_scouting_config_t *config, + struct z_owned_closure_hello_t *callback); ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); @@ -1893,18 +1898,18 @@ ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. */ ZENOHC_API -ZCError z_slice_map_insert_by_alias(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); +z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); /** * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. * * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. */ ZENOHC_API -ZCError z_slice_map_insert_by_copy(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); +z_error_t z_slice_map_insert_by_copy(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); /** * Returns true if the map is empty, false otherwise. */ @@ -1994,14 +1999,14 @@ ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); */ ZENOHC_API void z_task_detach(struct z_owned_task_t *this_); ZENOHC_API -ZCError z_task_init(struct z_owned_task_t *this_, - const struct z_task_attr_t *_attr, - void (*fun)(void *arg), - void *arg); +z_error_t z_task_init(struct z_owned_task_t *this_, + const struct z_task_attr_t *_attr, + void (*fun)(void *arg), + void *arg); /** * Joins the task and releases all allocated resources */ -ZENOHC_API ZCError z_task_join(struct z_owned_task_t *this_); +ZENOHC_API z_error_t z_task_join(struct z_owned_task_t *this_); ZENOHC_API void z_task_null(struct z_owned_task_t *this_); ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); @@ -2019,19 +2024,19 @@ ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); +z_error_t z_undeclare_publisher(struct z_owned_publisher_t *publisher); /** * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. * * Parameters: * qable: The :c:type:`z_owned_queryable_t` to undeclare. */ -ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); +ZENOHC_API z_error_t z_undeclare_queryable(struct z_owned_queryable_t *qable); /** * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -ZCError z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); +z_error_t z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); /** * Converts the kind of zenoh entity into a string. * @@ -2048,16 +2053,16 @@ 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. */ ZENOHC_API -ZCError zc_config_from_file(const char *path, - struct z_owned_config_t *this_); +z_error_t zc_config_from_file(const char *path, + struct z_owned_config_t *this_); /** * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. * * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). */ ZENOHC_API -ZCError zc_config_from_str(const char *s, - struct z_owned_config_t *this_); +z_error_t zc_config_from_str(const char *s, + struct z_owned_config_t *this_); /** * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. * Use `z_drop` to safely deallocate this string @@ -2090,18 +2095,18 @@ ZENOHC_API void zc_init_logger(void); * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. */ ZENOHC_API -ZCError zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, - const char *name, - size_t len); +z_error_t zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, + const char *name, + size_t len); /** * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. * 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 -ZCError zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, - char *name, - size_t *len); +z_error_t zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, + char *name, + size_t *len); /** * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: * - `name` MUST be valid UTF8. @@ -2135,11 +2140,11 @@ struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_def * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. */ ZENOHC_API -ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct zc_liveliness_declare_subscriber_options_t _options); +z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct zc_liveliness_declare_subscriber_options_t _options); /** * Constructs and declares a liveliness token on the network. * @@ -2149,10 +2154,10 @@ ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, * Passing `NULL` as options is valid and equivalent to a pointer to the default options. */ ZENOHC_API -ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct zc_liveliness_declaration_options_t _options); +z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct zc_liveliness_declaration_options_t _options); /** * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. * @@ -2161,10 +2166,10 @@ ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. */ ZENOHC_API -ZCError zc_liveliness_get(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_reply_t *callback, - struct zc_liveliness_get_options_t options); +z_error_t zc_liveliness_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_reply_t *callback, + struct zc_liveliness_get_options_t options); /** * The gravestone value for `zc_liveliness_get_options_t` */ @@ -2182,7 +2187,7 @@ ZENOHC_API void zc_liveliness_token_null(struct zc_owned_liveliness_token_t *thi /** * Destroys a liveliness token, notifying subscribers of its destruction. */ -ZENOHC_API ZCError zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); +ZENOHC_API z_error_t zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); /** * Creates a new blocking fifo channel, returned as a pair of closures. * @@ -2284,9 +2289,9 @@ ZENOHC_API enum zcu_locality_t zcu_locality_default(void); * Register callback for notifying subscribers matching. */ ZENOHC_API -ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, - struct zcu_owned_closure_matching_status_t *callback, - struct zcu_owned_matching_listener_t *this_); +z_error_t zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, + struct zcu_owned_closure_matching_status_t *callback, + struct zcu_owned_matching_listener_t *this_); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); /** * Declares a Publication Cache. @@ -2315,10 +2320,10 @@ ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); */ ZENOHC_API -ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct ze_publication_cache_options_t options); +z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct ze_publication_cache_options_t options); /** * Declares a Querying Subscriber for a given key expression. * @@ -2353,11 +2358,11 @@ ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); */ ZENOHC_API -ZCError ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct ze_querying_subscriber_options_t options); +z_error_t ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct ze_querying_subscriber_options_t options); /** * Returns ``true`` if `pub_cache` is valid. */ @@ -2379,9 +2384,9 @@ ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subs * The queried samples will be merged with the received publications and made available in the subscriber callback. */ ZENOHC_API -ZCError ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, - struct z_keyexpr_t selector, - const struct z_get_options_t *options); +z_error_t ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, + struct z_keyexpr_t selector, + const struct z_get_options_t *options); /** * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. */ @@ -2399,9 +2404,9 @@ ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_option * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -ZCError ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); +z_error_t ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); /** * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -ZCError ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); +z_error_t ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index a2d0582b1..110f4871a 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -14,8 +14,13 @@ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ - z_owned_bytes_t : z_bytes_loan, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ + z_owned_slice_map_t : z_slice_map_loan \ + z_owned_slice_t : z_slice_loan, \ + z_owned_bytes_t : z_bytes_loan, \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ + z_owned_mutex_t : z_mutex_loan, \ + z_condvar_t : z_condvar_loan, \ + z_owned_bytes_reader_t : z_bytes_reader_loan, \ )(&x) #define z_drop(x) \ @@ -24,7 +29,6 @@ z_owned_keyexpr_t * : z_keyexpr_drop, \ z_owned_config_t * : z_config_drop, \ z_owned_scouting_config_t * : z_scouting_config_drop, \ - z_owned_pull_subscriber_t * : z_undeclare_pull_subscriber, \ z_owned_subscriber_t * : z_undeclare_subscriber, \ z_owned_queryable_t * : z_undeclare_queryable, \ z_owned_encoding_t * : z_encoding_drop, \ @@ -42,13 +46,16 @@ z_owned_query_channel_closure_t * : z_query_channel_closure_drop, \ z_owned_reply_channel_t * : z_reply_channel_drop, \ z_owned_query_channel_t * : z_query_channel_drop, \ - z_owned_bytes_map_t * : z_slice_map_drop, \ - z_owned_bytes_t * : z_bytes_drop, \ - zc_owned_shmbuf_t * : zc_shmbuf_drop, \ - zc_owned_shm_manager_t * : zc_shm_manager_drop, \ + z_owned_slice_map_t * : z_slice_map_drop, \ + z_owned_slice_t * : z_slice_drop, \ zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ ze_owned_publication_cache_t * : ze_undeclare_publication_cache, \ - ze_owned_querying_subscriber_t * : ze_undeclare_querying_subscriber \ + ze_owned_querying_subscriber_t * : ze_undeclare_querying_subscriber, \ + z_owned_bytes_t * : z_bytes_drop, \ + z_owned_bytes_reader_t * : z_bytes_reader_drop, \ + z_owned_mutex_t * : z_mutex_drop, \ + z_owned_condvar_t * : z_condvar_drop, \ + z_owned_bytes_reader_t * : z_bytes_reader_drop \ )(x) #define z_null(x) (*x = \ @@ -57,7 +64,6 @@ z_owned_keyexpr_t * : z_keyexpr_null, \ z_owned_config_t * : z_config_null, \ z_owned_scouting_config_t * : z_scouting_config_null, \ - z_owned_pull_subscriber_t * : z_pull_subscriber_null, \ z_owned_subscriber_t * : z_subscriber_null, \ z_owned_queryable_t * : z_queryable_null, \ z_owned_encoding_t * : z_encoding_null, \ @@ -73,13 +79,15 @@ zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ z_owned_reply_channel_t * : z_reply_channel_null, \ - z_owned_bytes_map_t * : z_slice_map_null, \ - z_owned_bytes_t * : z_bytes_null, \ - z_bytes_t * : z_attachment_null, \ - zc_owned_shmbuf_t * : zc_shmbuf_null, \ - zc_owned_shm_manager_t * : zc_shm_manager_null, \ + z_owned_slice_map_t * : z_slice_map_null, \ + z_owned_bytes_t * : z_bytes_null, \ + z_owned_slice_t * : z_slice_null, \ ze_owned_publication_cache_t * : ze_publication_cache_null, \ - zc_owned_liveliness_token_t * : zc_liveliness_token_null \ + zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ + z_owned_bytes_reader_t * : z_bytes_reader_null, \ + z_owned_mutex_t * : z_mutex_null, \ + z_owned_condvar_t * : z_condvar_null, \ + z_owned_task_t * : z_task_null \ )()) #define z_check(x) \ @@ -89,7 +97,6 @@ z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ - z_owned_bytes_t : z_slice_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -98,14 +105,15 @@ z_owned_hello_t : z_hello_check, \ z_owned_query_t : z_query_check, \ z_owned_str_t : z_str_check, \ - z_owned_bytes_map_t : z_slice_map_check, \ - z_owned_bytes_t: z_bytes_check, \ - z_bytes_t : z_attachment_check, \ - zc_owned_shmbuf_t : zc_shmbuf_check, \ - zc_owned_shm_manager_t : zc_shm_manager_check, \ + z_owned_slice_map_t : z_slice_map_check, \ + z_owned_slice_t: z_slice_check, \ + z_owned_bytes_t : z_bytes_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ ze_owned_publication_cache_t : ze_publication_cache_check, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_check \ + z_owned_mutex_t : z_mutex_check, \ + z_owned_condvar_t : z_owned_condar_check, \ + z_owned_task_t : z_task_check \ )(&x) #define z_call(x, ...) \ @@ -138,12 +146,16 @@ template<> struct zenoh_loan_type{ typedef z_config_t type; }; template<> struct zenoh_loan_type{ typedef z_publisher_t type; }; template<> struct zenoh_loan_type{ typedef z_subscriber_t type; }; template<> struct zenoh_loan_type{ typedef z_query_t type; }; -template<> struct zenoh_loan_type{ typedef z_pull_subscriber_t type; }; template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; template<> struct zenoh_loan_type{ typedef z_bytes_t type; }; +template<> struct zenoh_loan_type{ typedef z_bytes_reader_t type; }; template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; +template<> struct zenoh_loan_type{ typedef z_slice_t type; }; +template<> struct zenoh_loan_type{ typedef z_slice_map_t type; }; +template<> struct zenoh_loan_type{ typedef z_mutex_t type; }; +template<> struct zenoh_loan_type{ typedef z_condvar_t type; }; template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } template<> inline z_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keyexpr_loan(&x); } @@ -156,7 +168,12 @@ template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_lo template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } template<> inline z_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } +template<> inline z_bytes_reader_t z_loan(const z_owned_bytes_reader_t& x) { return z_bytes_reader_loan(&x); } template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } +template<> inline z_slice_t z_loan(const z_owned_slice_t& x) { return z_slice_loan(&x); } +template<> inline z_slice_map_t z_loan(const z_owned_slice_map_t& x) { return z_slice_map_loan(&x); } +template<> inline z_mutex_t z_loan(const z_owned_mutex_t& x) { return z_mutex_loan(&x); } +template<> inline z_condvar_t z_loan(const z_owned_condvar_t& x) { return z_condvar_loan(&x); } template struct zenoh_drop_type { typedef T type; }; template inline typename zenoh_drop_type::type z_drop(T*); @@ -166,7 +183,6 @@ template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -175,9 +191,7 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -186,10 +200,13 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; +template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> inline int8_t z_drop(z_owned_session_t* v) { return z_close(v); } template<> inline int8_t z_drop(z_owned_publisher_t* v) { return z_undeclare_publisher(v); } @@ -205,9 +222,7 @@ template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } -template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } -template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } -template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } +template<> inline void z_drop(z_owned_bytes_reader_t* v) { z_bytes_reader_drop(v); } template<> inline void z_drop(z_owned_closure_sample_t* v) { z_closure_sample_drop(v); } template<> inline void z_drop(z_owned_closure_query_t* v) { z_closure_query_drop(v); } template<> inline void z_drop(z_owned_closure_reply_t* v) { z_closure_reply_drop(v); } @@ -216,17 +231,19 @@ template<> inline void z_drop(z_owned_closure_zid_t* v) { z_closure_zid_drop(v); template<> inline void z_drop(zcu_owned_closure_matching_status_t* v) { zcu_closure_matching_status_drop(v); } template<> inline void z_drop(z_owned_reply_channel_closure_t* v) { z_reply_channel_closure_drop(v); } template<> inline void z_drop(z_owned_reply_channel_t* v) { z_reply_channel_drop(v); } -template<> inline void z_drop(z_owned_bytes_map_t* v) { z_slice_map_drop(v); } +template<> inline void z_drop(z_owned_slice_t* v) { z_slice_drop(v); } +template<> inline void z_drop(z_owned_slice_map_t* v) { z_slice_map_drop(v); } template<> inline void z_drop(zc_owned_liveliness_token_t* v) { zc_liveliness_undeclare_token(v); } template<> inline int8_t z_drop(ze_owned_publication_cache_t* v) { return ze_undeclare_publication_cache(v); } template<> inline int8_t z_drop(ze_owned_querying_subscriber_t* v) { return ze_undeclare_querying_subscriber(v); } +template<> inline void z_drop(z_owned_mutex_t* v) { z_mutex_drop(v); } +template<> inline void z_drop(z_owned_condvar_t* v) { z_condvar_drop(v); } inline void z_null(z_owned_session_t& v) { v = z_session_null(); } inline void z_null(z_owned_publisher_t& v) { v = z_publisher_null(); } inline void z_null(z_owned_keyexpr_t& v) { v = z_keyexpr_null(); } inline void z_null(z_owned_config_t& v) { v = z_config_null(); } inline void z_null(z_owned_scouting_config_t& v) { v = z_scouting_config_null(); } -inline void z_null(z_owned_pull_subscriber_t& v) { v = z_pull_subscriber_null(); } inline void z_null(z_owned_subscriber_t& v) { v = z_subscriber_null(); } inline void z_null(z_owned_queryable_t& v) { v = z_queryable_null(); } inline void z_null(z_owned_encoding_t& v) { v = z_encoding_null(); } @@ -235,9 +252,7 @@ inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } -inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } -inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } -inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } +inline void z_null(z_owned_bytes_reader_t& v) { v = z_bytes_reader_null(); } inline void z_null(z_owned_closure_sample_t& v) { v = z_closure_sample_null(); } inline void z_null(z_owned_closure_query_t& v) { v = z_closure_query_null(); } inline void z_null(z_owned_closure_reply_t& v) { v = z_closure_reply_null(); } @@ -246,10 +261,14 @@ inline void z_null(z_owned_closure_zid_t& v) { v = z_closure_zid_null(); } inline void z_null(zcu_owned_closure_matching_status_t& v) { v = zcu_closure_matching_status_null(); } inline void z_null(z_owned_reply_channel_closure_t& v) { v = z_reply_channel_closure_null(); } inline void z_null(z_owned_reply_channel_t& v) { v = z_reply_channel_null(); } -inline void z_null(z_owned_bytes_map_t& v) { v = z_slice_map_null(); } +inline void z_null(z_owned_slice_t& v) { v = z_slice_null(); } +inline void z_null(z_owned_slice_map_t& v) { v = z_slice_map_null(); } inline void z_null(zc_owned_liveliness_token_t& v) { v = zc_liveliness_token_null(); } inline void z_null(ze_owned_publication_cache_t& v) { v = ze_publication_cache_null(); } inline void z_null(ze_owned_querying_subscriber_t& v) { v = ze_querying_subscriber_null(); } +inline void z_null(z_owned_mutex_t& v) { v = z_mutex_null(); } +inline void z_null(z_owned_condvar_t& v) { v = z_condvar_null(); } +inline void z_null(z_owned_task_t& v) { v = z_task_null(); } inline bool z_check(const z_owned_session_t& v) { return z_session_check(&v); } inline bool z_check(const z_owned_publisher_t& v) { return z_publisher_check(&v); } @@ -258,9 +277,7 @@ inline bool z_check(const z_keyexpr_t& v) { return z_keyexpr_is_initialized(&v); inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } inline bool z_check(const z_owned_bytes_t& v) { return z_slice_check(&v); } -inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } -inline bool z_check(const zc_owned_shmbuf_t& v) { return zc_shmbuf_check(&v); } -inline bool z_check(const zc_owned_shm_manager_t& v) { return zc_shm_manager_check(&v); } +inline bool z_check(const z_owned_bytes_reader_t& v) { return z_bytes_reader_check(&v); } inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } inline bool z_check(const z_owned_pull_subscriber_t& v) { return z_pull_subscriber_check(&v); } inline bool z_check(const z_owned_queryable_t& v) { return z_queryable_check(&v); } @@ -269,12 +286,14 @@ inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } -inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } -inline bool z_check(const z_owned_bytes_map_t& v) { return z_slice_map_check(&v); } -inline bool z_check(constz_bytes_t& v) { return z_attachment_check(&v); } +inline bool z_check(const z_owned_slice_t& v) { return z_slice_check(&v); } +inline bool z_check(const z_owned_slice_map_t& v) { return z_slice_map_check(&v); } inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } inline bool z_check(const ze_owned_publication_cache_t& v) { return ze_publication_cache_check(&v); } inline bool z_check(const ze_owned_querying_subscriber_t& v) { return ze_querying_subscriber_check(&v); } +inline bool z_check(const z_owned_mutex_t& v) { return z_mutex_check(&v); } +inline bool z_check(const z_owned_condvar_t& v) { return z_condvar_check(&v); } +inline bool z_check(const z_owned_task_t& v) { return z_task_check(&v); } inline void z_call(const struct z_owned_closure_sample_t &closure, const struct z_sample_t *sample) { z_closure_sample_call(&closure, sample); } diff --git a/src/collections.rs b/src/collections.rs index 6bf5622b5..c07832d11 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -429,7 +429,7 @@ pub extern "C" fn z_slice_map_insert_by_copy( this: z_slice_map_t, key: z_slice_t, value: z_slice_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_mut(); if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); @@ -449,7 +449,7 @@ pub extern "C" fn z_slice_map_insert_by_alias( this: z_slice_map_t, key: z_slice_t, value: z_slice_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_mut(); if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { this.insert(Cow::Borrowed(key), Cow::Borrowed(value)); diff --git a/src/config.rs b/src/config.rs index 12ab9e087..f8e3d7ced 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,7 +16,7 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; -use crate::errors::{ZCError, Z_EPARSE}; +use crate::errors::{z_error_t, Z_EPARSE}; use crate::transmute::{ unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, @@ -170,7 +170,7 @@ pub extern "C" fn z_config_check(config: &z_owned_config_t) -> bool { pub unsafe extern "C" fn zc_config_from_str( s: *const c_char, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let mut res = errors::Z_OK; if s.is_null() { z_config_null(this); @@ -205,7 +205,7 @@ pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { pub unsafe extern "C" fn zc_config_from_file( path: *const c_char, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let path_str = CStr::from_ptr(path); let mut res = errors::Z_OK; let config = match path_str.to_str() { @@ -245,7 +245,7 @@ pub unsafe extern "C" fn z_config_client( peers: *const *const c_char, n_peers: usize, this: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { let mut res = errors::Z_OK; let locators = if peers.is_null() { Vec::new() diff --git a/src/errors.rs b/src/errors.rs index 72448026a..7415ffb40 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,12 +1,12 @@ -pub type ZCError = i8; -pub const Z_OK: ZCError = 0; -pub const Z_EINVAL: ZCError = -1; -pub const Z_EPARSE: ZCError = -2; -pub const Z_EIO: ZCError = -3; -pub const Z_ENETWORK: ZCError = -4; +pub type z_error_t = i8; +pub const Z_OK: z_error_t = 0; +pub const Z_EINVAL: z_error_t = -1; +pub const Z_EPARSE: z_error_t = -2; +pub const Z_EIO: z_error_t = -3; +pub const Z_ENETWORK: z_error_t = -4; // negativ pthread error codes (due to convention to return negative values on error) -pub const Z_EBUSY_MUTEX: ZCError = -16; -pub const Z_EINVAL_MUTEX: ZCError = -22; -pub const Z_EAGAIN_MUTEX: ZCError = -11; -pub const Z_EPOISON_MUTEX: ZCError = -22; // same as Z_EINVAL_MUTEX -pub const Z_EGENERIC: ZCError = i8::MIN; +pub const Z_EBUSY_MUTEX: z_error_t = -16; +pub const Z_EINVAL_MUTEX: z_error_t = -22; +pub const Z_EAGAIN_MUTEX: z_error_t = -11; +pub const Z_EPOISON_MUTEX: z_error_t = -22; // same as Z_EINVAL_MUTEX +pub const Z_EGENERIC: z_error_t = i8::MIN; diff --git a/src/get.rs b/src/get.rs index 97c17bc52..67abe9db6 100644 --- a/src/get.rs +++ b/src/get.rs @@ -148,7 +148,7 @@ pub unsafe extern "C" fn z_get( parameters: *const c_char, callback: &mut z_owned_closure_reply_t, options: z_get_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let mut closure = z_owned_closure_reply_t::empty(); std::mem::swap(callback, &mut closure); let p = if parameters.is_null() { diff --git a/src/info.rs b/src/info.rs index c2604d84a..90afc28ca 100644 --- a/src/info.rs +++ b/src/info.rs @@ -50,7 +50,7 @@ pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { pub unsafe extern "C" fn z_info_peers_zid( session: z_session_t, callback: &mut z_owned_closure_zid_t, -) -> errors::ZCError { +) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); let session = session.transmute_ref(); @@ -71,7 +71,7 @@ pub unsafe extern "C" fn z_info_peers_zid( pub unsafe extern "C" fn z_info_routers_zid( session: z_session_t, callback: &mut z_owned_closure_zid_t, -) -> errors::ZCError { +) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); let session = session.transmute_ref(); diff --git a/src/keyexpr.rs b/src/keyexpr.rs index b39eb6dfd..6f25b75c6 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -15,7 +15,7 @@ use std::mem::MaybeUninit; use crate::errors; -use crate::errors::ZCError; +use crate::errors::z_error_t; use crate::errors::Z_OK; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; @@ -68,7 +68,7 @@ unsafe fn keyexpr_create( name: &'static mut [u8], should_auto_canonize: bool, should_copy: bool, -) -> Result, errors::ZCError> { +) -> Result, errors::z_error_t> { match std::str::from_utf8_mut(name) { Ok(name) => match keyexpr_create_inner(name, should_auto_canonize, should_copy) { Ok(v) => Ok(v), @@ -90,7 +90,7 @@ unsafe fn keyexpr_create( pub unsafe extern "C" fn z_keyexpr_new( name: *const c_char, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { if name.is_null() { return errors::Z_EINVAL; } @@ -114,7 +114,7 @@ pub unsafe extern "C" fn z_keyexpr_new( pub unsafe extern "C" fn z_keyexpr_new_autocanonize( name: *const c_char, this: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { if name.is_null() { return errors::Z_EINVAL; } @@ -178,7 +178,7 @@ impl std::error::Error for UninitializedKeyExprError {} /// Otherwise returns error value #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> ZCError { +pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> z_error_t { let name = std::slice::from_raw_parts_mut(start as _, len); match keyexpr_create(name, false, false) { Ok(_) => errors::Z_OK, @@ -195,7 +195,7 @@ pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> /// 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_canonize_null_terminated(start: *mut c_char) -> ZCError { +pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) -> z_error_t { let mut len = libc::strlen(start); match z_keyexpr_canonize(start, &mut len) { Z_OK => { @@ -214,7 +214,7 @@ pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) /// 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_canonize(start: *mut c_char, len: &mut usize) -> ZCError { +pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) -> z_error_t { let name = std::slice::from_raw_parts_mut(start as _, *len); match keyexpr_create(name, true, false) { Ok(ke) => { @@ -232,7 +232,7 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice( this: *mut MaybeUninit, name: *const c_char, len: usize, -) -> ZCError { +) -> z_error_t { let this = this.transmute_uninit_ptr(); if name.is_null() { Inplace::empty(this); @@ -261,7 +261,7 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( this: *mut MaybeUninit, name: *mut c_char, len: &mut usize, -) -> ZCError { +) -> z_error_t { let this = this.transmute_uninit_ptr(); if name.is_null() { Inplace::empty(this); @@ -289,7 +289,7 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( pub unsafe extern "C" fn z_keyexpr( this: *mut MaybeUninit, name: *const c_char, -) -> ZCError { +) -> z_error_t { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL @@ -307,7 +307,7 @@ pub unsafe extern "C" fn z_keyexpr( pub unsafe extern "C" fn z_keyexpr_autocanonize( this: *mut MaybeUninit, name: *mut c_char, -) -> ZCError { +) -> z_error_t { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL @@ -401,7 +401,7 @@ pub extern "C" fn z_declare_keyexpr( this: *mut MaybeUninit, session: z_session_t, key_expr: z_keyexpr_t, -) -> ZCError { +) -> z_error_t { let this = this.transmute_uninit_ptr(); let key_expr = key_expr.transmute_ref(); let session = session.transmute_ref(); @@ -480,7 +480,7 @@ pub unsafe extern "C" fn z_keyexpr_concat( right_start: *const c_char, right_len: usize, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let left = left.transmute_ref(); let right = std::slice::from_raw_parts(right_start as _, right_len); @@ -518,7 +518,7 @@ pub extern "C" fn z_keyexpr_join( left: z_keyexpr_t, right: z_keyexpr_t, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let left = left.transmute_ref(); let right = right.transmute_ref(); let this = this.transmute_uninit_ptr(); diff --git a/src/liveliness.rs b/src/liveliness.rs index 29fee985c..e16a77727 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -71,7 +71,7 @@ pub extern "C" fn zc_liveliness_declare_token( session: z_session_t, key_expr: z_keyexpr_t, _options: zc_liveliness_declaration_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -92,7 +92,7 @@ pub extern "C" fn zc_liveliness_declare_token( #[no_mangle] pub extern "C" fn zc_liveliness_undeclare_token( this: &mut zc_owned_liveliness_token_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_mut(); if let Some(token) = this.extract().take() { if let Err(e) = token.undeclare().res() { @@ -136,7 +136,7 @@ pub extern "C" fn zc_liveliness_declare_subscriber( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, _options: zc_liveliness_declare_subscriber_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_sample_t::empty()); @@ -185,7 +185,7 @@ pub extern "C" fn zc_liveliness_get( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_reply_t, options: zc_liveliness_get_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_reply_t::empty()); diff --git a/src/payload.rs b/src/payload.rs index a6bfdc927..d80d0f060 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,4 +1,4 @@ -use crate::errors::{self, ZCError}; +use crate::errors::{self, z_error_t}; use crate::transmute::{ unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, @@ -71,7 +71,7 @@ extern "C" fn z_bytes_len(payload: z_bytes_t) -> usize { pub unsafe extern "C" fn z_bytes_decode_into_string( payload: z_bytes_t, dst: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { let len = z_bytes_len(payload); let cstr = z_owned_str_t::preallocate(len); let payload = payload.transmute_ref(); @@ -94,7 +94,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( payload: z_bytes_t, dst: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { let dst = dst.transmute_uninit_ptr(); let payload = payload.transmute_ref(); let iter = payload.iter::<(Vec, Vec)>(); @@ -112,7 +112,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( pub unsafe extern "C" fn z_bytes_decode_into_bytes( payload: z_bytes_t, dst: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { let len = z_bytes_len(payload); let b = z_owned_slice_t::preallocate(len); let payload = payload.transmute_ref(); @@ -253,7 +253,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( this: z_bytes_reader_t, offset: i64, origin: libc::c_int, -) -> ZCError { +) -> z_error_t { let reader = this.transmute_mut(); let pos = match origin { libc::SEEK_SET => offset.try_into().map(SeekFrom::Start), diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index e592c4166..cd1c016e3 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -23,7 +23,7 @@ decl_transmute_owned!( decl_transmute_handle!((Mutex<()>, Option>), z_mutex_t); #[no_mangle] -pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::ZCError { +pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let m = (Mutex::<()>::new(()), None::>); Inplace::init(this, Some(m)); @@ -40,6 +40,11 @@ pub extern "C" fn z_mutex_check(this: &z_owned_mutex_t) -> bool { this.transmute_ref().is_some() } +#[no_mangle] +pub extern "C" fn z_mutex_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); +} + #[no_mangle] pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { let this = this.transmute_ref(); @@ -48,7 +53,7 @@ pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { } #[no_mangle] -pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::ZCError { +pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.lock() { @@ -64,7 +69,7 @@ pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::ZCError { } #[no_mangle] -pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::ZCError { +pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); if this.1.is_none() { return errors::Z_EINVAL_MUTEX; @@ -76,7 +81,7 @@ pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::ZCError { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::ZCError { +pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.try_lock() { Ok(new_lock) => { @@ -126,7 +131,7 @@ pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> z_condvar_t { } #[no_mangle] -pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::ZCError { +pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::z_error_t { let this = this.transmute_mut(); this.notify_one(); errors::Z_OK @@ -134,7 +139,7 @@ pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::ZCError { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_wait(this: z_condvar_t, m: z_mutex_t) -> errors::ZCError { +pub unsafe extern "C" fn z_condvar_wait(this: z_condvar_t, m: z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); let m = m.transmute_mut(); if m.1.is_none() { @@ -172,7 +177,7 @@ pub extern "C" fn z_task_detach(this: &mut z_owned_task_t) { /// Joins the task and releases all allocated resources #[no_mangle] -pub extern "C" fn z_task_join(this: &mut z_owned_task_t) -> errors::ZCError { +pub extern "C" fn z_task_join(this: &mut z_owned_task_t) -> errors::z_error_t { let this = this.transmute_mut().extract().take(); if let Some(task) = this { match task.join() { @@ -209,7 +214,7 @@ pub unsafe extern "C" fn z_task_init( _attr: *const z_task_attr_t, fun: unsafe extern "C" fn(arg: *mut c_void), arg: *mut c_void, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let fun_arg_pair = FunArgPair { fun, arg }; diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 18e0ce407..25c4d4ffd 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -90,7 +90,7 @@ pub extern "C" fn ze_declare_publication_cache( session: z_session_t, key_expr: z_keyexpr_t, options: ze_publication_cache_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -138,7 +138,7 @@ pub extern "C" fn ze_publication_cache_check(this: &ze_owned_publication_cache_t #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_undeclare_publication_cache( this: &mut ze_owned_publication_cache_t, -) -> errors::ZCError { +) -> errors::z_error_t { if let Some(p) = this.transmute_mut().extract().take() { if let Err(e) = p.close().res_sync() { log::error!("{}", e); diff --git a/src/publisher.rs b/src/publisher.rs index 3ab7eb2d5..3d3c6a84d 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -101,7 +101,7 @@ pub extern "C" fn z_declare_publisher( key_expr: z_keyexpr_t, options: Option<&z_publisher_options_t>, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref().clone().into_owned(); @@ -188,7 +188,7 @@ pub unsafe extern "C" fn z_publisher_put( publisher: z_publisher_t, payload: &mut z_owned_bytes_t, options: z_publisher_put_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let publisher = publisher.transmute_ref(); let payload = match payload.transmute_mut().extract() { Some(p) => p, @@ -242,7 +242,7 @@ pub extern "C" fn z_publisher_delete_options_default() -> z_publisher_delete_opt pub extern "C" fn z_publisher_delete( publisher: z_publisher_t, _options: z_publisher_delete_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let publisher = publisher.transmute_ref(); if let Err(e) = publisher.delete().res_sync() { log::error!("{}", e); @@ -283,7 +283,7 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( publisher: z_publisher_t, callback: &mut zcu_owned_closure_matching_status_t, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); std::mem::swap(callback, &mut closure); @@ -312,7 +312,7 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( /// Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> errors::ZCError { +pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> errors::z_error_t { if let Some(p) = publisher.transmute_mut().extract().take() { if let Err(e) = p.undeclare().res_sync() { log::error!("{}", e); diff --git a/src/put.rs b/src/put.rs index 8ba9c77c1..a59934106 100644 --- a/src/put.rs +++ b/src/put.rs @@ -75,7 +75,7 @@ pub extern "C" fn z_put( key_expr: z_keyexpr_t, payload: &mut z_owned_bytes_t, options: z_put_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let payload = match payload.transmute_mut().extract() { @@ -137,7 +137,7 @@ pub extern "C" fn z_delete( session: z_session_t, key_expr: z_keyexpr_t, opts: z_delete_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let del = session diff --git a/src/queryable.rs b/src/queryable.rs index ea1b7905e..279afba74 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -146,7 +146,7 @@ pub extern "C" fn z_declare_queryable( callback: &mut z_owned_closure_query_t, options: Option<&z_queryable_options_t>, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut closure, callback); @@ -177,7 +177,7 @@ pub extern "C" fn z_declare_queryable( /// qable: The :c:type:`z_owned_queryable_t` to undeclare. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> errors::ZCError { +pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> errors::z_error_t { if let Some(qable) = qable.transmute_mut().extract().take() { if let Err(e) = qable.undeclare().res_sync() { log::error!("{}", e); @@ -214,7 +214,7 @@ pub unsafe extern "C" fn z_query_reply( key_expr: z_keyexpr_t, payload: &mut z_owned_bytes_t, options: z_query_reply_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let query = query.transmute_ref(); let key_expr = key_expr.transmute_ref(); diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index aea07e03a..6afb0f9fe 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -134,7 +134,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: ze_querying_subscriber_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); @@ -180,7 +180,7 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( sub: ze_querying_subscriber_t, selector: z_keyexpr_t, options: Option<&z_get_options_t>, -) -> errors::ZCError { +) -> errors::z_error_t { unsafe impl Sync for z_get_options_t {} let sub = sub.transmute_ref(); let session = sub.1; @@ -212,7 +212,7 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( #[no_mangle] pub extern "C" fn ze_undeclare_querying_subscriber( this: &mut ze_owned_querying_subscriber_t, -) -> errors::ZCError { +) -> errors::z_error_t { if let Some(s) = this.transmute_mut().extract().take() { if let Err(e) = s.0.close().res_sync() { log::error!("{}", e); diff --git a/src/scouting.rs b/src/scouting.rs index 22a61fb2e..113f11c70 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -264,7 +264,7 @@ pub extern "C" fn z_scouting_config_drop(config: &mut z_owned_scouting_config_t) pub extern "C" fn z_scout( config: &mut z_owned_scouting_config_t, callback: &mut z_owned_closure_hello_t, -) -> errors::ZCError { +) -> errors::z_error_t { if cfg!(feature = "logger-autoinit") { zc_init_logger(); } diff --git a/src/session.rs b/src/session.rs index c37d8b721..5079c50f0 100644 --- a/src/session.rs +++ b/src/session.rs @@ -59,7 +59,7 @@ pub extern "C" fn z_session_null(this: *mut MaybeUninit) { pub extern "C" fn z_open( this: *mut MaybeUninit, config: &mut z_owned_config_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); if cfg!(feature = "logger-autoinit") { zc_init_logger(); diff --git a/src/subscriber.rs b/src/subscriber.rs index ea530d561..4e0582ad4 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -140,7 +140,7 @@ pub extern "C" fn z_declare_subscriber( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: z_subscriber_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); @@ -178,7 +178,9 @@ pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_keyexpr_ /// Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_subscriber(subscriber: &mut z_owned_subscriber_t) -> errors::ZCError { +pub extern "C" fn z_undeclare_subscriber( + subscriber: &mut z_owned_subscriber_t, +) -> errors::z_error_t { if let Some(s) = subscriber.transmute_mut().extract().take() { if let Err(e) = s.undeclare().res_sync() { log::error!("{}", e); From 630c3cbaccbfb97de33ab58f1d4f28569dca8009 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 23:11:06 +0200 Subject: [PATCH 053/377] more fixes --- Cargo.toml | 1 + build-resources/opaque-types/src/lib.rs | 2 +- examples/z_sub_thr.c | 23 ++++++---- include/zenoh_commons.h | 60 ++++++++++++------------- include/zenoh_macros.h | 6 +-- src/collections.rs | 11 ++++- src/config.rs | 12 ++--- src/get.rs | 36 ++++++++------- src/liveliness.rs | 4 +- src/payload.rs | 14 +++--- src/publication_cache.rs | 22 ++++----- src/publisher.rs | 19 ++++---- src/pull_subscriber.rs | 4 +- src/put.rs | 19 ++++---- src/queryable.rs | 23 +++++----- src/querying_subscriber.rs | 28 ++++++------ src/scouting.rs | 4 +- src/subscriber.rs | 9 ++-- 18 files changed, 159 insertions(+), 138 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4e62df310..1d25448fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,7 @@ zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } zenoh-util = { path = "../zenoh/commons/zenoh-util" } + [build-dependencies] cbindgen = "0.26.0" fs2 = "0.4.3" diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 846e887a3..9e9f7d434 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -60,7 +60,7 @@ get_opaque_type_data!(Option, zc_owned_sample_t); get_opaque_type_data!(&'static Sample, z_sample_t); /// A reader for payload data. -get_opaque_type_data!(Option>, z_owned_bytes_t_reader_t); +get_opaque_type_data!(Option>, z_owned_bytes_reader_t); get_opaque_type_data!(&'static ZBytesReader<'static>, z_bytes_reader_t); /// The encoding of a payload, in a MIME-like format. diff --git a/examples/z_sub_thr.c b/examples/z_sub_thr.c index 05ee709d3..3fdfe1e2a 100644 --- a/examples/z_sub_thr.c +++ b/examples/z_sub_thr.c @@ -14,6 +14,7 @@ #include #include "zenoh.h" +#include #define N 1000000 @@ -33,7 +34,7 @@ z_stats_t *z_stats_make() { return stats; } -void on_sample(const z_sample_t *sample, void *context) { +void on_sample(z_sample_t sample, void *context) { z_stats_t *stats = (z_stats_t *)context; if (stats->count == 0) { stats->start = z_clock_now(); @@ -60,7 +61,8 @@ void drop_stats(void *context) { } int main(int argc, char **argv) { - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 1) { if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[1]) < 0) { printf( @@ -71,18 +73,22 @@ int main(int argc, char **argv) { } } - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } - z_owned_keyexpr_t ke = z_declare_keyexpr(z_loan(s), z_keyexpr("test/thr")); + z_owned_keyexpr_t ke; + z_keyexpr(&ke, "test/thr"); + z_owned_keyexpr_t declared_ke; + z_declare_keyexpr(&ke, z_loan(s), z_loan(ke)); z_stats_t *context = z_stats_make(); z_owned_closure_sample_t callback = z_closure(on_sample, drop_stats, context); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_loan(ke), z_move(callback), NULL); - if (!z_check(sub)) { + z_owned_subscriber_t sub; + if (z_declare_subscriber(&sub, z_loan(s), z_loan(declared_ke), z_move(callback), NULL)) { printf("Unable to create subscriber.\n"); exit(-1); } @@ -93,7 +99,8 @@ int main(int argc, char **argv) { } z_undeclare_subscriber(z_move(sub)); - z_undeclare_keyexpr(z_loan(s), z_move(ke)); + z_keyexpr_drop(z_move(ke)); + z_undeclare_keyexpr(z_loan(s), z_move(declared_ke)); z_close(z_move(s)); return 0; } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index fd817ec0b..88a84d4dd 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -165,9 +165,9 @@ typedef struct ALIGN(8) z_slice_map_t { /** * A reader for payload data. */ -typedef struct ALIGN(8) z_owned_bytes_t_reader_t { +typedef struct ALIGN(8) z_owned_bytes_reader_t { uint8_t _0[24]; -} z_owned_bytes_t_reader_t; +} z_owned_bytes_reader_t; typedef struct ALIGN(8) z_bytes_reader_t { uint8_t _0[8]; } z_bytes_reader_t; @@ -922,19 +922,16 @@ ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); * The gravestone value for `z_owned_bytes_t`. */ ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); -ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_t_reader_t *this_); -ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_t_reader_t *this_); -ZENOHC_API -struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_t_reader_t *reader); +ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_reader_t *this_); +ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_reader_t *this_); +ZENOHC_API struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); /** * Creates a reader for the specified `payload`. * * Returns 0 in case of success, -1 if `payload` is not valid. */ -ZENOHC_API -void z_bytes_reader_new(struct z_bytes_t payload, - struct z_owned_bytes_t_reader_t *this_); -ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_t_reader_t *this_); +ZENOHC_API void z_bytes_reader_new(struct z_bytes_t payload, struct z_owned_bytes_reader_t *this_); +ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); /** * Reads data into specified destination. * @@ -1078,14 +1075,6 @@ z_error_t z_config_client(const char *const *peers, * Clones the config. */ ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); -/** - * Frees `config`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); -/** - * Returns a :c:type:`z_config_t` loaned from `s`. - */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); /** * Return a new, zenoh-allocated, empty configuration. * @@ -1099,7 +1088,15 @@ ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. */ ZENOHC_API -void z_config_new(struct z_owned_config_t *this_); +void z_config_default(struct z_owned_config_t *this_); +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_config_t' type */ @@ -1171,11 +1168,11 @@ z_error_t z_declare_publisher(struct z_session_t session, * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. */ ZENOHC_API -z_error_t z_declare_queryable(struct z_session_t session, +z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, + struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_query_t *callback, - const struct z_queryable_options_t *options, - struct z_owned_queryable_t *this_); + struct z_queryable_options_t *options); /** * Declare a subscriber for a given key expression. * @@ -1214,7 +1211,7 @@ z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_sample_t *callback, - struct z_subscriber_options_t options); + struct z_subscriber_options_t *options); /** * Delete data. * @@ -1278,7 +1275,7 @@ z_error_t z_get(struct z_session_t session, struct z_keyexpr_t key_expr, const char *parameters, struct z_owned_closure_reply_t *callback, - struct z_get_options_t options); + struct z_get_options_t *options); ZENOHC_API struct z_get_options_t z_get_options_default(void); /** * Returns ``true`` if `hello` is valid. @@ -1537,7 +1534,7 @@ ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); ZENOHC_API z_error_t z_publisher_put(struct z_publisher_t publisher, struct z_owned_bytes_t *payload, - struct z_publisher_put_options_t options); + struct z_publisher_put_options_t *options); /** * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ @@ -1561,7 +1558,7 @@ ZENOHC_API z_error_t z_put(struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_bytes_t *payload, - struct z_put_options_t options); + struct z_put_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ @@ -1680,7 +1677,7 @@ ZENOHC_API z_error_t z_query_reply(struct z_query_t query, struct z_keyexpr_t key_expr, struct z_owned_bytes_t *payload, - struct z_query_reply_options_t options); + struct z_query_reply_options_t *options); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ @@ -1922,6 +1919,7 @@ void z_slice_map_iterate(const struct z_slice_map_t *this_, * Returns number of key-value pairs in the map. */ ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); +ZENOHC_API struct z_slice_map_t z_slice_map_loan(const struct z_owned_slice_map_t *this_); /** * Constructs a new empty map. */ @@ -2144,7 +2142,7 @@ z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_sample_t *callback, - struct zc_liveliness_declare_subscriber_options_t _options); + struct zc_liveliness_declare_subscriber_options_t *_options); /** * Constructs and declares a liveliness token on the network. * @@ -2157,7 +2155,7 @@ ZENOHC_API z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, struct z_session_t session, struct z_keyexpr_t key_expr, - struct zc_liveliness_declaration_options_t _options); + struct zc_liveliness_declaration_options_t *_options); /** * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. * @@ -2323,7 +2321,7 @@ ZENOHC_API z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, struct z_session_t session, struct z_keyexpr_t key_expr, - struct ze_publication_cache_options_t options); + struct ze_publication_cache_options_t *options); /** * Declares a Querying Subscriber for a given key expression. * @@ -2362,7 +2360,7 @@ z_error_t ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t * struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_sample_t *callback, - struct ze_querying_subscriber_options_t options); + struct ze_querying_subscriber_options_t *options); /** * Returns ``true`` if `pub_cache` is valid. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 110f4871a..69f89de72 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -9,18 +9,17 @@ z_owned_config_t : z_config_loan, \ z_owned_publisher_t : z_publisher_loan, \ z_owned_subscriber_t : z_subscriber_loan, \ - z_owned_pull_subscriber_t : z_pull_subscriber_loan, \ z_owned_encoding_t : z_encoding_loan, \ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ - z_owned_slice_map_t : z_slice_map_loan \ + z_owned_slice_map_t : z_slice_map_loan, \ z_owned_slice_t : z_slice_loan, \ z_owned_bytes_t : z_bytes_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ z_owned_mutex_t : z_mutex_loan, \ z_condvar_t : z_condvar_loan, \ - z_owned_bytes_reader_t : z_bytes_reader_loan, \ + z_owned_bytes_reader_t : z_bytes_reader_loan \ )(&x) #define z_drop(x) \ @@ -162,7 +161,6 @@ template<> inline z_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keye template<> inline z_config_t z_loan(const z_owned_config_t& x) { return z_config_loan(&x); } template<> inline z_publisher_t z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } template<> inline z_subscriber_t z_loan(const z_owned_subscriber_t& x) { return z_subscriber_loan(&x); } -template<> inline z_pull_subscriber_t z_loan(const z_owned_pull_subscriber_t& x) { return z_pull_subscriber_loan(&x); } template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_encoding_loan(&x); } template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } diff --git a/src/collections.rs b/src/collections.rs index c07832d11..38412ba29 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -21,7 +21,7 @@ use zenoh::prelude::ZenohId; use crate::errors; use crate::transmute::{ - Inplace, InplaceDefault, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; /// A contiguous view of bytes owned by some other entity. @@ -338,7 +338,7 @@ decl_transmute_handle!( ); pub use crate::opaque_types::z_owned_config_t; -decl_transmute_owned!(Option, z_owned_slice_map_t); +decl_transmute_owned!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); /// Constructs a new empty map. #[no_mangle] @@ -371,6 +371,13 @@ pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { Inplace::drop(this); } +#[no_mangle] +pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) ->z_slice_map_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() +} + /// Returns number of key-value pairs in the map. #[no_mangle] pub extern "C" fn z_slice_map_len(this: z_slice_map_t) -> usize { diff --git a/src/config.rs b/src/config.rs index f8e3d7ced..e7e420474 100644 --- a/src/config.rs +++ b/src/config.rs @@ -71,11 +71,11 @@ decl_transmute_owned!(Option>, z_owned_config_t); /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan(s: &'static z_owned_config_t) -> z_config_t { - let s = s.transmute_ref(); - let s = unwrap_ref_unchecked(s); - let s = s.as_ref(); - s.transmute_handle() +pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> z_config_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + let this = this.as_ref(); + this.transmute_handle() } /// Return a new, zenoh-allocated, empty configuration. @@ -89,7 +89,7 @@ pub extern "C" fn z_config_loan(s: &'static z_owned_config_t) -> z_config_t { /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[no_mangle] -pub extern "C" fn z_config_new(this: *mut MaybeUninit) { +pub extern "C" fn z_config_default(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); let config: Box = Box::default(); Inplace::init(this, Some(config)); diff --git a/src/get.rs b/src/get.rs index 67abe9db6..bdf8ddfa0 100644 --- a/src/get.rs +++ b/src/get.rs @@ -147,7 +147,7 @@ pub unsafe extern "C" fn z_get( key_expr: z_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, - options: z_get_options_t, + options: Option<&mut z_get_options_t>, ) -> errors::z_error_t { let mut closure = z_owned_closure_reply_t::empty(); std::mem::swap(callback, &mut closure); @@ -160,24 +160,26 @@ pub unsafe extern "C" fn z_get( let key_expr = key_expr.transmute_ref(); let mut get = session.get(key_expr.clone().with_parameters(p)); - if !options.payload.is_null() { - if let Some(payload) = unsafe { *options.payload }.transmute_mut().extract() { - get = get.payload(payload); + if let Some(options) = options { + if !options.payload.is_null() { + if let Some(payload) = unsafe { *options.payload }.transmute_mut().extract() { + get = get.payload(payload); + } + } + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + get = get.encoding(encoding); + } + if !options.attachment.is_null() { + let attachment = unsafe { *options.payload }.transmute_mut().extract(); + get = get.attachment(attachment); } - } - if !options.encoding.is_null() { - let encoding = unsafe { *options.encoding }.transmute_mut().extract(); - get = get.encoding(encoding); - } - if !options.attachment.is_null() { - let attachment = unsafe { *options.payload }.transmute_mut().extract(); - get = get.attachment(attachment); - } - get = get - .consolidation(options.consolidation) - .timeout(std::time::Duration::from_millis(options.timeout_ms)) - .target(options.target.into()); + get = get + .consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .target(options.target.into()); + } match get .callback(move |response| z_closure_reply_call(&closure, response.transmute_handle())) .res_sync() diff --git a/src/liveliness.rs b/src/liveliness.rs index e16a77727..f35c1ce22 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -70,7 +70,7 @@ pub extern "C" fn zc_liveliness_declare_token( this: *mut MaybeUninit, session: z_session_t, key_expr: z_keyexpr_t, - _options: zc_liveliness_declaration_options_t, + _options: Option<&mut zc_liveliness_declaration_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); @@ -135,7 +135,7 @@ pub extern "C" fn zc_liveliness_declare_subscriber( session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - _options: zc_liveliness_declare_subscriber_options_t, + _options: Option<&mut zc_liveliness_declare_subscriber_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); diff --git a/src/payload.rs b/src/payload.rs index d80d0f060..582f65408 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -180,8 +180,8 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( z_bytes_encode_from_bytes(this, bytes); } -pub use crate::opaque_types::z_owned_bytes_t_reader_t; -decl_transmute_owned!(Option>, z_owned_bytes_t_reader_t); +pub use crate::opaque_types::z_owned_bytes_reader_t; +decl_transmute_owned!(Option>, z_owned_bytes_reader_t); pub use crate::opaque_types::z_bytes_reader_t; decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); @@ -193,7 +193,7 @@ decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_new( payload: z_bytes_t, - this: *mut MaybeUninit, + this: *mut MaybeUninit, ) { let this = this.transmute_uninit_ptr(); let payload = payload.transmute_ref(); @@ -203,25 +203,25 @@ pub unsafe extern "C" fn z_bytes_reader_new( #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_null(this: *mut MaybeUninit) { +pub unsafe extern "C" fn z_bytes_reader_null(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); Inplace::empty(this); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_check(this: &z_owned_bytes_t_reader_t) -> bool { +pub unsafe extern "C" fn z_bytes_reader_check(this: &z_owned_bytes_reader_t) -> bool { this.transmute_ref().is_some() } #[no_mangle] -extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_t_reader_t) { +extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_reader_t) { let reader = this.transmute_mut(); Inplace::drop(reader); } #[no_mangle] -extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_t_reader_t) -> z_bytes_reader_t { +extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_reader_t) -> z_bytes_reader_t { let reader = reader.transmute_ref(); let reader = unwrap_ref_unchecked(reader); reader.transmute_handle() diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 25c4d4ffd..7f8f9e9e6 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -89,21 +89,23 @@ pub extern "C" fn ze_declare_publication_cache( this: *mut MaybeUninit, session: z_session_t, key_expr: z_keyexpr_t, - options: ze_publication_cache_options_t, + options: Option<&mut ze_publication_cache_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let mut p = session.declare_publication_cache(key_expr); - p = p.history(options.history); - p = p.queryable_allowed_origin(options.queryable_origin.into()); - p = p.queryable_complete(options.queryable_complete); - if options.resources_limit != 0 { - p = p.resources_limit(options.resources_limit) - } - if !options.queryable_prefix.is_null() { - let queryable_prefix = unsafe { *options.queryable_prefix }.transmute_ref(); - p = p.queryable_prefix(queryable_prefix.clone()); + if let Some(options) = options { + p = p.history(options.history); + p = p.queryable_allowed_origin(options.queryable_origin.into()); + p = p.queryable_complete(options.queryable_complete); + if options.resources_limit != 0 { + p = p.resources_limit(options.resources_limit) + } + if !options.queryable_prefix.is_null() { + let queryable_prefix = unsafe { *options.queryable_prefix }.transmute_ref(); + p = p.queryable_prefix(queryable_prefix.clone()); + } } match p.res_sync() { Ok(publication_cache) => { diff --git a/src/publisher.rs b/src/publisher.rs index 3d3c6a84d..30c033645 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -187,7 +187,7 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t pub unsafe extern "C" fn z_publisher_put( publisher: z_publisher_t, payload: &mut z_owned_bytes_t, - options: z_publisher_put_options_t, + options: Option<&mut z_publisher_put_options_t>, ) -> errors::z_error_t { let publisher = publisher.transmute_ref(); let payload = match payload.transmute_mut().extract() { @@ -199,14 +199,15 @@ pub unsafe extern "C" fn z_publisher_put( }; let mut put = publisher.put(payload); - - if !options.encoding.is_null() { - let encoding = unsafe { *options.encoding }.transmute_mut().extract(); - put = put.encoding(encoding); - }; - if !options.attachment.is_null() { - let attachment = unsafe { *options.attachment }.transmute_mut().extract(); - put = put.attachment(attachment); + if let Some(options) = options { + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + put = put.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + put = put.attachment(attachment); + } } if let Err(e) = put.res_sync() { diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index ebef7064b..624be46cb 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -131,7 +131,7 @@ pub extern "C" fn z_pull_subscriber_options_default() -> z_pull_subscriber_optio /// /// .. code-block:: C /// -/// z_subscriber_options_t opts = z_subscriber_options_default(); +/// z_subscriber_options_t options = z_subscriber_options_default(); /// z_owned_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -139,7 +139,7 @@ pub extern "C" fn z_declare_pull_subscriber( session: z_session_t, keyexpr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - opts: Option<&z_pull_subscriber_options_t>, + options: Option<&z_pull_subscriber_options_t>, ) -> z_owned_pull_subscriber_t { let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); diff --git a/src/put.rs b/src/put.rs index a59934106..8bc9505d1 100644 --- a/src/put.rs +++ b/src/put.rs @@ -74,7 +74,7 @@ pub extern "C" fn z_put( session: z_session_t, key_expr: z_keyexpr_t, payload: &mut z_owned_bytes_t, - options: z_put_options_t, + options: Option<&mut z_put_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -87,14 +87,15 @@ pub extern "C" fn z_put( }; let mut put = session.put(key_expr, payload); - - if !options.encoding.is_null() { - let encoding = unsafe { *options.encoding }.transmute_mut().extract(); - put = put.encoding(encoding); - }; - if !options.attachment.is_null() { - let attachment = unsafe { *options.attachment }.transmute_mut().extract(); - put = put.attachment(attachment); + if let Some(options) = options { + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + put = put.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + put = put.attachment(attachment); + } } if let Err(e) = put.res_sync() { diff --git a/src/queryable.rs b/src/queryable.rs index 279afba74..17b5a82bc 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -141,11 +141,11 @@ pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_declare_queryable( + this: *mut MaybeUninit, session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_query_t, - options: Option<&z_queryable_options_t>, - this: *mut MaybeUninit, + options: Option<&mut z_queryable_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); @@ -213,7 +213,7 @@ pub unsafe extern "C" fn z_query_reply( query: z_query_t, key_expr: z_keyexpr_t, payload: &mut z_owned_bytes_t, - options: z_query_reply_options_t, + options: Option<&mut z_query_reply_options_t>, ) -> errors::z_error_t { let query = query.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -227,14 +227,15 @@ pub unsafe extern "C" fn z_query_reply( }; let mut reply = query.reply(key_expr, payload); - - if !options.encoding.is_null() { - let encoding = unsafe { *options.encoding }.transmute_mut().extract(); - reply = reply.encoding(encoding); - }; - if !options.attachment.is_null() { - let attachment = unsafe { *options.attachment }.transmute_mut().extract(); - reply = reply.attachment(attachment); + if let Some(options) = options { + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + reply = reply.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + reply = reply.attachment(attachment); + } } if let Err(e) = reply.res_sync() { diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 6afb0f9fe..9bc8e2459 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -133,7 +133,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - options: ze_querying_subscriber_options_t, + options: Option<&mut ze_querying_subscriber_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); @@ -142,18 +142,20 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( let mut sub = session .declare_subscriber(key_expr.transmute_ref()) .querying(); - sub = sub - .reliability(options.reliability.into()) - .allowed_origin(options.allowed_origin.into()) - .query_target(options.query_target.into()) - .query_consolidation(options.query_consolidation) - .query_accept_replies(options.query_accept_replies.into()); - if !options.query_selector.is_null() { - let query_selector = unsafe { *options.query_selector }.transmute_ref().clone(); - sub = sub.query_selector(query_selector) - } - if options.query_timeout_ms != 0 { - sub = sub.query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); + if let Some(options) = options { + sub = sub + .reliability(options.reliability.into()) + .allowed_origin(options.allowed_origin.into()) + .query_target(options.query_target.into()) + .query_consolidation(options.query_consolidation) + .query_accept_replies(options.query_accept_replies.into()); + if !options.query_selector.is_null() { + let query_selector = unsafe { *options.query_selector }.transmute_ref().clone(); + sub = sub.query_selector(query_selector) + } + if options.query_timeout_ms != 0 { + sub = sub.query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); + } } let sub = sub.callback(move |sample| { let sample = sample.transmute_handle(); diff --git a/src/scouting.rs b/src/scouting.rs index 113f11c70..3d593852d 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -14,7 +14,7 @@ use crate::{ errors::{self, Z_OK}, transmute::{Inplace, TransmuteRef}, - z_closure_hello_call, z_config_check, z_config_clone, z_config_drop, z_config_new, + z_closure_hello_call, z_config_check, z_config_clone, z_config_default, z_config_drop, z_config_null, z_config_t, z_id_t, z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, CopyableToCArray, }; @@ -210,7 +210,7 @@ pub unsafe extern "C" fn z_scouting_config_default( this: *mut MaybeUninit, ) { let mut _config = MaybeUninit::::uninit(); - z_config_new(&mut _config as *mut MaybeUninit); + z_config_default(&mut _config as *mut MaybeUninit); let _config = _config.assume_init(); let config = z_owned_scouting_config_t { diff --git a/src/subscriber.rs b/src/subscriber.rs index 4e0582ad4..81b1a8c4c 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -139,21 +139,22 @@ pub extern "C" fn z_declare_subscriber( session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - options: z_subscriber_options_t, + options: Option<&mut z_subscriber_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let subscriber = session + let mut subscriber = session .declare_subscriber(key_expr) .callback(move |sample| { let sample = sample.transmute_handle(); z_closure_sample_call(&closure, sample) }); - - let subscriber = subscriber.reliability(options.reliability.into()); + if let Some(options) = options { + subscriber = subscriber.reliability(options.reliability.into()); + } match subscriber.res() { Ok(sub) => { Inplace::init(this, Some(sub)); From 328c28f3cf7abde4dbcbe9c0b48388d7858d75f3 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 23:19:06 +0200 Subject: [PATCH 054/377] removed ref to local zenoh --- Cargo.lock | 195 ++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 15 ++-- Cargo.toml.in | 15 ++-- src/collections.rs | 10 ++- src/payload.rs | 7 +- 5 files changed, 212 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ebd15726..3120c2703 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -285,6 +285,9 @@ name = "bitflags" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -370,9 +373,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -476,6 +479,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crossbeam-utils" version = "0.8.16" @@ -1135,6 +1153,15 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lockfree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ee94b5ad113c7cb98c5a040f783d0952ee4fe100993881d1673c2cb002dd23" +dependencies = [ + "owned-alloc", +] + [[package]] name = "log" version = "0.4.21" @@ -1297,9 +1324,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -1363,6 +1390,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "owned-alloc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30fceb411f9a12ff9222c5f824026be368ff15dc2f13468d850c7d3f502205d6" + [[package]] name = "parking" version = "2.1.0" @@ -1574,6 +1607,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -1779,6 +1821,18 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64", + "bitflags 2.4.0", + "serde", + "serde_derive", +] + [[package]] name = "rsa" version = "0.9.2" @@ -1946,6 +2000,12 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + [[package]] name = "ryu" version = "1.0.15" @@ -2140,6 +2200,12 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + [[package]] name = "sha3" version = "0.10.8" @@ -2276,6 +2342,42 @@ dependencies = [ "der", ] +[[package]] +name = "stabby" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ec04c5825384722310b6a1fd83023bee0bfdc838f7aa3069f0a59e10203836b" +dependencies = [ + "lazy_static", + "rustversion", + "stabby-abi", +] + +[[package]] +name = "stabby-abi" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976322da1deb6cc64a8406fd24378b840b1962acaac1978a993131c3838d81b3" +dependencies = [ + "libc", + "rustversion", + "sha2-const-stable", + "stabby-macros", +] + +[[package]] +name = "stabby-macros" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736712a13ab37b1fa6e073831efca751bbcb31033af4d7308bd5d9d605939183" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "rand", + "syn 1.0.109", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -2375,6 +2477,20 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "thread-priority" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72cb4958060ee2d9540cef68bb3871fd1e547037772c7fe7650d5d1cbec53b3" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "log", + "rustversion", + "winapi", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -2494,6 +2610,23 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.37" @@ -3082,9 +3215,19 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "zenoh" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "ahash", "async-trait", @@ -3140,6 +3283,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "zenoh-collections", ] @@ -3175,6 +3319,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "serde", "tracing", @@ -3187,10 +3332,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" [[package]] name = "zenoh-config" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "flume", "json5", @@ -3210,6 +3357,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-global-executor", "lazy_static", @@ -3221,6 +3369,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "aes", "hmac", @@ -3233,6 +3382,7 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "bincode", "flume", @@ -3244,12 +3394,14 @@ dependencies = [ "tokio", "tracing", "zenoh", + "zenoh-macros", "zenoh-util", ] [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3263,6 +3415,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "zenoh-config", @@ -3280,6 +3433,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "flume", @@ -3302,6 +3456,7 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "base64", @@ -3330,6 +3485,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "tokio", @@ -3347,6 +3503,7 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "base64", @@ -3375,6 +3532,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "socket2 0.5.6", @@ -3395,6 +3553,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "futures", @@ -3414,6 +3573,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "futures-util", @@ -3434,6 +3594,7 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "proc-macro2", "quote", @@ -3444,6 +3605,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "const_format", "libloading", @@ -3459,6 +3621,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "const_format", "rand", @@ -3473,6 +3636,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "anyhow", ] @@ -3480,10 +3644,16 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "futures", "lazy_static", + "libc", + "ron", + "serde", "tokio", + "zenoh-collections", + "zenoh-macros", "zenoh-protocol", "zenoh-result", ] @@ -3491,17 +3661,31 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ + "async-trait", + "bincode", + "crc", + "lazy_static", + "lockfree", + "num-traits", + "rand", "serde", "shared_memory", + "stabby", + "thread-priority", + "tokio", "tracing", "zenoh-buffers", + "zenoh-core", + "zenoh-macros", "zenoh-result", ] [[package]] name = "zenoh-sync" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "event-listener 4.0.0", "futures", @@ -3515,6 +3699,7 @@ dependencies = [ [[package]] name = "zenoh-task" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "futures", "tokio", @@ -3527,6 +3712,7 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "flume", @@ -3559,6 +3745,7 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-std", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 1d25448fe..1b5582b26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ maintenance = { status = "actively-developed" } [dependencies] async-std = "=1.12.0" async-trait = "0.1.66" -chrono = "0.4.34" +chrono = "0.4.37" env_logger = "0.10.0" futures = "0.3.26" json5 = "0.4.1" @@ -53,15 +53,10 @@ spin = "0.9.5" unwrap-infallible = "0.1.5" const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -#zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -#zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -#zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -#zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } - -zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } -zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} -zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } -zenoh-util = { path = "../zenoh/commons/zenoh-util" } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } [build-dependencies] diff --git a/Cargo.toml.in b/Cargo.toml.in index b2ef20aa5..80c4f40ec 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -41,7 +41,7 @@ maintenance = { status = "actively-developed" } [dependencies] async-std = "=1.12.0" async-trait = "0.1.66" -chrono = "0.4.34" +chrono = "0.4.37" env_logger = "0.10.0" futures = "0.3.26" json5 = "0.4.1" @@ -53,15 +53,10 @@ spin = "0.9.5" unwrap-infallible = "0.1.5" const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -#zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -#zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -#zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -#zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } - -zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } -zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} -zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } -zenoh-util = { path = "../zenoh/commons/zenoh-util" } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } [build-dependencies] diff --git a/src/collections.rs b/src/collections.rs index 38412ba29..2b0dc1898 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -21,7 +21,8 @@ use zenoh::prelude::ZenohId; use crate::errors; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, + TransmuteRef, TransmuteUninitPtr, }; /// A contiguous view of bytes owned by some other entity. @@ -338,7 +339,10 @@ decl_transmute_handle!( ); pub use crate::opaque_types::z_owned_config_t; -decl_transmute_owned!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); +decl_transmute_owned!( + Option, Cow<'static, [u8]>>>, + z_owned_slice_map_t +); /// Constructs a new empty map. #[no_mangle] @@ -372,7 +376,7 @@ pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { } #[no_mangle] -pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) ->z_slice_map_t { +pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> z_slice_map_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/payload.rs b/src/payload.rs index 582f65408..530fbf358 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -133,12 +133,13 @@ impl ZSliceBuffer for z_slice_t { fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.start, self.len) } } - fn as_mut_slice(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.start as *mut u8, self.len) } - } fn as_any(&self) -> &dyn Any { self } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } } /// Encodes byte sequence by aliasing. From a0e26653bc9d3a2d6922f61e57eaf0c58e40e2ce Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 24 Apr 2024 01:21:37 +0200 Subject: [PATCH 055/377] removed ref to local zenoh in build-resources --- build-resources/opaque-types/Cargo.lock | 181 ++++++++++++++++++++++++ build-resources/opaque-types/Cargo.toml | 8 +- 2 files changed, 183 insertions(+), 6 deletions(-) diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index 87d494976..ec5cafe8e 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -313,6 +313,9 @@ name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -423,6 +426,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crossbeam-utils" version = "0.8.19" @@ -989,6 +1007,15 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lockfree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ee94b5ad113c7cb98c5a040f783d0952ee4fe100993881d1673c2cb002dd23" +dependencies = [ + "owned-alloc", +] + [[package]] name = "log" version = "0.4.21" @@ -1173,6 +1200,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "owned-alloc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30fceb411f9a12ff9222c5f824026be368ff15dc2f13468d850c7d3f502205d6" + [[package]] name = "parking" version = "2.2.0" @@ -1380,6 +1413,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.79" @@ -1517,6 +1559,18 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64", + "bitflags 2.5.0", + "serde", + "serde_derive", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1590,6 +1644,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + [[package]] name = "ryu" version = "1.0.17" @@ -1731,6 +1791,12 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + [[package]] name = "sha3" version = "0.10.8" @@ -1831,6 +1897,42 @@ dependencies = [ "lock_api", ] +[[package]] +name = "stabby" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ec04c5825384722310b6a1fd83023bee0bfdc838f7aa3069f0a59e10203836b" +dependencies = [ + "lazy_static", + "rustversion", + "stabby-abi", +] + +[[package]] +name = "stabby-abi" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976322da1deb6cc64a8406fd24378b840b1962acaac1978a993131c3838d81b3" +dependencies = [ + "libc", + "rustversion", + "sha2-const-stable", + "stabby-macros", +] + +[[package]] +name = "stabby-macros" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736712a13ab37b1fa6e073831efca751bbcb31033af4d7308bd5d9d605939183" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "rand", + "syn 1.0.109", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1897,6 +1999,20 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "thread-priority" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72cb4958060ee2d9540cef68bb3871fd1e547037772c7fe7650d5d1cbec53b3" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "log", + "rustversion", + "winapi", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -1959,6 +2075,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.40" @@ -2461,9 +2594,19 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "zenoh" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "ahash", "async-trait", @@ -2519,6 +2662,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "zenoh-collections", ] @@ -2526,6 +2670,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "serde", "tracing", @@ -2538,10 +2683,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" [[package]] name = "zenoh-config" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "flume", "json5", @@ -2561,6 +2708,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-global-executor", "lazy_static", @@ -2572,6 +2720,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "aes", "hmac", @@ -2584,6 +2733,7 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "bincode", "flume", @@ -2595,12 +2745,14 @@ dependencies = [ "tokio", "tracing", "zenoh", + "zenoh-macros", "zenoh-util", ] [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "hashbrown 0.14.3", "keyed-set", @@ -2614,6 +2766,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "zenoh-config", @@ -2625,6 +2778,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "flume", @@ -2647,6 +2801,7 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "proc-macro2", "quote", @@ -2657,6 +2812,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "const_format", "libloading", @@ -2672,6 +2828,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "const_format", "rand", @@ -2686,6 +2843,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "anyhow", ] @@ -2693,10 +2851,16 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "futures", "lazy_static", + "libc", + "ron", + "serde", "tokio", + "zenoh-collections", + "zenoh-macros", "zenoh-protocol", "zenoh-result", ] @@ -2704,17 +2868,31 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ + "async-trait", + "bincode", + "crc", + "lazy_static", + "lockfree", + "num-traits", + "rand", "serde", "shared_memory", + "stabby", + "thread-priority", + "tokio", "tracing", "zenoh-buffers", + "zenoh-core", + "zenoh-macros", "zenoh-result", ] [[package]] name = "zenoh-sync" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "event-listener 4.0.3", "futures", @@ -2728,6 +2906,7 @@ dependencies = [ [[package]] name = "zenoh-task" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "futures", "tokio", @@ -2740,6 +2919,7 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "flume", @@ -2771,6 +2951,7 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-std", "async-trait", diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml index a1c020ed4..4d976ea98 100644 --- a/build-resources/opaque-types/Cargo.toml +++ b/build-resources/opaque-types/Cargo.toml @@ -7,10 +7,6 @@ edition = "2021" [dependencies] # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -# zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } const_format = "0.2.32" -zenoh = { path = "../../../zenoh/zenoh", features = [ - "shared-memory", - "unstable", -], default-features = false } -zenoh-ext = { path = "../../../zenoh/zenoh-ext", features = ["unstable"] } From c9cedafea83068239ce0e806922f23253b412e26 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 24 Apr 2024 10:34:02 +0200 Subject: [PATCH 056/377] z_get/z_delete examples compile --- examples/z_delete.c | 12 ++++++++---- examples/z_get.c | 36 ++++++++++++++++++++---------------- include/zenoh_commons.h | 4 ++-- include/zenoh_macros.h | 10 +++------- src/put.rs | 14 ++++++++------ 5 files changed, 41 insertions(+), 35 deletions(-) diff --git a/examples/z_delete.c b/examples/z_delete.c index 5000444bc..6f364dc80 100644 --- a/examples/z_delete.c +++ b/examples/z_delete.c @@ -21,7 +21,8 @@ int main(int argc, char **argv) { if (argc > 1) keyexpr = argv[1]; - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 3) { if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { printf( @@ -33,19 +34,22 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } printf("Deleting resources matching '%s'...\n", keyexpr); z_delete_options_t options = z_delete_options_default(); - int res = z_delete(z_loan(s), z_keyexpr(keyexpr), &options); + z_owned_keyexpr_t ke; + z_keyexpr(&ke, keyexpr); + int res = z_delete(z_loan(s), z_loan(ke), &options); if (res < 0) { printf("Delete failed...\n"); } + z_keyexpr_drop(z_move(ke)); z_close(z_move(s)); return 0; } diff --git a/examples/z_get.c b/examples/z_get.c index d8f90b35e..90291189c 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -30,12 +30,13 @@ int main(int argc, char **argv) { // Do nothing break; } - z_keyexpr_t keyexpr = z_keyexpr(expr); - if (!z_check(keyexpr)) { + z_owned_keyexpr_t keyexpr; + if (z_keyexpr(&keyexpr, expr) < 0) { printf("%s is not a valid key expression", expr); exit(-1); } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 3) { if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { printf( @@ -47,8 +48,8 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (!z_open(&s, z_move(config))) { printf("Unable to open session!\n"); exit(-1); } @@ -56,25 +57,28 @@ int main(int argc, char **argv) { printf("Sending Query '%s'...\n", expr); z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get_options_t opts = z_get_options_default(); + z_owned_bytes_t payload; if (value != NULL) { - opts.payload = z_bytes_encode_from_string(value); + z_bytes_encode_from_string(&payload, value); + opts.payload = &payload; } - z_get(z_loan(s), keyexpr, "", z_move(channel.send), + z_get(z_loan(s), z_loan(keyexpr), "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate - z_owned_reply_t reply = z_reply_null(); - z_owned_str_t payload_value = z_str_null(); + z_owned_reply_t reply; + z_owned_str_t reply_str; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { - if (z_reply_is_ok(&reply)) { - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); - printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); - z_drop(z_move(payload_value)); - z_drop(z_move(keystr)); + if (z_reply_is_ok(z_loan(reply))) { + z_sample_t sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_bytes_decode_into_string(z_sample_payload(&sample), &reply_str); + printf(">> Received ('%s': '%s')\n", z_loan(key_str), z_loan(reply_str)); + z_drop(z_move(reply_str)); + z_drop(z_move(key_str)); } else { printf("Received an error\n"); } } + z_drop(z_move(keyexpr)); z_drop(z_move(reply)); z_drop(z_move(channel)); z_close(z_move(s)); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 88a84d4dd..88bf8cae1 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1218,14 +1218,14 @@ z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, * Parameters: * session: The zenoh session. * key_expr: The key expression to delete. - * options: The put options. + * options: The delete options. * Returns: * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API z_error_t z_delete(struct z_session_t session, struct z_keyexpr_t key_expr, - struct z_delete_options_t opts); + struct z_delete_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 69f89de72..531bf095c 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -17,6 +17,7 @@ z_owned_slice_t : z_slice_loan, \ z_owned_bytes_t : z_bytes_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ + z_owned_reply_t : z_owned_reply_t, \ z_owned_mutex_t : z_mutex_loan, \ z_condvar_t : z_condvar_loan, \ z_owned_bytes_reader_t : z_bytes_reader_loan \ @@ -93,11 +94,9 @@ _Generic((x), z_owned_session_t : z_session_check, \ z_owned_publisher_t : z_publisher_check, \ z_owned_keyexpr_t : z_keyexpr_check, \ - z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ z_owned_subscriber_t : z_subscriber_check, \ - z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ z_owned_encoding_t : z_encoding_check, \ z_owned_reply_t : z_reply_check, \ @@ -109,9 +108,9 @@ z_owned_bytes_t : z_bytes_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ ze_owned_publication_cache_t : ze_publication_cache_check, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_check \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_check,\ z_owned_mutex_t : z_mutex_check, \ - z_owned_condvar_t : z_owned_condar_check, \ + z_owned_condvar_t : z_condvar_check, \ z_owned_task_t : z_task_check \ )(&x) @@ -211,7 +210,6 @@ template<> inline int8_t z_drop(z_owned_publisher_t* v) { return z_undeclare_pub template<> inline void z_drop(z_owned_keyexpr_t* v) { z_keyexpr_drop(v); } template<> inline void z_drop(z_owned_config_t* v) { z_config_drop(v); } template<> inline void z_drop(z_owned_scouting_config_t* v) { z_scouting_config_drop(v); } -template<> inline int8_t z_drop(z_owned_pull_subscriber_t* v) { return z_undeclare_pull_subscriber(v); } template<> inline int8_t z_drop(z_owned_subscriber_t* v) { return z_undeclare_subscriber(v); } template<> inline int8_t z_drop(z_owned_queryable_t* v) { return z_undeclare_queryable(v); } template<> inline void z_drop(z_owned_encoding_t* v) { z_encoding_drop(v); } @@ -271,13 +269,11 @@ inline void z_null(z_owned_task_t& v) { v = z_task_null(); } inline bool z_check(const z_owned_session_t& v) { return z_session_check(&v); } inline bool z_check(const z_owned_publisher_t& v) { return z_publisher_check(&v); } inline bool z_check(const z_owned_keyexpr_t& v) { return z_keyexpr_check(&v); } -inline bool z_check(const z_keyexpr_t& v) { return z_keyexpr_is_initialized(&v); } inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } inline bool z_check(const z_owned_bytes_t& v) { return z_slice_check(&v); } inline bool z_check(const z_owned_bytes_reader_t& v) { return z_bytes_reader_check(&v); } inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } -inline bool z_check(const z_owned_pull_subscriber_t& v) { return z_pull_subscriber_check(&v); } inline bool z_check(const z_owned_queryable_t& v) { return z_queryable_check(&v); } inline bool z_check(const z_owned_encoding_t& v) { return z_encoding_check(&v); } inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } diff --git a/src/put.rs b/src/put.rs index 8bc9505d1..728499034 100644 --- a/src/put.rs +++ b/src/put.rs @@ -129,7 +129,7 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { /// Parameters: /// session: The zenoh session. /// key_expr: The key expression to delete. -/// options: The put options. +/// options: The delete options. /// Returns: /// ``0`` in case of success, negative values in case of failure. #[no_mangle] @@ -137,14 +137,16 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { pub extern "C" fn z_delete( session: z_session_t, key_expr: z_keyexpr_t, - opts: z_delete_options_t, + options: Option<&mut z_delete_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let del = session - .delete(key_expr) - .congestion_control(opts.congestion_control.into()) - .priority(opts.priority.into()); + let mut del = session + .delete(key_expr); + if let Some(options) = options { + del = del.congestion_control(options.congestion_control.into()) + .priority(options.priority.into()); + } match del.res_sync() { Err(e) => { From 1b54f3f82c53b375e995e777c632b405508d8769 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 24 Apr 2024 11:10:39 +0200 Subject: [PATCH 057/377] z_get_liveliness example builds --- examples/z_get_liveliness.c | 27 +++++++++++++++------------ include/zenoh_commons.h | 7 ++++++- include/zenoh_macros.h | 5 ++--- src/collections.rs | 1 + src/get.rs | 14 ++++++++++---- src/liveliness.rs | 6 ++++-- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/examples/z_get_liveliness.c b/examples/z_get_liveliness.c index 9a00f3ca3..08ed225f1 100644 --- a/examples/z_get_liveliness.c +++ b/examples/z_get_liveliness.c @@ -22,13 +22,14 @@ int main(int argc, char **argv) { expr = argv[1]; } - z_keyexpr_t keyexpr = z_keyexpr(expr); - if (!z_check(keyexpr)) { + z_owned_keyexpr_t keyexpr; + if (z_keyexpr(&keyexpr, expr) < 0) { printf("%s is not a valid key expression\n", expr); exit(-1); } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { printf( @@ -39,27 +40,29 @@ int main(int argc, char **argv) { } } + z_owned_session_t s; printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } printf("Sending liveliness query '%s'...\n", expr); z_owned_reply_channel_t channel = zc_reply_fifo_new(16); - zc_liveliness_get(z_loan(s), keyexpr, z_move(channel.send), NULL); - z_owned_reply_t reply = z_reply_null(); + zc_liveliness_get(z_loan(s), z_loan(keyexpr), z_move(channel.send), NULL); + z_owned_reply_t reply; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { - if (z_reply_is_ok(&reply)) { - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - printf(">> Alive token ('%s')\n", z_loan(keystr)); - z_drop(z_move(keystr)); + if (z_reply_is_ok(z_loan(reply))) { + z_sample_t sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + printf(">> Alive token ('%s')\n", z_loan(key_str)); + z_drop(z_move(key_str)); } else { printf("Received an error\n"); } } + + z_drop(z_move(keyexpr)); z_drop(z_move(reply)); z_drop(z_move(channel)); z_close(z_move(s)); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 88bf8cae1..08fe40b04 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1753,6 +1753,7 @@ struct z_value_t z_reply_err(struct z_reply_t reply); */ ZENOHC_API bool z_reply_is_ok(struct z_reply_t reply); +ZENOHC_API struct z_reply_t z_reply_loan(struct z_owned_reply_t *this_); /** * Returns an invalidated :c:type:`z_owned_reply_t`. * @@ -1857,6 +1858,10 @@ ZENOHC_API int8_t z_sleep_us(size_t time); */ ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); +/** + * Frees `b` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_slice_drop(struct z_owned_slice_t *b); /** * Returns the gravestone value for `z_slice_t` */ @@ -2167,7 +2172,7 @@ ZENOHC_API z_error_t zc_liveliness_get(struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_reply_t *callback, - struct zc_liveliness_get_options_t options); + struct zc_liveliness_get_options_t *options); /** * The gravestone value for `zc_liveliness_get_options_t` */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 531bf095c..fbd60560b 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -17,7 +17,7 @@ z_owned_slice_t : z_slice_loan, \ z_owned_bytes_t : z_bytes_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ - z_owned_reply_t : z_owned_reply_t, \ + z_owned_reply_t : z_reply_loan, \ z_owned_mutex_t : z_mutex_loan, \ z_condvar_t : z_condvar_loan, \ z_owned_bytes_reader_t : z_bytes_reader_loan \ @@ -54,8 +54,7 @@ z_owned_bytes_t * : z_bytes_drop, \ z_owned_bytes_reader_t * : z_bytes_reader_drop, \ z_owned_mutex_t * : z_mutex_drop, \ - z_owned_condvar_t * : z_condvar_drop, \ - z_owned_bytes_reader_t * : z_bytes_reader_drop \ + z_owned_condvar_t * : z_condvar_drop \ )(x) #define z_null(x) (*x = \ diff --git a/src/collections.rs b/src/collections.rs index 2b0dc1898..740870321 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -156,6 +156,7 @@ pub unsafe extern "C" fn z_slice_wrap(start: *const u8, len: usize) -> z_slice_t } /// Frees `b` and invalidates it for double-drop safety. +#[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_slice_drop(b: &mut z_owned_slice_t) { if !b.start.is_null() { diff --git a/src/get.rs b/src/get.rs index bdf8ddfa0..8be10c18b 100644 --- a/src/get.rs +++ b/src/get.rs @@ -22,6 +22,7 @@ use zenoh::sample::ValueBuilderTrait; use zenoh::prelude::{ConsolidationMode, Mode, QueryConsolidation, QueryTarget, Reply}; use crate::errors; +use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; @@ -194,17 +195,22 @@ pub unsafe extern "C" fn z_get( /// Frees `reply`, invalidating it for double-drop safety. #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_drop(this: &mut z_owned_reply_t) { +pub extern "C" fn z_reply_drop(this: &mut z_owned_reply_t) { Inplace::drop(this.transmute_mut()) } /// Returns ``true`` if `reply` is valid. #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { +pub extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { this.transmute_ref().is_some() } +#[no_mangle] +pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> z_reply_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() +} + /// The replies consolidation strategy to apply on replies to a :c:func:`z_get`. #[repr(C)] #[derive(Clone, Copy)] diff --git a/src/liveliness.rs b/src/liveliness.rs index f35c1ce22..fed6a9bfc 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -184,7 +184,7 @@ pub extern "C" fn zc_liveliness_get( session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_reply_t, - options: zc_liveliness_get_options_t, + options: Option<&mut zc_liveliness_get_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -193,7 +193,9 @@ pub extern "C" fn zc_liveliness_get( let mut builder = liveliness .get(key_expr) .callback(move |response| z_closure_reply_call(&callback, response.transmute_handle())); - builder = builder.timeout(core::time::Duration::from_millis(options.timeout_ms as u64)); + if let Some(options) = options { + builder = builder.timeout(core::time::Duration::from_millis(options.timeout_ms as u64)); + } match builder.res() { Ok(()) => errors::Z_OK, Err(e) => { From 504a81cdeb45dae780fb55ae65fa14823993869d Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 24 Apr 2024 23:10:53 +0200 Subject: [PATCH 058/377] fixed api to newly-agreed usage of handle pointers --- build-resources/opaque-types/src/lib.rs | 34 +- build.rs | 6 +- include/zenoh_commons.h | 444 ++++++++++++------------ include/zenoh_concrete.h | 5 +- src/closures/query_channel.rs | 8 +- src/closures/query_closure.rs | 10 +- src/closures/reply_closure.rs | 10 +- src/closures/response_channel.rs | 4 +- src/closures/sample_closure.rs | 10 +- src/collections.rs | 118 ++++--- src/commons.rs | 57 +-- src/config.rs | 46 ++- src/errors.rs | 1 + src/get.rs | 41 +-- src/keyexpr.rs | 88 ++--- src/liveliness.rs | 25 +- src/payload.rs | 30 +- src/publisher.rs | 46 +-- src/put.rs | 20 +- src/queryable.rs | 55 ++- src/querying_subscriber.rs | 16 +- src/scouting.rs | 36 +- src/session.rs | 20 +- src/subscriber.rs | 12 +- src/transmute.rs | 27 +- 25 files changed, 588 insertions(+), 581 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 9e9f7d434..3781c062c 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -44,29 +44,29 @@ macro_rules! get_opaque_type_data { /// To minimize copies and reallocations, Zenoh may provide you data in split buffers. get_opaque_type_data!(Option, z_owned_bytes_t); /// A loaned payload. -get_opaque_type_data!(&'static ZBytes, z_bytes_t); +get_opaque_type_data!(ZBytes, z_bytes_t); /// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher get_opaque_type_data!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); -get_opaque_type_data!(&'static HashMap, Cow<'static, [u8]>>, z_slice_map_t); +get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_slice_map_t); /// An owned sample. /// /// This is a read only type that can only be constructed by cloning a `z_sample_t`. /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. get_opaque_type_data!(Option, zc_owned_sample_t); -get_opaque_type_data!(&'static Sample, z_sample_t); +get_opaque_type_data!(Sample, z_sample_t); /// A reader for payload data. get_opaque_type_data!(Option>, z_owned_bytes_reader_t); -get_opaque_type_data!(&'static ZBytesReader<'static>, z_bytes_reader_t); +get_opaque_type_data!(ZBytesReader<'static>, z_bytes_reader_t); /// The encoding of a payload, in a MIME-like format. /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. -get_opaque_type_data!(&'static Encoding, z_encoding_t); +get_opaque_type_data!(Encoding, z_encoding_t); get_opaque_type_data!(Encoding, z_owned_encoding_t); /// An owned reply to a :c:func:`z_get`. @@ -77,18 +77,18 @@ get_opaque_type_data!(Encoding, z_owned_encoding_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. get_opaque_type_data!(Option, z_owned_reply_t); -get_opaque_type_data!(&'static Reply, z_reply_t); +get_opaque_type_data!(Reply, z_reply_t); /// A zenoh value. get_opaque_type_data!(Value, z_owned_value_t); -get_opaque_type_data!(&'static Value, z_value_t); +get_opaque_type_data!(Value, z_value_t); // Loaned variant of a Query received by a Queryable. /// /// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. /// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. get_opaque_type_data!(Option, z_owned_query_t); -get_opaque_type_data!(&'static Query, z_query_t); +get_opaque_type_data!(Query, z_query_t); /// An owned zenoh queryable. /// @@ -101,7 +101,7 @@ get_opaque_type_data!(&'static Query, z_query_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_queryable_t); -get_opaque_type_data!(&'static Queryable<'static, ()>, z_queryable_t); +get_opaque_type_data!(Queryable<'static, ()>, z_queryable_t); /// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. /// @@ -114,7 +114,7 @@ get_opaque_type_data!(&'static Queryable<'static, ()>, z_queryable_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); -get_opaque_type_data!(&'static (zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); +get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); /// A zenoh-allocated key expression. /// @@ -151,7 +151,7 @@ get_opaque_type_data!(Option>, z_owned_keyexpr_t); /// /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. -get_opaque_type_data!(&'static KeyExpr<'_>, z_keyexpr_t); +get_opaque_type_data!(KeyExpr<'_>, z_keyexpr_t); /// An owned zenoh session. /// @@ -164,7 +164,7 @@ get_opaque_type_data!(&'static KeyExpr<'_>, z_keyexpr_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_session_t); -get_opaque_type_data!(&'static Session, z_session_t); +get_opaque_type_data!(Session, z_session_t); /// An owned zenoh configuration. /// @@ -176,9 +176,9 @@ get_opaque_type_data!(&'static Session, z_session_t); /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -get_opaque_type_data!(Option>, z_owned_config_t); +get_opaque_type_data!(Option, z_owned_config_t); /// A loaned zenoh configuration. -get_opaque_type_data!(&'static Config, z_config_t); +get_opaque_type_data!(Config, z_config_t); /// Represents a Zenoh ID. /// @@ -198,7 +198,7 @@ get_opaque_type_data!(Timestamp, z_timestamp_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_publisher_t); -get_opaque_type_data!(&'static Publisher<'static>, z_publisher_t); +get_opaque_type_data!(Publisher<'static>, z_publisher_t); /// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. /// @@ -224,7 +224,7 @@ get_opaque_type_data!(Option>, zcu_own /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_subscriber_t); -get_opaque_type_data!(&'static Subscriber<'static, ()>, z_subscriber_t); +get_opaque_type_data!(Subscriber<'static, ()>, z_subscriber_t); /// A liveliness token that can be used to provide the network with information about connectivity to its /// declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key @@ -232,7 +232,7 @@ get_opaque_type_data!(&'static Subscriber<'static, ()>, z_subscriber_t); /// /// A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. get_opaque_type_data!(Option>, zc_owned_liveliness_token_t); -get_opaque_type_data!(&'static LivelinessToken<'static>, zc_liveliness_token_t); +get_opaque_type_data!(LivelinessToken<'static>, zc_liveliness_token_t); /// An owned zenoh publication_cache. diff --git a/build.rs b/build.rs index 50668d5a6..01fc61a4a 100644 --- a/build.rs +++ b/build.rs @@ -85,6 +85,9 @@ fn produce_opaque_types_data() -> PathBuf { } fn generate_opaque_types() { + let type_to_inner_field_name = HashMap::from([ + ("z_id_t", "id"), + ]); let current_folder = get_build_rs_path(); let path_in = produce_opaque_types_data(); let path_out = current_folder.join("./src/opaque_types/mod.rs"); @@ -98,11 +101,12 @@ fn generate_opaque_types() { let re = Regex::new(r"type: (\w+), align: (\d+), size: (\d+)").unwrap(); for (_, [type_name, align, size]) in re.captures_iter(&data_in).map(|c| c.extract()) { + let inner_field_name = type_to_inner_field_name.get(type_name).unwrap_or(&"_0"); let s = format!( "#[derive(Copy, Clone)] #[repr(C, align({align}))] pub struct {type_name} {{ - _0: [u8; {size}], + {inner_field_name}: [u8; {size}], }} " ); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 08fe40b04..0a3a59df7 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -122,15 +122,15 @@ typedef enum zcu_reply_keyexpr_t { typedef struct ALIGN(8) z_owned_bytes_t { uint8_t _0[40]; } z_owned_bytes_t; -typedef int8_t z_error_t; /** * A loaned payload. */ typedef struct ALIGN(8) z_bytes_t { - uint8_t _0[8]; + uint8_t _0[40]; } z_bytes_t; +typedef int8_t z_error_t; typedef struct z_owned_slice_t { - uint8_t *start; + const uint8_t *start; size_t len; } z_owned_slice_t; /** @@ -160,7 +160,7 @@ typedef struct z_slice_t { size_t len; } z_slice_t; typedef struct ALIGN(8) z_slice_map_t { - uint8_t _0[8]; + uint8_t _0[48]; } z_slice_map_t; /** * A reader for payload data. @@ -169,7 +169,7 @@ typedef struct ALIGN(8) z_owned_bytes_reader_t { uint8_t _0[24]; } z_owned_bytes_reader_t; typedef struct ALIGN(8) z_bytes_reader_t { - uint8_t _0[8]; + uint8_t _0[24]; } z_bytes_reader_t; /** * Clock @@ -185,7 +185,7 @@ typedef struct z_clock_t { * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. */ typedef struct ALIGN(1) z_id_t { - uint8_t _0[16]; + uint8_t id[16]; } z_id_t; /** * An owned array of owned, zenoh allocated, NULL terminated strings. @@ -287,11 +287,11 @@ typedef struct z_owned_closure_owned_query_t { */ typedef struct z_owned_closure_query_t { void *context; - void (*call)(struct z_query_t, void *context); + void (*call)(const struct z_query_t*, void *context); void (*drop)(void*); } z_owned_closure_query_t; typedef struct ALIGN(8) z_reply_t { - uint8_t _0[8]; + uint8_t _0[256]; } z_reply_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: @@ -311,11 +311,11 @@ typedef struct ALIGN(8) z_reply_t { */ typedef struct z_owned_closure_reply_t { void *context; - void (*call)(struct z_reply_t, void*); + void (*call)(const struct z_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; typedef struct ALIGN(8) z_sample_t { - uint8_t _0[8]; + uint8_t _0[240]; } z_sample_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. @@ -335,7 +335,7 @@ typedef struct ALIGN(8) z_sample_t { */ typedef struct z_owned_closure_sample_t { void *context; - void (*call)(struct z_sample_t, void *context); + void (*call)(const struct z_sample_t*, void *context); void (*drop)(void*); } z_owned_closure_sample_t; /** @@ -381,13 +381,13 @@ typedef struct ALIGN(8) z_mutex_t { * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. */ typedef struct ALIGN(8) z_owned_config_t { - uint8_t _0[8]; + uint8_t _0[1544]; } z_owned_config_t; /** * A loaned zenoh configuration. */ typedef struct ALIGN(8) z_config_t { - uint8_t _0[8]; + uint8_t _0[1544]; } z_config_t; /** * A zenoh-allocated key expression. @@ -431,19 +431,8 @@ typedef struct ALIGN(8) z_owned_keyexpr_t { * both for local processing and network-wise. */ typedef struct ALIGN(8) z_keyexpr_t { - uint8_t _0[8]; + uint8_t _0[32]; } z_keyexpr_t; -/** - * Options passed to the :c:func:`z_declare_publisher` function. - * - * Members: - * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. - * z_priority_t priority: The priority of messages from this publisher. - */ -typedef struct z_publisher_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_publisher_options_t; /** * An owned zenoh publisher. * @@ -459,6 +448,17 @@ typedef struct z_publisher_options_t { typedef struct ALIGN(8) z_owned_publisher_t { uint8_t _0[56]; } z_owned_publisher_t; +/** + * Options passed to the :c:func:`z_declare_publisher` function. + * + * Members: + * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. + * z_priority_t priority: The priority of messages from this publisher. + */ +typedef struct z_publisher_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_publisher_options_t; /** * Options passed to the :c:func:`z_declare_queryable` function. * @@ -493,7 +493,7 @@ typedef struct ALIGN(8) z_owned_encoding_t { * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. */ typedef struct ALIGN(8) z_encoding_t { - uint8_t _0[8]; + uint8_t _0[48]; } z_encoding_t; /** * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. @@ -549,7 +549,7 @@ typedef struct ALIGN(8) z_owned_mutex_t { uint8_t _0[32]; } z_owned_mutex_t; typedef struct ALIGN(8) z_publisher_t { - uint8_t _0[8]; + uint8_t _0[56]; } z_publisher_t; /** * Represents the set of options that can be applied to the delete operation by a previously declared publisher, @@ -622,7 +622,7 @@ typedef struct z_query_reply_options_t { struct z_owned_bytes_t *attachment; } z_query_reply_options_t; typedef struct ALIGN(8) z_value_t { - uint8_t _0[8]; + uint8_t _0[88]; } z_value_t; /** * An owned reply to a :c:func:`z_get`. @@ -661,6 +661,15 @@ typedef struct z_owned_reply_channel_t { struct z_owned_closure_reply_t send; struct z_owned_reply_channel_closure_t recv; } z_owned_reply_channel_t; +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[240]; +} zc_owned_sample_t; typedef struct ALIGN(8) z_timestamp_t { uint8_t _0[24]; } z_timestamp_t; @@ -677,9 +686,11 @@ typedef struct z_owned_scouting_config_t { * * Returning `true` is treated as `continue`. */ -typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); +typedef bool (*z_slice_map_iter_body_t)(const struct z_slice_t *key, + const struct z_slice_t *value, + void *context); typedef struct ALIGN(8) z_subscriber_t { - uint8_t _0[8]; + uint8_t _0[32]; } z_subscriber_t; typedef struct ALIGN(8) z_owned_task_t { uint8_t _0[24]; @@ -722,15 +733,6 @@ typedef struct ALIGN(8) zc_owned_liveliness_token_t { typedef struct zc_liveliness_get_options_t { uint32_t timeout_ms; } zc_liveliness_get_options_t; -/** - * An owned sample. - * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. - */ -typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[240]; -} zc_owned_sample_t; /** * A struct that indicates if there exist Subscribers matching the Publisher's key expression. * @@ -848,7 +850,7 @@ typedef struct ze_querying_subscriber_options_t { uint64_t query_timeout_ms; } ze_querying_subscriber_options_t; typedef struct ALIGN(8) ze_querying_subscriber_t { - uint8_t _0[8]; + uint8_t _0[64]; } ze_querying_subscriber_t; ZENOHC_API extern const unsigned int Z_ROUTER; ZENOHC_API extern const unsigned int Z_PEER; @@ -871,12 +873,12 @@ ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); /** * Increments the payload's reference count, returning an owned version of it. */ -ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_bytes_t *dst); +ZENOHC_API void z_bytes_clone(const struct z_bytes_t *src, struct z_owned_bytes_t *dst); /** * Decodes payload into owned bytes */ ZENOHC_API -z_error_t z_bytes_decode_into_bytes(struct z_bytes_t payload, +z_error_t z_bytes_decode_into_bytes(const struct z_bytes_t *payload, struct z_owned_slice_t *dst); /** * Decodes payload into bytes map. @@ -888,7 +890,7 @@ z_error_t z_bytes_decode_into_bytes_map(struct z_bytes_t payload, * Decodes payload into null-terminated string. */ ZENOHC_API -z_error_t z_bytes_decode_into_string(struct z_bytes_t payload, +z_error_t z_bytes_decode_into_string(const struct z_bytes_t *payload, struct z_owned_str_t *dst); /** * Decrements the payload's reference counter, destroying it if applicable. @@ -899,13 +901,15 @@ ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); /** * Encodes byte sequence by aliasing. */ -ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, struct z_slice_t bytes); +ZENOHC_API +void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, + const struct z_slice_t *bytes); /** * Encodes bytes map by copying. */ ZENOHC_API void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, - struct z_slice_map_t bytes_map); + const struct z_slice_map_t *bytes_map); /** * Encodes a null-terminated string by aliasing. */ @@ -913,18 +917,19 @@ ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const /** * Returns total number bytes in the payload. */ -ZENOHC_API size_t z_bytes_len(struct z_bytes_t payload); +ZENOHC_API size_t z_bytes_len(const struct z_bytes_t *payload); /** * Loans the payload, allowing you to call functions that only need a loan of it. */ -ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); +ZENOHC_API const struct z_bytes_t *z_bytes_loan(const struct z_owned_bytes_t *payload); /** * The gravestone value for `z_owned_bytes_t`. */ ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_reader_t *this_); ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_reader_t *this_); -ZENOHC_API struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); +ZENOHC_API +const struct z_bytes_reader_t *z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); /** * Creates a reader for the specified `payload`. * @@ -939,7 +944,7 @@ ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. */ ZENOHC_API -size_t z_bytes_reader_read(struct z_bytes_reader_t this_, +size_t z_bytes_reader_read(const struct z_bytes_reader_t *this_, uint8_t *dest, size_t len); /** @@ -949,14 +954,14 @@ size_t z_bytes_reader_read(struct z_bytes_reader_t this_, * Return ​0​ upon success, negative error code otherwise. */ ZENOHC_API -z_error_t z_bytes_reader_seek(struct z_bytes_reader_t this_, +z_error_t z_bytes_reader_seek(const struct z_bytes_reader_t *this_, int64_t offset, int origin); /** * Returns the read position indicator. * Returns read position indicator on success or -1L if failure occurs. */ -ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t this_); +ZENOHC_API int64_t z_bytes_reader_tell(const struct z_bytes_reader_t *this_); ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); @@ -967,7 +972,7 @@ ZENOHC_API struct z_clock_t z_clock_now(void); * Returns a negative value if an error occured while closing the session. * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); +ZENOHC_API z_error_t z_close(struct z_owned_session_t *session); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1001,7 +1006,7 @@ ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void) */ ZENOHC_API void z_closure_query_call(const struct z_owned_closure_query_t *closure, - struct z_query_t query); + const struct z_query_t *query); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1015,7 +1020,7 @@ ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); */ ZENOHC_API void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, - struct z_reply_t reply); + const struct z_reply_t *reply); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1029,7 +1034,7 @@ ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); */ ZENOHC_API void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - struct z_sample_t sample); + const struct z_sample_t *sample); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1068,9 +1073,9 @@ ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); * If `peer` is not null, it is added to the configuration as remote peer. */ ZENOHC_API -z_error_t z_config_client(const char *const *peers, - size_t n_peers, - struct z_owned_config_t *this_); +z_error_t z_config_client(struct z_owned_config_t *this_, + const char *const *peers, + size_t n_peers); /** * Clones the config. */ @@ -1096,7 +1101,7 @@ ZENOHC_API void z_config_drop(struct z_owned_config_t *config); /** * Returns a :c:type:`z_config_t` loaned from `s`. */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *this_); +ZENOHC_API const struct z_config_t *z_config_loan(const struct z_owned_config_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_config_t' type */ @@ -1113,8 +1118,8 @@ ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); */ ZENOHC_API z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr); + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr); /** * Declares a publisher for the given key expression. * @@ -1151,10 +1156,10 @@ z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); */ ZENOHC_API -z_error_t z_declare_publisher(struct z_session_t session, - struct z_keyexpr_t key_expr, - const struct z_publisher_options_t *options, - struct z_owned_publisher_t *this_); +z_error_t z_declare_publisher(struct z_owned_publisher_t *this_, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, + const struct z_publisher_options_t *options); /** * Creates a Queryable for the given key expression. * @@ -1169,8 +1174,8 @@ z_error_t z_declare_publisher(struct z_session_t session, */ ZENOHC_API z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_query_t *callback, struct z_queryable_options_t *options); /** @@ -1208,8 +1213,8 @@ z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, */ ZENOHC_API z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct z_subscriber_options_t *options); /** @@ -1223,13 +1228,13 @@ z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -z_error_t z_delete(struct z_session_t session, - struct z_keyexpr_t key_expr, +z_error_t z_delete(const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_delete_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ -ZENOHC_API struct z_delete_options_t z_delete_options_default(void); +ZENOHC_API void z_delete_options_default(struct z_delete_options_t *this_); /** * Returns ``true`` if `encoding` is valid. */ @@ -1237,7 +1242,7 @@ ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); /** * Constructs a default :c:type:`z_encoding_t`. */ -ZENOHC_API struct z_encoding_t z_encoding_default(void); +ZENOHC_API const struct z_encoding_t *z_encoding_default(void); /** * Frees `encoding`, invalidating it for double-drop safety. */ @@ -1249,7 +1254,7 @@ ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const /** * Returns a :c:type:`z_encoding_t` loaned from `encoding`. */ -ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); +ZENOHC_API const struct z_encoding_t *z_encoding_loan(const struct z_owned_encoding_t *encoding); /** * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type */ @@ -1271,12 +1276,12 @@ ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); * options: additional options for the get. */ ZENOHC_API -z_error_t z_get(struct z_session_t session, - struct z_keyexpr_t key_expr, +z_error_t z_get(const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, const char *parameters, struct z_owned_closure_reply_t *callback, struct z_get_options_t *options); -ZENOHC_API struct z_get_options_t z_get_options_default(void); +ZENOHC_API void z_get_options_default(struct z_get_options_t *this_); /** * Returns ``true`` if `hello` is valid. */ @@ -1288,11 +1293,11 @@ ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); /** * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. */ -ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); +ZENOHC_API const struct z_hello_t *z_hello_loan(const struct z_owned_hello_t *hello); /** * Constructs a gravestone value for hello, useful to steal one from a callback */ -ZENOHC_API struct z_owned_hello_t z_hello_null(void); +ZENOHC_API void z_hello_null(struct z_owned_hello_t *this_); /** * Fetches the Zenoh IDs of all connected peers. * @@ -1327,20 +1332,20 @@ ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); * Constructs a :c:type:`z_keyexpr_t` departing from a string. * It is a loaned key expression that aliases `name`. */ -ZENOHC_API z_error_t z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); +ZENOHC_API z_error_t z_keyexpr(struct z_keyexpr_t *this_, const char *name); /** * Returns the key expression's internal string by aliasing it. * * Currently exclusive to zenoh-c */ -ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); +ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(const struct z_keyexpr_t *ke); /** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. * 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 -z_error_t z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, +z_error_t z_keyexpr_autocanonize(struct z_keyexpr_t *this_, char *name); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. @@ -1379,10 +1384,10 @@ ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); * as this would extremely likely cause bugs. */ ZENOHC_API -z_error_t z_keyexpr_concat(struct z_keyexpr_t left, +z_error_t z_keyexpr_concat(struct z_owned_keyexpr_t *this_, + const struct z_keyexpr_t *left, const char *right_start, - size_t right_len, - struct z_owned_keyexpr_t *this_); + size_t right_len); /** * Frees `keyexpr` and invalidates it for double-drop safety. */ @@ -1390,21 +1395,21 @@ ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); /** * Returns ``0`` if both ``left`` and ``right`` are equal. */ -ZENOHC_API bool z_keyexpr_equals(struct z_keyexpr_t left, struct z_keyexpr_t right); +ZENOHC_API bool z_keyexpr_equals(const struct z_keyexpr_t *left, const struct z_keyexpr_t *right); /** * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set * defined by ``right``. */ ZENOHC_API -bool z_keyexpr_includes(struct z_keyexpr_t left, - struct z_keyexpr_t right); +bool z_keyexpr_includes(const struct z_keyexpr_t *left, + const struct z_keyexpr_t *right); /** * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the * sets defined by ``left`` and ``right``. */ ZENOHC_API -bool z_keyexpr_intersects(struct z_keyexpr_t left, - struct z_keyexpr_t right); +bool z_keyexpr_intersects(const struct z_keyexpr_t *left, + const struct z_keyexpr_t *right); /** * Returns ``0`` if the passed string is a valid (and canon) key expression. * Otherwise returns error value @@ -1415,13 +1420,13 @@ ZENOHC_API z_error_t z_keyexpr_is_canon(const char *start, size_t len); * In case of error, the return value will be set to its invalidated state. */ ZENOHC_API -z_error_t z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right, - struct z_owned_keyexpr_t *this_); +z_error_t z_keyexpr_join(struct z_owned_keyexpr_t *this_, + const struct z_keyexpr_t *left, + const struct z_keyexpr_t *right); /** * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. */ -ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); +ZENOHC_API const struct z_keyexpr_t *z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. */ @@ -1442,15 +1447,15 @@ ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. */ ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, - struct z_keyexpr_t right); +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_keyexpr_t *left, + const struct z_keyexpr_t *right); /** * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. * The user is responsible of droping the returned string using `z_drop` */ -ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); +ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(const struct z_keyexpr_t *ke); /** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: * * - `name` MUST be valid UTF8. * - `name` MUST follow the Key Expression specification, ie: @@ -1462,7 +1467,7 @@ ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); * It is a loaned key expression that aliases `name`. */ ZENOHC_API -void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, +void z_keyexpr_unchecked(struct z_keyexpr_t *this_, const char *name); ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); @@ -1482,7 +1487,7 @@ z_error_t z_open(struct z_owned_session_t *this_, /** * Returns ``true`` if `pub` is valid. */ -ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); +ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *this_); /** * Sends a `DELETE` message onto the publisher's key expression. * @@ -1490,7 +1495,7 @@ ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); * ``0`` in case of success, ``1`` in case of failure. */ ZENOHC_API -z_error_t z_publisher_delete(struct z_publisher_t publisher, +z_error_t z_publisher_delete(const struct z_publisher_t *publisher, struct z_publisher_delete_options_t _options); /** * Constructs the default values for the delete operation via a publisher entity. @@ -1498,15 +1503,15 @@ z_error_t z_publisher_delete(struct z_publisher_t publisher, * Returns: * Returns the constructed :c:type:`z_publisher_delete_options_t`. */ -ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); +ZENOHC_API void z_publisher_delete_options_default(struct z_publisher_delete_options_t *this_); /** * Returns the key expression of the publisher */ -ZENOHC_API struct z_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); +ZENOHC_API const struct z_keyexpr_t *z_publisher_keyexpr(const struct z_publisher_t *publisher); /** * Returns a :c:type:`z_publisher_t` loaned from `p`. */ -ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); +ZENOHC_API const struct z_publisher_t *z_publisher_loan(const struct z_owned_publisher_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type */ @@ -1514,7 +1519,7 @@ ZENOHC_API void z_publisher_null(struct z_owned_publisher_t *this_); /** * Constructs the default value for :c:type:`z_publisher_options_t`. */ -ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); +ZENOHC_API void z_publisher_options_default(struct z_publisher_options_t *this_); /** * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. * @@ -1532,13 +1537,13 @@ ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -z_error_t z_publisher_put(struct z_publisher_t publisher, +z_error_t z_publisher_put(const struct z_publisher_t *publisher, struct z_owned_bytes_t *payload, struct z_publisher_put_options_t *options); /** * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ -ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); +ZENOHC_API void z_publisher_put_options_default(struct z_publisher_put_options_t *this_); /** * Put data, transfering its ownership. * @@ -1555,20 +1560,20 @@ ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void * ``0`` in case of success, negative error values in case of failure. */ ZENOHC_API -z_error_t z_put(struct z_session_t session, - struct z_keyexpr_t key_expr, +z_error_t z_put(const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_bytes_t *payload, struct z_put_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ -ZENOHC_API struct z_put_options_t z_put_options_default(void); +ZENOHC_API void z_put_options_default(struct z_put_options_t *this_); /** * Gets the attachment to the query by aliasing. * - * Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. + * Returns NULL if query does not contain an attachment. */ -ZENOHC_API struct z_bytes_t z_query_attachment(struct z_query_t query); +ZENOHC_API const struct z_bytes_t *z_query_attachment(const struct z_query_t *query); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1601,8 +1606,8 @@ bool z_query_check(const struct z_owned_query_t *query); * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). */ ZENOHC_API -void z_query_clone(struct z_owned_query_t *this_, - struct z_query_t query); +void z_query_clone(const struct z_query_t *this_, + struct z_owned_query_t *dst); /** * Automatic query consolidation strategy selection. * @@ -1637,17 +1642,21 @@ ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); */ ZENOHC_API void z_query_drop(struct z_owned_query_t *this_); +/** + * Checks if query contains a payload value. + */ +ZENOHC_API bool z_query_has_value(const struct z_query_t *query); /** * Get a query's key by aliasing it. */ -ZENOHC_API struct z_keyexpr_t z_query_keyexpr(struct z_query_t query); +ZENOHC_API const struct z_keyexpr_t *z_query_keyexpr(const struct z_query_t *query); /** * Aliases the query. * * This function may not be called with the null pointer, but can be called with the gravestone value. */ ZENOHC_API -struct z_query_t z_query_loan(const struct z_owned_query_t *this_); +const struct z_query_t *z_query_loan(const struct z_owned_query_t *this_); /** * The gravestone value of `z_owned_query_t`. */ @@ -1656,7 +1665,7 @@ ZENOHC_API void z_query_null(struct z_owned_query_t *this_); * Get a query's `value selector `_ by aliasing it. */ ZENOHC_API -struct z_slice_t z_query_parameters(struct z_query_t query); +struct z_slice_t z_query_parameters(const struct z_query_t *query); /** * Send a reply to a query. * @@ -1681,7 +1690,7 @@ z_error_t z_query_reply(struct z_query_t query, /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ -ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); +ZENOHC_API void z_query_reply_options_default(struct z_query_reply_options_t *this_); /** * Create a default :c:type:`z_query_target_t`. */ @@ -1693,7 +1702,7 @@ ZENOHC_API enum z_query_target_t z_query_target_default(void); * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. */ ZENOHC_API -struct z_value_t z_query_value(struct z_query_t query); +const struct z_value_t *z_query_value(const struct z_query_t *query); /** * Returns ``true`` if `qable` is valid. */ @@ -1705,7 +1714,7 @@ ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ -ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); +ZENOHC_API void z_queryable_options_default(struct z_queryable_options_t *this_); ZENOHC_API void z_random_fill(void *buf, size_t len); ZENOHC_API uint16_t z_random_u16(void); ZENOHC_API uint32_t z_random_u32(void); @@ -1734,7 +1743,7 @@ ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); * Returns ``true`` if `reply` is valid. */ ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); -ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, struct z_reply_t reply); +ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, const struct z_reply_t *reply); /** * Frees `reply`, invalidating it for double-drop safety. */ @@ -1742,18 +1751,18 @@ ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); /** * Yields the contents of the reply by asserting it indicates a failure. * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. + * Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). */ ZENOHC_API -struct z_value_t z_reply_err(struct z_reply_t reply); +const struct z_value_t *z_reply_err(const struct z_reply_t *reply); /** * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. * * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. */ ZENOHC_API -bool z_reply_is_ok(struct z_reply_t reply); -ZENOHC_API struct z_reply_t z_reply_loan(struct z_owned_reply_t *this_); +bool z_reply_is_ok(const struct z_reply_t *reply); +ZENOHC_API const struct z_reply_t *z_reply_loan(struct z_owned_reply_t *this_); /** * Returns an invalidated :c:type:`z_owned_reply_t`. * @@ -1767,32 +1776,42 @@ ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); /** * Yields the contents of the reply by asserting it indicates a success. * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. + * Returns null if reply does not contains a sample (i. e. if :c:func:`z_reply_is_ok` returns ``false``). */ ZENOHC_API -struct z_sample_t z_reply_ok(struct z_reply_t reply); +const struct z_sample_t *z_reply_ok(const struct z_reply_t *reply); /** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) * Gets sample's attachment. * - * Before calling this function, ensure that `zc_sample_has_attachment` returns true + * Returns NULL if sample does not contain an attachement. */ -ZENOHC_API struct z_bytes_t z_sample_attachment(struct z_sample_t sample); +ZENOHC_API const struct z_bytes_t *z_sample_attachment(const struct z_sample_t *sample); /** - * The encoding of the payload. + * Returns `true` if `sample` is valid. + * + * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * unless the value has been dropped already. */ -ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); +ZENOHC_API +bool z_sample_check(const struct zc_owned_sample_t *sample); /** - * The qos with which the sample was received. - * TODO: split to methods (priority, congestion_control, express) - * Checks if sample contains an attachment. + * Clone a sample in the cheapest way available. */ -ZENOHC_API bool z_sample_has_attachment(struct z_sample_t sample); +ZENOHC_API void z_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); +ZENOHC_API enum z_congestion_control_t z_sample_congestion_control(const struct z_sample_t *sample); +/** + * The encoding of the payload. + */ +ZENOHC_API const struct z_encoding_t *z_sample_encoding(const struct z_sample_t *sample); +ZENOHC_API bool z_sample_express(const struct z_sample_t *sample); /** * The Key Expression of the sample. * * `sample` is aliased by its return value. */ -ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); +ZENOHC_API const struct z_keyexpr_t *z_sample_keyexpr(const struct z_sample_t *sample); /** * The sample's kind (put or delete). */ @@ -1801,7 +1820,8 @@ ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); * The sample's data, the return value aliases the sample. * */ -ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API const struct z_bytes_t *z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API enum z_priority_t z_sample_priority(const struct z_sample_t *sample); /** * The samples timestamp * @@ -1827,8 +1847,8 @@ ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t * ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); ZENOHC_API -void z_scouting_config_from(struct z_config_t config, - struct z_owned_scouting_config_t *this_); +void z_scouting_config_from(struct z_owned_scouting_config_t *this_, + const struct z_config_t *config); ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); /** * Returns ``true`` if `session` is valid. @@ -1845,7 +1865,7 @@ ZENOHC_API bool z_session_check(const struct z_owned_session_t *this_); * have been destroyed is UB (likely SEGFAULT) */ ZENOHC_API -struct z_session_t z_session_loan(const struct z_owned_session_t *this_); +const struct z_session_t *z_session_loan(const struct z_owned_session_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_session_t' type */ @@ -1857,11 +1877,11 @@ ZENOHC_API int8_t z_sleep_us(size_t time); * Returns ``true`` if `b` is initialized. */ ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); -ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); +ZENOHC_API void z_slice_clone(struct z_owned_slice_t *this_, const struct z_slice_t *s); /** - * Frees `b` and invalidates it for double-drop safety. + * Frees `this` and invalidates it for double-drop safety. */ -ZENOHC_API void z_slice_drop(struct z_owned_slice_t *b); +ZENOHC_API void z_slice_drop(struct z_owned_slice_t *this_); /** * Returns the gravestone value for `z_slice_t` */ @@ -1875,7 +1895,7 @@ ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); /** * Returns ``true`` if `b` is initialized. */ -ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *b); +ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *this_); ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); /** * Returns `true` if the map is not in its gravestone state @@ -1891,7 +1911,9 @@ ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); * Returns the value associated with `key`, returning a gravestone value if: * - `key` is in gravestone state. */ -ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z_slice_t key); +ZENOHC_API +struct z_slice_t z_slice_map_get(const struct z_slice_map_t *this_, + const struct z_slice_t *key); /** * Associates `value` to `key` in the map, aliasing them. * @@ -1900,22 +1922,22 @@ ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. */ ZENOHC_API -z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); +z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t *this_, + const struct z_slice_t *key, + const struct z_slice_t *value); /** * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. * * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. */ ZENOHC_API -z_error_t z_slice_map_insert_by_copy(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); +z_error_t z_slice_map_insert_by_copy(struct z_slice_map_t *this_, + const struct z_slice_t *key, + const struct z_slice_t *value); /** * Returns true if the map is empty, false otherwise. */ -ZENOHC_API bool z_slice_map_is_empty(struct z_slice_map_t this_); +ZENOHC_API bool z_slice_map_is_empty(const struct z_slice_map_t *this_); ZENOHC_API void z_slice_map_iterate(const struct z_slice_map_t *this_, z_slice_map_iter_body_t body, @@ -1923,8 +1945,9 @@ void z_slice_map_iterate(const struct z_slice_map_t *this_, /** * Returns number of key-value pairs in the map. */ -ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); -ZENOHC_API struct z_slice_map_t z_slice_map_loan(const struct z_owned_slice_map_t *this_); +ZENOHC_API size_t z_slice_map_len(const struct z_slice_map_t *this_); +ZENOHC_API const struct z_slice_map_t *z_slice_map_loan(const struct z_owned_slice_map_t *this_); +ZENOHC_API struct z_slice_map_t *z_slice_map_loan_mut(struct z_owned_slice_map_t *this_); /** * Constructs a new empty map. */ @@ -1933,21 +1956,14 @@ ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); * Constructs the gravestone value for `z_owned_slice_map_t` */ ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); -/** - * Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_slice_empty()` - */ -ZENOHC_API -struct z_slice_t z_slice_new(const char *str); /** * Returns the gravestone value for `z_owned_slice_t` */ -ZENOHC_API struct z_owned_slice_t z_slice_null(void); +ZENOHC_API void z_slice_null(struct z_owned_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. */ -ZENOHC_API struct z_slice_t z_slice_wrap(const uint8_t *start, size_t len); +ZENOHC_API struct z_slice_t z_slice_wrap(uint8_t *start, size_t len); /** * Returns ``true`` if `strs` is valid. */ @@ -1959,7 +1975,7 @@ ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); /** * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. */ -ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); +ZENOHC_API const struct z_str_array_t *z_str_array_loan(const struct z_owned_str_array_t *strs); /** * Returns ``true`` if `s` is a valid string */ @@ -1975,7 +1991,7 @@ ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); /** * Returns undefined `z_owned_str_t` */ -ZENOHC_API struct z_owned_str_t z_str_null(void); +ZENOHC_API void z_str_null(struct z_owned_str_t *this_); /** * Returns ``true`` if `sub` is valid. */ @@ -1983,11 +1999,11 @@ ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber /** * Returns the key expression of the subscriber. */ -ZENOHC_API struct z_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); +ZENOHC_API const struct z_keyexpr_t *z_subscriber_keyexpr(const struct z_subscriber_t *subscriber); /** * Returns a :c:type:`z_subscriber_t` loaned from `this`. */ -ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *this_); +ZENOHC_API const struct z_subscriber_t *z_subscriber_loan(const struct z_owned_subscriber_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type */ @@ -1995,7 +2011,7 @@ ZENOHC_API void z_subscriber_null(struct z_owned_subscriber_t *this_); /** * Constructs the default value for :c:type:`z_subscriber_options_t`. */ -ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); +ZENOHC_API void z_subscriber_options_default(struct z_subscriber_options_t *this_); ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); /** * Detaches the task and releases all allocated resources. @@ -2022,12 +2038,14 @@ ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. * The keyxpr is consumed. */ -ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); +ZENOHC_API +z_error_t z_undeclare_keyexpr(const struct z_session_t *session, + struct z_owned_keyexpr_t *kexpr); /** * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -z_error_t z_undeclare_publisher(struct z_owned_publisher_t *publisher); +z_error_t z_undeclare_publisher(struct z_owned_publisher_t *this_); /** * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. * @@ -2056,16 +2074,16 @@ 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. */ ZENOHC_API -z_error_t zc_config_from_file(const char *path, - struct z_owned_config_t *this_); +z_error_t zc_config_from_file(struct z_owned_config_t *this_, + const char *path); /** * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. * * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). */ ZENOHC_API -z_error_t zc_config_from_str(const char *s, - struct z_owned_config_t *this_); +z_error_t zc_config_from_str(struct z_owned_config_t *this_, + const char *s); /** * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. * Use `z_drop` to safely deallocate this string @@ -2079,14 +2097,14 @@ struct z_owned_str_t zc_config_get(struct z_config_t config, * Returns 0 if successful, a negative value otherwise. */ ZENOHC_API -int8_t zc_config_insert_json(struct z_config_t config, - const char *key, - const char *value); +z_error_t zc_config_insert_json(const struct z_config_t *config, + const char *key, + const char *value); /** * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. */ ZENOHC_API -struct z_owned_str_t zc_config_to_string(struct z_config_t config); +struct z_owned_str_t zc_config_to_string(const struct z_config_t *config); /** * Initialises the zenoh runtime logger. * @@ -2097,21 +2115,18 @@ ZENOHC_API void zc_init_logger(void); /** * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. */ -ZENOHC_API -z_error_t zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, - const char *name, - size_t len); +ZENOHC_API z_error_t zc_keyexpr_from_slice(struct z_keyexpr_t *this_, const char *name, size_t len); /** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. * 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 -z_error_t zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, +z_error_t zc_keyexpr_from_slice_autocanonize(struct z_keyexpr_t *this_, char *name, size_t *len); /** - * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: * - `name` MUST be valid UTF8. * - `name` MUST follow the Key Expression specification, ie: * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -2121,11 +2136,11 @@ z_error_t zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, * It is a loaned key expression that aliases `name`. */ ZENOHC_API -void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, +void zc_keyexpr_from_slice_unchecked(struct z_keyexpr_t *this_, const char *start, size_t len); ZENOHC_API -struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_default(void); +void zc_liveliness_declaration_options_default(struct zc_liveliness_declaration_options_t *this_); /** * Declares a subscriber on liveliness tokens that intersect `key`. * @@ -2144,8 +2159,8 @@ struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_def */ ZENOHC_API z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct zc_liveliness_declare_subscriber_options_t *_options); /** @@ -2158,8 +2173,8 @@ z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, */ ZENOHC_API z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct zc_liveliness_declaration_options_t *_options); /** * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. @@ -2169,16 +2184,16 @@ z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. */ ZENOHC_API -z_error_t zc_liveliness_get(struct z_session_t session, - struct z_keyexpr_t key_expr, +z_error_t zc_liveliness_get(const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_reply_t *callback, struct zc_liveliness_get_options_t *options); /** * The gravestone value for `zc_liveliness_get_options_t` */ -ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); +ZENOHC_API void zc_liveliness_get_options_default(struct zc_liveliness_get_options_t *this_); ZENOHC_API -struct zc_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_default(void); +void zc_liveliness_subscriber_options_default(struct zc_liveliness_declare_subscriber_options_t *this_); /** * Returns `true` unless the token is at its gravestone value. */ @@ -2243,18 +2258,6 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); */ ZENOHC_API struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); -/** - * Returns `true` if `sample` is valid. - * - * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed - * unless the value has been dropped already. - */ -ZENOHC_API -bool zc_sample_check(const struct zc_owned_sample_t *sample); -/** - * Clone a sample in the cheapest way available. - */ -ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); /** * Destroy the sample. */ @@ -2264,14 +2267,14 @@ ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); * * Calling this function using a dropped sample is undefined behaviour. */ -ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); +ZENOHC_API const struct z_sample_t *zc_sample_loan(const struct zc_owned_sample_t *sample); ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ ZENOHC_API -int8_t zc_session_rcinc(struct z_owned_session_t *dst, - const struct z_owned_session_t *src); +z_error_t zc_session_clone(struct z_owned_session_t *dst, + const struct z_owned_session_t *src); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -2292,9 +2295,9 @@ ZENOHC_API enum zcu_locality_t zcu_locality_default(void); * Register callback for notifying subscribers matching. */ ZENOHC_API -z_error_t zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, - struct zcu_owned_closure_matching_status_t *callback, - struct zcu_owned_matching_listener_t *this_); +z_error_t zcu_publisher_matching_listener_callback(struct zcu_owned_matching_listener_t *this_, + const struct z_publisher_t *publisher, + struct zcu_owned_closure_matching_status_t *callback); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); /** * Declares a Publication Cache. @@ -2362,8 +2365,8 @@ z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this */ ZENOHC_API z_error_t ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct ze_querying_subscriber_options_t *options); /** @@ -2387,14 +2390,14 @@ ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subs * The queried samples will be merged with the received publications and made available in the subscriber callback. */ ZENOHC_API -z_error_t ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, - struct z_keyexpr_t selector, +z_error_t ze_querying_subscriber_get(const struct ze_querying_subscriber_t *sub, + const struct z_keyexpr_t *selector, const struct z_get_options_t *options); /** * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. */ ZENOHC_API -struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); +const struct ze_querying_subscriber_t *ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); /** * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type */ @@ -2402,7 +2405,8 @@ ZENOHC_API void ze_querying_subscriber_null(struct ze_owned_querying_subscriber_ /** * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. */ -ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); +ZENOHC_API +void ze_querying_subscriber_options_default(struct ze_querying_subscriber_options_t *this_); /** * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. */ diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 764cf399a..03f29535b 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -37,10 +37,10 @@ typedef struct ALIGN(8) z_owned_session_t { uint8_t _0[8]; } z_owned_session_t; typedef struct ALIGN(8) z_query_t { - uint8_t _0[8]; + uint8_t _0[16]; } z_query_t; typedef struct ALIGN(8) z_session_t { - uint8_t _0[8]; + uint8_t _0[40]; } z_session_t; /** * An owned zenoh queryable. @@ -77,6 +77,7 @@ typedef struct ALIGN(8) z_owned_subscriber_t { #define Z_EPARSE -2 #define Z_EIO -3 #define Z_ENETWORK -4 +#define Z_ENULL -5 #define Z_EBUSY_MUTEX -16 #define Z_EINVAL_MUTEX -22 #define Z_EAGAIN_MUTEX -11 diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index 15264a470..1cd1f063d 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -50,9 +50,9 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |query: z_query_t| { + From::from(move |query: &z_query_t| { let mut this = MaybeUninit::::uninit(); - z_query_clone(&mut this as *mut MaybeUninit, query); + z_query_clone(query, &mut this as *mut MaybeUninit); let this = this.assume_init(); if let Err(e) = tx.send(this) { log::error!("Attempted to push onto a closed reply_fifo: {}", e); @@ -63,9 +63,9 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |query: z_query_t| { + From::from(move |query: &z_query_t| { let mut this = MaybeUninit::::uninit(); - z_query_clone(&mut this as *mut MaybeUninit, query); + z_query_clone(query, &mut this as *mut MaybeUninit); let this = this.assume_init(); if let Err(e) = tx.send(this) { log::error!("Attempted to push onto a closed reply_fifo: {}", e); diff --git a/src/closures/query_closure.rs b/src/closures/query_closure.rs index f0387bc45..0512e28c8 100644 --- a/src/closures/query_closure.rs +++ b/src/closures/query_closure.rs @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_query_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_query_t { @@ -45,7 +45,7 @@ pub extern "C" fn z_closure_query_null() -> z_owned_closure_query_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: z_query_t) { +pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: &z_query_t) { match closure.call { Some(call) => call(query, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -57,12 +57,12 @@ pub extern "C" fn z_closure_query_drop(closure: &mut z_owned_closure_query_t) { let mut empty_closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_query_t { +impl From for z_owned_closure_query_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: z_query_t, this: *mut c_void) { + extern "C" fn call(query: *const z_query_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; - this(sample) + unsafe { this(query.as_ref().unwrap()) } } extern "C" fn drop(this: *mut c_void) { std::mem::drop(unsafe { Box::from_raw(this as *mut F) }) diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index d05b63ab3..c070c4bd8 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_reply_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } @@ -46,7 +46,7 @@ pub extern "C" fn z_closure_reply_null() -> z_owned_closure_reply_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_reply_call(closure: &z_owned_closure_reply_t, reply: z_reply_t) { +pub extern "C" fn z_closure_reply_call(closure: &z_owned_closure_reply_t, reply: &z_reply_t) { match closure.call { Some(call) => call(reply, closure.context), None => { @@ -60,12 +60,12 @@ pub extern "C" fn z_closure_reply_drop(closure: &mut z_owned_closure_reply_t) { let mut empty_closure = z_owned_closure_reply_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_reply_t { +impl From for z_owned_closure_reply_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(response: z_reply_t, this: *mut c_void) { + extern "C" fn call(response: *const z_reply_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; - this(response) + unsafe { this(response.as_ref().unwrap()) } } extern "C" fn drop(this: *mut c_void) { std::mem::drop(unsafe { Box::from_raw(this as *mut F) }) diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 5cabdccdc..4ef56b760 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -49,7 +49,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |reply: z_reply_t| { + From::from(move |reply: &z_reply_t| { let mut this = MaybeUninit::::uninit(); z_reply_clone(&mut this as *mut MaybeUninit, reply); let this = this.assume_init(); @@ -62,7 +62,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |reply: z_reply_t| { + From::from(move |reply: &z_reply_t| { let mut this = MaybeUninit::::uninit(); z_reply_clone(&mut this as *mut MaybeUninit, reply); let this = this.assume_init(); diff --git a/src/closures/sample_closure.rs b/src/closures/sample_closure.rs index 4d95cf177..043b59fb8 100644 --- a/src/closures/sample_closure.rs +++ b/src/closures/sample_closure.rs @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_sample_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_sample_t { @@ -47,7 +47,7 @@ pub extern "C" fn z_closure_sample_null() -> z_owned_closure_sample_t { /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: z_sample_t) { +pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: &z_sample_t) { match closure.call { Some(call) => call(sample, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -60,12 +60,12 @@ pub extern "C" fn z_closure_sample_drop(closure: &mut z_owned_closure_sample_t) let mut empty_closure = z_owned_closure_sample_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_sample_t { +impl From for z_owned_closure_sample_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: z_sample_t, this: *mut c_void) { + extern "C" fn call(sample: *const z_sample_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; - this(sample) + unsafe { this(sample.as_ref().unwrap()) } } extern "C" fn drop(this: *mut c_void) { std::mem::drop(unsafe { Box::from_raw(this as *mut F) }) diff --git a/src/collections.rs b/src/collections.rs index 740870321..f24d7d075 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -15,6 +15,7 @@ use std::borrow::Cow; use std::collections::HashMap; use std::mem::MaybeUninit; +use std::ptr::{null, null_mut}; use libc::{c_char, c_void, size_t}; use zenoh::prelude::ZenohId; @@ -45,7 +46,7 @@ impl z_slice_t { } pub fn empty() -> Self { z_slice_t { - start: std::ptr::null(), + start: std::ptr::null_mut(), len: 0, } } @@ -60,7 +61,7 @@ impl Default for z_slice_t { #[repr(C)] #[derive(Clone, Debug)] pub struct z_owned_slice_t { - pub start: *mut u8, + pub start: *const u8, pub len: size_t, } @@ -71,9 +72,15 @@ impl Drop for z_owned_slice_t { } impl z_owned_slice_t { + pub fn null() -> z_owned_slice_t { + z_owned_slice_t { + start: null(), + len: 0 + } + } pub fn new(data: &[u8]) -> z_owned_slice_t { if data.is_empty() { - return z_slice_null(); + return Self::null(); } let data = data.to_vec().into_boxed_slice(); z_owned_slice_t { @@ -92,29 +99,26 @@ impl z_owned_slice_t { #[allow(clippy::missing_safety_doc)] pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping(value.as_ptr(), self.start.add(start), value.len()); + std::ptr::copy_nonoverlapping(value.as_ptr(), self.start.add(start) as *mut u8, value.len()); } } impl Default for z_owned_slice_t { fn default() -> Self { - z_slice_null() + Self::null() } } /// Returns ``true`` if `b` is initialized. #[no_mangle] -pub extern "C" fn z_slice_is_initialized(b: &z_slice_t) -> bool { - !b.start.is_null() +pub extern "C" fn z_slice_is_initialized(this: &z_slice_t) -> bool { + !this.start.is_null() } /// Returns the gravestone value for `z_slice_t` #[no_mangle] pub const extern "C" fn z_slice_empty() -> z_slice_t { - z_slice_t { - len: 0, - start: core::ptr::null(), - } + z_slice_t::empty() } /// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). @@ -129,25 +133,15 @@ pub unsafe extern "C" fn z_slice_from_str(str: *const c_char) -> z_slice_t { let len = unsafe { libc::strlen(str) }; z_slice_t { len, - start: str.cast(), + start: str.cast_mut() as *mut u8, } } } -#[deprecated = "Renamed to z_slice_from_str"] -/// Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). -/// -/// `str == NULL` will cause this to return `z_slice_empty()` -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_new(str: *const c_char) -> z_slice_t { - z_slice_from_str(str) -} - /// Constructs a `len` bytes long view starting at `start`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_wrap(start: *const u8, len: usize) -> z_slice_t { +pub unsafe extern "C" fn z_slice_wrap(start: *mut u8, len: usize) -> z_slice_t { if start.is_null() { z_slice_empty() } else { @@ -155,26 +149,26 @@ pub unsafe extern "C" fn z_slice_wrap(start: *const u8, len: usize) -> z_slice_t } } -/// Frees `b` and invalidates it for double-drop safety. +/// Frees `this` and invalidates it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_drop(b: &mut z_owned_slice_t) { - if !b.start.is_null() { +pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { + if !this.start.is_null() { std::mem::drop(Box::from_raw( - core::ptr::slice_from_raw_parts(b.start, b.len).cast_mut(), + core::ptr::slice_from_raw_parts(this.start, this.len).cast_mut(), )); - b.start = std::ptr::null_mut(); - b.len = 0; + this.start = std::ptr::null_mut(); + this.len = 0; } } /// Returns the gravestone value for `z_owned_slice_t` #[no_mangle] -pub const extern "C" fn z_slice_null() -> z_owned_slice_t { - z_owned_slice_t { +pub unsafe extern "C" fn z_slice_null(this: *mut MaybeUninit) { + (*this).as_mut_ptr().write(z_owned_slice_t { len: 0, start: core::ptr::null_mut(), - } + }); } #[no_mangle] @@ -186,11 +180,11 @@ pub const extern "C" fn z_slice_loan(b: &z_owned_slice_t) -> z_slice_t { } #[no_mangle] -pub extern "C" fn z_slice_clone(b: &z_slice_t) -> z_owned_slice_t { - if !z_slice_is_initialized(b) { - z_slice_null() +pub unsafe extern "C" fn z_slice_clone(this: *mut MaybeUninit, s: &z_slice_t) { + if !z_slice_is_initialized(s) { + z_slice_null(this); } else { - z_owned_slice_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) }) + (*this).as_mut_ptr().write(z_owned_slice_t::new(unsafe { std::slice::from_raw_parts(s.start, s.len) })); } } @@ -257,6 +251,11 @@ pub struct z_owned_str_t { } impl z_owned_str_t { + pub fn null() -> z_owned_str_t { + z_owned_str_t { + _cstr: null_mut() + } + } #[allow(clippy::missing_safety_doc)] pub unsafe fn preallocate(len: usize) -> z_owned_str_t { let cstr = libc::malloc(len + 1) as *mut libc::c_char; @@ -292,7 +291,7 @@ impl Drop for z_owned_str_t { impl Default for z_owned_str_t { fn default() -> Self { - z_str_null() + Self::null() } } @@ -315,10 +314,12 @@ pub extern "C" fn z_str_check(s: &z_owned_str_t) -> bool { /// Returns undefined `z_owned_str_t` #[no_mangle] -pub extern "C" fn z_str_null() -> z_owned_str_t { - z_owned_str_t { - _cstr: std::ptr::null_mut(), - } +pub unsafe extern "C" fn z_str_null(this: *mut MaybeUninit) { + (*this).as_mut_ptr().write( + z_owned_str_t { + _cstr: std::ptr::null_mut(), + } + ); } /// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. @@ -377,21 +378,28 @@ pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { } #[no_mangle] -pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> z_slice_map_t { +pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_slice_map_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } +#[no_mangle] +pub extern "C" fn z_slice_map_loan_mut(this: &mut z_owned_slice_map_t) -> &mut z_slice_map_t { + let this = this.transmute_mut(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle_mut() +} + /// Returns number of key-value pairs in the map. #[no_mangle] -pub extern "C" fn z_slice_map_len(this: z_slice_map_t) -> usize { +pub extern "C" fn z_slice_map_len(this: &z_slice_map_t) -> usize { this.transmute_ref().len() } /// Returns true if the map is empty, false otherwise. #[no_mangle] -pub extern "C" fn z_slice_map_is_empty(this: z_slice_map_t) -> bool { +pub extern "C" fn z_slice_map_is_empty(this: &z_slice_map_t) -> bool { z_slice_map_len(this) == 0 } @@ -403,7 +411,7 @@ pub extern "C" fn z_slice_map_is_empty(this: z_slice_map_t) -> bool { /// Returning `true` is treated as `continue`. #[allow(non_camel_case_types)] pub type z_slice_map_iter_body_t = - extern "C" fn(key: z_slice_t, value: z_slice_t, context: *mut c_void) -> bool; + extern "C" fn(key: &z_slice_t, value: &z_slice_t, context: *mut c_void) -> bool; #[no_mangle] pub extern "C" fn z_slice_map_iterate( @@ -413,7 +421,9 @@ pub extern "C" fn z_slice_map_iterate( ) { let this = this.transmute_ref(); for (key, value) in this { - if !body(key.as_ref().into(), value.as_ref().into(), context) { + let key_slice = key.as_ref().into(); + let value_slice = value.as_ref().into(); + if !body(&key_slice, &value_slice, context) { break; } } @@ -422,11 +432,11 @@ pub extern "C" fn z_slice_map_iterate( /// Returns the value associated with `key`, returning a gravestone value if: /// - `key` is in gravestone state. #[no_mangle] -pub extern "C" fn z_slice_map_get(this: z_slice_map_t, key: z_slice_t) -> z_slice_t { +pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> z_slice_t { if !z_slice_is_initialized(&key) { return z_slice_empty(); } - let m = this.transmute_mut(); + let m = this.transmute_ref(); let key = key.as_slice().unwrap(); m.get(key) .map(|s| s.as_ref().into()) @@ -438,9 +448,9 @@ pub extern "C" fn z_slice_map_get(this: z_slice_map_t, key: z_slice_t) -> z_slic /// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_copy( - this: z_slice_map_t, - key: z_slice_t, - value: z_slice_t, + this: &mut z_slice_map_t, + key: &z_slice_t, + value: &z_slice_t, ) -> errors::z_error_t { let this = this.transmute_mut(); if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { @@ -458,9 +468,9 @@ pub extern "C" fn z_slice_map_insert_by_copy( /// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_alias( - this: z_slice_map_t, - key: z_slice_t, - value: z_slice_t, + this: &mut z_slice_map_t, + key: &z_slice_t, + value: &z_slice_t, ) -> errors::z_error_t { let this = this.transmute_mut(); if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { diff --git a/src/commons.rs b/src/commons.rs index 650e230d6..27eaafec8 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -14,6 +14,7 @@ use std::ffi::CStr; use std::mem::MaybeUninit; +use std::ptr::null; use std::str::FromStr; use crate::transmute::unwrap_ref_unchecked; @@ -93,20 +94,20 @@ decl_transmute_handle!(Sample, z_sample_t); /// /// `sample` is aliased by its return value. #[no_mangle] -pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { +pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> &z_keyexpr_t { let sample = sample.transmute_ref(); - sample.key_expr().into() + sample.key_expr().transmute_handle() } /// The encoding of the payload. #[no_mangle] -pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { +pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> &z_encoding_t { let sample = sample.transmute_ref(); sample.encoding().transmute_handle() } /// The sample's data, the return value aliases the sample. /// #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> &z_bytes_t { let sample = sample.transmute_ref(); sample.payload().transmute_handle() } @@ -136,23 +137,18 @@ pub extern "C" fn z_sample_timestamp( /// The qos with which the sample was received. /// TODO: split to methods (priority, congestion_control, express) -/// Checks if sample contains an attachment. -#[no_mangle] -pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { - let sample = sample.transmute_ref(); - sample.attachment().is_some() -} /// Gets sample's attachment. /// -/// Before calling this function, ensure that `zc_sample_has_attachment` returns true +/// Returns NULL if sample does not contain an attachement. #[no_mangle] -pub extern "C" fn z_sample_attachment(sample: z_sample_t) -> z_bytes_t { +pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> *const z_bytes_t { let sample = sample.transmute_ref(); - sample - .attachment() - .expect("Sample does not have an attachment") - .transmute_handle() + match sample.attachment() { + Some(attachment) => attachment.transmute_handle() as *const _, + None => null(), + } + } pub use crate::opaque_types::zc_owned_sample_t; @@ -160,19 +156,38 @@ decl_transmute_owned!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] -pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); } + +#[no_mangle] +pub extern "C" fn z_sample_priority(sample: &z_sample_t) -> z_priority_t { + let sample = sample.transmute_ref(); + sample.priority().into() +} + +#[no_mangle] +pub extern "C" fn z_sample_express(sample: &z_sample_t) -> bool { + let sample = sample.transmute_ref(); + sample.express() +} + +#[no_mangle] +pub extern "C" fn z_sample_congestion_control(sample: &z_sample_t) -> z_congestion_control_t { + let sample = sample.transmute_ref(); + sample.congestion_control().into() +} + /// Returns `true` if `sample` is valid. /// /// Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed /// unless the value has been dropped already. #[no_mangle] -pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { +pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { let sample = sample.transmute_ref(); sample.is_some() } @@ -181,7 +196,7 @@ pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: &'static zc_owned_sample_t) -> z_sample_t { +pub extern "C" fn zc_sample_loan(sample: & zc_owned_sample_t) -> &z_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } @@ -237,7 +252,7 @@ pub unsafe extern "C" fn z_encoding_from_str( /// Constructs a default :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_default() -> z_encoding_t { +pub extern "C" fn z_encoding_default() -> &'static z_encoding_t { Encoding::ZENOH_BYTES.transmute_handle() } @@ -258,7 +273,7 @@ pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> boo /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_encoding_t { +pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> &z_encoding_t { encoding.transmute_ref().transmute_handle() } diff --git a/src/config.rs b/src/config.rs index e7e420474..a837136ec 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,12 +16,12 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; -use crate::errors::{z_error_t, Z_EPARSE}; +use crate::errors::z_error_t; use crate::transmute::{ unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; -use crate::{errors, z_owned_str_t, z_str_null}; +use crate::{errors, z_owned_str_t}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -67,14 +67,13 @@ pub use crate::opaque_types::z_config_t; decl_transmute_handle!(Config, z_config_t); pub use crate::opaque_types::z_owned_config_t; -decl_transmute_owned!(Option>, z_owned_config_t); +decl_transmute_owned!(Option, z_owned_config_t); /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> z_config_t { +pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_config_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); - let this = this.as_ref(); this.transmute_handle() } @@ -91,7 +90,7 @@ pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> z_config_t { #[no_mangle] pub extern "C" fn z_config_default(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); - let config: Box = Box::default(); + let config = Config::default(); Inplace::init(this, Some(config)); } @@ -106,7 +105,7 @@ pub extern "C" fn z_config_null(this: *mut MaybeUninit) { #[no_mangle] pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) { let src = src.transmute_ref(); - let src = Box::new(src.clone()); + let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); } @@ -119,12 +118,12 @@ pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) - let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, - Err(_) => return z_str_null(), + Err(_) => return z_owned_str_t::null(), }; let val = config.get_json(key).ok(); match val { Some(val) => val.as_bytes().into(), - None => z_str_null(), + None => z_owned_str_t::null(), } } @@ -134,16 +133,16 @@ pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) - #[no_mangle] #[allow(clippy::missing_safety_doc, unused_must_use)] pub unsafe extern "C" fn zc_config_insert_json( - config: z_config_t, + config: &z_config_t, key: *const c_char, value: *const c_char, -) -> i8 { +) -> errors::z_error_t { let config = config.transmute_mut(); let key = CStr::from_ptr(key); let value = CStr::from_ptr(value); match config.insert_json5(&key.to_string_lossy(), &value.to_string_lossy()) { Ok(_) => 0, - Err(_) => i8::MIN, + Err(_) => errors::Z_EGENERIC, } } @@ -168,8 +167,8 @@ pub extern "C" fn z_config_check(config: &z_owned_config_t) -> bool { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_config_from_str( - s: *const c_char, this: *mut MaybeUninit, + s: *const c_char, ) -> errors::z_error_t { let mut res = errors::Z_OK; if s.is_null() { @@ -177,11 +176,10 @@ pub unsafe extern "C" fn zc_config_from_str( res = errors::Z_EINVAL; } else { let conf_str = CStr::from_ptr(s); - let props: Option> = json5::from_str(&conf_str.to_string_lossy()) - .ok() - .map(Box::new); + let props: Option = json5::from_str(&conf_str.to_string_lossy()) + .ok(); if props.is_none() { - res = Z_EPARSE; + res = errors::Z_EPARSE; } Inplace::init(this.transmute_uninit_ptr(), props); } @@ -191,11 +189,11 @@ pub unsafe extern "C" fn zc_config_from_str( /// Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { +pub extern "C" fn zc_config_to_string(config: &z_config_t) -> z_owned_str_t { let config: &Config = config.transmute_ref(); match json5::to_string(config) { Ok(s) => s.as_bytes().into(), - Err(_) => z_str_null(), + Err(_) => z_owned_str_t::null(), } } @@ -203,14 +201,14 @@ pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_config_from_file( - path: *const c_char, this: *mut MaybeUninit, + path: *const c_char, ) -> errors::z_error_t { let path_str = CStr::from_ptr(path); let mut res = errors::Z_OK; let config = match path_str.to_str() { Ok(path) => match zenoh::config::Config::from_file(path) { - Ok(c) => Some(Box::new(c)), + Ok(c) => Some(c), Err(e) => { log::error!("Couldn't read config from {}: {}", path, e); res = errors::Z_EPARSE; @@ -233,7 +231,7 @@ pub unsafe extern "C" fn zc_config_from_file( pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { Inplace::init( this.transmute_uninit_ptr(), - Some(Box::new(zenoh::config::peer())), + Some(zenoh::config::peer()), ); } @@ -242,9 +240,9 @@ pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_config_client( + this: *mut MaybeUninit, peers: *const *const c_char, n_peers: usize, - this: *mut MaybeUninit, ) -> z_error_t { let mut res = errors::Z_OK; let locators = if peers.is_null() { @@ -274,7 +272,7 @@ pub unsafe extern "C" fn z_config_client( }; Inplace::init( this.transmute_uninit_ptr(), - Some(Box::new(zenoh::config::client(locators))), + Some(zenoh::config::client(locators)), ); res } diff --git a/src/errors.rs b/src/errors.rs index 7415ffb40..cf494f4e0 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,6 +4,7 @@ pub const Z_EINVAL: z_error_t = -1; pub const Z_EPARSE: z_error_t = -2; pub const Z_EIO: z_error_t = -3; pub const Z_ENETWORK: z_error_t = -4; +pub const Z_ENULL: z_error_t = -5; // negativ pthread error codes (due to convention to return negative values on error) pub const Z_EBUSY_MUTEX: z_error_t = -16; pub const Z_EINVAL_MUTEX: z_error_t = -22; diff --git a/src/get.rs b/src/get.rs index 8be10c18b..cba2370d1 100644 --- a/src/get.rs +++ b/src/get.rs @@ -15,6 +15,7 @@ use libc::c_char; use std::ffi::CStr; use std::mem::MaybeUninit; +use std::ptr::null; use std::ptr::null_mut; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; @@ -47,35 +48,35 @@ decl_transmute_handle!(Reply, z_reply_t); /// If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_is_ok(reply: z_reply_t) -> bool { +pub unsafe extern "C" fn z_reply_is_ok(reply: &z_reply_t) -> bool { let reply = reply.transmute_ref(); reply.result().is_ok() } /// Yields the contents of the reply by asserting it indicates a success. /// -/// You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. +/// Returns null if reply does not contains a sample (i. e. if :c:func:`z_reply_is_ok` returns ``false``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { +pub unsafe extern "C" fn z_reply_ok(reply: &z_reply_t) -> *const z_sample_t { let reply = reply.transmute_ref(); - reply - .result() - .expect("Reply does not contain a sample") - .transmute_handle() + match reply.result() { + Ok(sample) => sample.transmute_handle(), + Err(_) => null(), + } } /// Yields the contents of the reply by asserting it indicates a failure. /// -/// You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. +/// Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_err(reply: z_reply_t) -> z_value_t { +pub unsafe extern "C" fn z_reply_err(reply: &z_reply_t) -> *const z_value_t{ let reply = reply.transmute_ref(); - reply - .result() - .expect_err("Reply does not contain error") - .transmute_handle() + match reply.result() { + Ok(_) => null(), + Err(v) => v.transmute_handle(), + } } /// Returns an invalidated :c:type:`z_owned_reply_t`. @@ -91,7 +92,7 @@ pub extern "C" fn z_reply_null(this: *mut MaybeUninit) { } #[no_mangle] -pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: z_reply_t) { +pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: &z_reply_t) { Inplace::init( this.transmute_uninit_ptr(), Some(reply.transmute_ref().clone()), @@ -116,15 +117,15 @@ pub struct z_get_options_t { pub timeout_ms: u64, } #[no_mangle] -pub extern "C" fn z_get_options_default() -> z_get_options_t { - z_get_options_t { +pub extern "C" fn z_get_options_default(this: &mut z_get_options_t) { + *this = z_get_options_t { target: QueryTarget::default().into(), consolidation: QueryConsolidation::default().into(), timeout_ms: 0, payload: null_mut(), encoding: null_mut(), attachment: null_mut(), - } + }; } /// Query data from the matching queryables in the system. @@ -144,8 +145,8 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_get( - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, options: Option<&mut z_get_options_t>, @@ -205,7 +206,7 @@ pub extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { } #[no_mangle] -pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> z_reply_t { +pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> &z_reply_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 6f25b75c6..4f07fd624 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -44,7 +44,7 @@ pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { } fn keyexpr_create_inner( - name: &'static mut str, + mut name: &'static mut str, should_auto_canonize: bool, should_copy: bool, ) -> Result, Box> { @@ -56,8 +56,8 @@ fn keyexpr_create_inner( } } else { match should_auto_canonize { - true => KeyExpr::<'static>::autocanonize(name), - false => KeyExpr::<'static>::try_from(name), + true => keyexpr::autocanonize(&mut name).map(|k| k.into()), + false => keyexpr::new(name).map(|k| k.into()) } } } @@ -134,7 +134,7 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize( /// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. #[no_mangle] -pub extern "C" fn z_keyexpr_loan(key_expr: &'static z_owned_keyexpr_t) -> z_keyexpr_t { +pub extern "C" fn z_keyexpr_loan(key_expr: &z_owned_keyexpr_t) -> &z_keyexpr_t { unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } @@ -165,15 +165,6 @@ pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { pub use crate::opaque_types::z_keyexpr_t; decl_transmute_handle!(KeyExpr<'static>, z_keyexpr_t); -#[derive(Debug, Clone, Copy)] -pub struct UninitializedKeyExprError; -impl std::fmt::Display for UninitializedKeyExprError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("Uninitialized Key Expression detected, make sure you use `z_keyexpr_check` or `z_loaned_keyexpr_check` after constructing your key expressions") - } -} -impl std::error::Error for UninitializedKeyExprError {} - /// Returns ``0`` if the passed string is a valid (and canon) key expression. /// Otherwise returns error value #[allow(clippy::missing_safety_doc)] @@ -229,42 +220,36 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_keyexpr_from_slice( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *const c_char, len: usize, ) -> z_error_t { - let this = this.transmute_uninit_ptr(); if name.is_null() { - Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, len); - match keyexpr_create(name, false, false) { Ok(ke) => { - Inplace::init(this, Some(ke)); + (*this).write(std::mem::transmute(ke)); errors::Z_OK } Err(e) => { - Inplace::empty(this); e } } } -/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. /// 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( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *mut c_char, len: &mut usize, ) -> z_error_t { - let this = this.transmute_uninit_ptr(); if name.is_null() { - Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); @@ -272,11 +257,10 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( match keyexpr_create(name, true, false) { Ok(ke) => { *len = ke.len(); - Inplace::init(this, Some(ke)); + (*this).write(std::mem::transmute(ke)); errors::Z_OK } Err(e) => { - Inplace::empty(this); e } } @@ -287,11 +271,10 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *const c_char, ) -> z_error_t { if name.is_null() { - Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL } else { let len = libc::strlen(name); @@ -299,17 +282,16 @@ pub unsafe extern "C" fn z_keyexpr( } } -/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. /// 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( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *mut c_char, ) -> z_error_t { if name.is_null() { - Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL } else { let mut len = libc::strlen(name); @@ -321,7 +303,7 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize( } } -/// Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: /// - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -332,17 +314,17 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( - this: *mut MaybeUninit, + this: *mut MaybeUninit, start: *const c_char, len: usize, ) { let name = std::slice::from_raw_parts(start as _, len); let name = std::str::from_utf8_unchecked(name); let name: KeyExpr = keyexpr::from_str_unchecked(name).into(); - Inplace::init(this.transmute_uninit_ptr(), Some(name)); + (*this).write(std::mem::transmute(name)); } -/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: /// /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: @@ -355,7 +337,7 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr_unchecked( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *const c_char, ) { zc_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) @@ -365,7 +347,7 @@ pub unsafe extern "C" fn z_keyexpr_unchecked( /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_to_string(ke: z_keyexpr_t) -> z_owned_str_t { +pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t) -> z_owned_str_t { ke.transmute_ref().as_bytes().into() } @@ -374,7 +356,7 @@ pub unsafe extern "C" fn z_keyexpr_to_string(ke: z_keyexpr_t) -> z_owned_str_t { /// Currently exclusive to zenoh-c #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { +pub extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t) -> z_slice_t { let ke = ke.transmute_ref(); z_slice_t { start: ke.as_ptr(), @@ -382,12 +364,6 @@ pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { } } -impl From<&'static KeyExpr<'static>> for z_keyexpr_t { - fn from(key: &'static KeyExpr<'static>) -> Self { - key.transmute_handle() - } -} - /**************************************/ /* DECLARATION */ /**************************************/ @@ -399,8 +375,8 @@ impl From<&'static KeyExpr<'static>> for z_keyexpr_t { #[no_mangle] pub extern "C" fn z_declare_keyexpr( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, ) -> z_error_t { let this = this.transmute_uninit_ptr(); let key_expr = key_expr.transmute_ref(); @@ -422,10 +398,10 @@ pub extern "C" fn z_declare_keyexpr( /// The keyxpr is consumed. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_keyexpr(session: z_session_t, kexpr: &mut z_owned_keyexpr_t) -> i8 { +pub extern "C" fn z_undeclare_keyexpr(session: &z_session_t, kexpr: &mut z_owned_keyexpr_t) -> errors::z_error_t { let Some(kexpr) = kexpr.transmute_mut().take() else { log::debug!("Attempted to undeclare dropped keyexpr"); - return i8::MIN; + return errors::Z_EINVAL; }; let session = session.transmute_ref(); match session.undeclare(kexpr).res() { @@ -440,7 +416,7 @@ pub extern "C" fn z_undeclare_keyexpr(session: z_session_t, kexpr: &mut z_owned_ #[allow(clippy::missing_safety_doc)] #[no_mangle] /// Returns ``0`` if both ``left`` and ``right`` are equal. -pub extern "C" fn z_keyexpr_equals(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_equals(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); *l == *r @@ -450,7 +426,7 @@ pub extern "C" fn z_keyexpr_equals(left: z_keyexpr_t, right: z_keyexpr_t) -> boo #[no_mangle] /// Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the /// sets defined by ``left`` and ``right``. -pub extern "C" fn z_keyexpr_intersects(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_intersects(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); l.intersects(r) @@ -460,7 +436,7 @@ pub extern "C" fn z_keyexpr_intersects(left: z_keyexpr_t, right: z_keyexpr_t) -> #[no_mangle] /// Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set /// defined by ``right``. -pub extern "C" fn z_keyexpr_includes(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_includes(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); l.includes(r) @@ -476,10 +452,10 @@ pub extern "C" fn z_keyexpr_includes(left: z_keyexpr_t, right: z_keyexpr_t) -> b /// To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, /// as this would extremely likely cause bugs. pub unsafe extern "C" fn z_keyexpr_concat( - left: z_keyexpr_t, + this: *mut MaybeUninit, + left: &z_keyexpr_t, right_start: *const c_char, right_len: usize, - this: *mut MaybeUninit, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let left = left.transmute_ref(); @@ -515,9 +491,9 @@ pub unsafe extern "C" fn z_keyexpr_concat( /// Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. /// In case of error, the return value will be set to its invalidated state. pub extern "C" fn z_keyexpr_join( - left: z_keyexpr_t, - right: z_keyexpr_t, this: *mut MaybeUninit, + left: &z_keyexpr_t, + right: &z_keyexpr_t, ) -> errors::z_error_t { let left = left.transmute_ref(); let right = right.transmute_ref(); @@ -566,8 +542,8 @@ impl From for z_keyexpr_intersection_level_t { /// /// Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. pub extern "C" fn z_keyexpr_relation_to( - left: z_keyexpr_t, - right: z_keyexpr_t, + left: &z_keyexpr_t, + right: &z_keyexpr_t, ) -> z_keyexpr_intersection_level_t { let l = left.transmute_ref(); let r = right.transmute_ref(); diff --git a/src/liveliness.rs b/src/liveliness.rs index fed6a9bfc..88e0966b3 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -54,9 +54,9 @@ pub struct zc_liveliness_declaration_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_default() -> zc_liveliness_declaration_options_t +pub extern "C" fn zc_liveliness_declaration_options_default(this: &mut zc_liveliness_declaration_options_t) { - zc_liveliness_declaration_options_t { _dummy: 0 } + *this = zc_liveliness_declaration_options_t { _dummy: 0 }; } /// Constructs and declares a liveliness token on the network. @@ -68,8 +68,8 @@ pub extern "C" fn zc_liveliness_declaration_options_default() -> zc_liveliness_d #[no_mangle] pub extern "C" fn zc_liveliness_declare_token( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, _options: Option<&mut zc_liveliness_declaration_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); @@ -110,9 +110,8 @@ pub struct zc_liveliness_declare_subscriber_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_default( -) -> zc_liveliness_declare_subscriber_options_t { - zc_liveliness_declare_subscriber_options_t { _dummy: 0 } +pub extern "C" fn zc_liveliness_subscriber_options_default(this: &mut zc_liveliness_declare_subscriber_options_t) { + *this = zc_liveliness_declare_subscriber_options_t { _dummy: 0 }; } /// Declares a subscriber on liveliness tokens that intersect `key`. @@ -132,8 +131,8 @@ pub extern "C" fn zc_liveliness_subscriber_options_default( #[no_mangle] pub extern "C" fn zc_liveliness_declare_subscriber( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_sample_t, _options: Option<&mut zc_liveliness_declare_subscriber_options_t>, ) -> errors::z_error_t { @@ -170,8 +169,8 @@ pub struct zc_liveliness_get_options_t { /// The gravestone value for `zc_liveliness_get_options_t` #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_default() -> zc_liveliness_get_options_t { - zc_liveliness_get_options_t { timeout_ms: 10000 } +pub extern "C" fn zc_liveliness_get_options_default(this: &mut zc_liveliness_get_options_t) { + *this = zc_liveliness_get_options_t { timeout_ms: 10000 }; } /// Queries liveliness tokens currently on the network with a key expression intersecting with `key`. @@ -181,8 +180,8 @@ pub extern "C" fn zc_liveliness_get_options_default() -> zc_liveliness_get_optio /// Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. #[no_mangle] pub extern "C" fn zc_liveliness_get( - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_reply_t, options: Option<&mut zc_liveliness_get_options_t>, ) -> errors::z_error_t { diff --git a/src/payload.rs b/src/payload.rs index 530fbf358..7f3556b27 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -41,7 +41,7 @@ extern "C" fn z_bytes_check(payload: &z_owned_bytes_t) -> bool { /// Loans the payload, allowing you to call functions that only need a loan of it. #[no_mangle] -extern "C" fn z_bytes_loan(payload: &'static z_owned_bytes_t) -> z_bytes_t { +extern "C" fn z_bytes_loan(payload: & z_owned_bytes_t) -> &z_bytes_t { let payload = payload.transmute_ref(); let payload = unwrap_ref_unchecked(payload); payload.transmute_handle() @@ -52,16 +52,16 @@ decl_transmute_handle!(ZBytes, z_bytes_t); /// Increments the payload's reference count, returning an owned version of it. #[no_mangle] -extern "C" fn z_bytes_clone(src: &z_owned_bytes_t, dst: *mut MaybeUninit) { +extern "C" fn z_bytes_clone(src: &z_bytes_t, dst: *mut MaybeUninit) { let dst = dst.transmute_uninit_ptr(); let src = src.transmute_ref(); - let src = src.as_ref().map(Clone::clone); + let src = Some(src.clone()); Inplace::init(dst, src); } /// Returns total number bytes in the payload. #[no_mangle] -extern "C" fn z_bytes_len(payload: z_bytes_t) -> usize { +extern "C" fn z_bytes_len(payload: &z_bytes_t) -> usize { payload.transmute_ref().len() } @@ -69,7 +69,7 @@ extern "C" fn z_bytes_len(payload: z_bytes_t) -> usize { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_string( - payload: z_bytes_t, + payload: &z_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let len = z_bytes_len(payload); @@ -110,13 +110,13 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_bytes( - payload: z_bytes_t, + payload: &z_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let len = z_bytes_len(payload); let b = z_owned_slice_t::preallocate(len); let payload = payload.transmute_ref(); - if let Err(e) = payload.reader().read(from_raw_parts_mut(b.start, len)) { + if let Err(e) = payload.reader().read(from_raw_parts_mut(b.start as *mut _, len)) { log::error!("Failed to read the payload: {}", e); Inplace::empty(dst); errors::Z_EIO @@ -147,10 +147,10 @@ impl ZSliceBuffer for z_slice_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_bytes( this: *mut MaybeUninit, - bytes: z_slice_t, + bytes: &z_slice_t, ) { let this = this.transmute_uninit_ptr(); - let payload = ZBytes::from(ZSlice::from(bytes)); + let payload = ZBytes::from(ZSlice::from(bytes.clone())); Inplace::init(this, Some(payload)); } @@ -159,7 +159,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( this: *mut MaybeUninit, - bytes_map: z_slice_map_t, + bytes_map: &z_slice_map_t, ) { let dst = this.transmute_uninit_ptr(); let hm = bytes_map.transmute_ref(); @@ -178,7 +178,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( start: cstr as *const u8, len: libc::strlen(cstr), }; - z_bytes_encode_from_bytes(this, bytes); + z_bytes_encode_from_bytes(this, &bytes); } pub use crate::opaque_types::z_owned_bytes_reader_t; @@ -222,7 +222,7 @@ extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_reader_t) { } #[no_mangle] -extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_reader_t) -> z_bytes_reader_t { +extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_reader_t { let reader = reader.transmute_ref(); let reader = unwrap_ref_unchecked(reader); reader.transmute_handle() @@ -235,7 +235,7 @@ extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_reader_t) -> z_ #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_read( - this: z_bytes_reader_t, + this: &z_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { @@ -251,7 +251,7 @@ pub unsafe extern "C" fn z_bytes_reader_read( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_seek( - this: z_bytes_reader_t, + this: &z_bytes_reader_t, offset: i64, origin: libc::c_int, ) -> z_error_t { @@ -274,7 +274,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( /// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_tell(this: z_bytes_reader_t) -> i64 { +pub unsafe extern "C" fn z_bytes_reader_tell(this: &z_bytes_reader_t) -> i64 { let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } diff --git a/src/publisher.rs b/src/publisher.rs index 30c033645..8b647dfd4 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -49,11 +49,11 @@ pub struct z_publisher_options_t { /// Constructs the default value for :c:type:`z_publisher_options_t`. #[no_mangle] -pub extern "C" fn z_publisher_options_default() -> z_publisher_options_t { - z_publisher_options_t { +pub extern "C" fn z_publisher_options_default(this: &mut z_publisher_options_t) { + *this = z_publisher_options_t { congestion_control: CongestionControl::default().into(), priority: Priority::default().into(), - } + }; } pub use crate::opaque_types::z_owned_publisher_t; @@ -97,10 +97,10 @@ decl_transmute_handle!(Publisher<'static>, z_publisher_t); #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_publisher( - session: z_session_t, - key_expr: z_keyexpr_t, - options: Option<&z_publisher_options_t>, this: *mut MaybeUninit, + session: &z_session_t, + key_expr: &z_keyexpr_t, + options: Option<&z_publisher_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); @@ -135,16 +135,16 @@ pub extern "C" fn z_publisher_null(this: *mut MaybeUninit) /// Returns ``true`` if `pub` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_publisher_check(pbl: &'static z_owned_publisher_t) -> bool { - pbl.transmute_ref().is_some() +pub extern "C" fn z_publisher_check(this: &z_owned_publisher_t) -> bool { + this.transmute_ref().is_some() } /// Returns a :c:type:`z_publisher_t` loaned from `p`. #[no_mangle] -pub extern "C" fn z_publisher_loan(p: &'static z_owned_publisher_t) -> z_publisher_t { - let p = p.transmute_ref(); - let p = unwrap_ref_unchecked(p); - p.transmute_handle() +pub extern "C" fn z_publisher_loan(this: &z_owned_publisher_t) -> &z_publisher_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } /// Options passed to the :c:func:`z_publisher_put` function. @@ -161,8 +161,8 @@ pub struct z_publisher_put_options_t { /// Constructs the default value for :c:type:`z_publisher_put_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t { - z_publisher_put_options_t { +pub extern "C" fn z_publisher_put_options_default(this: &mut z_publisher_put_options_t) { + *this = z_publisher_put_options_t { encoding: ptr::null_mut(), attachment: ptr::null_mut(), } @@ -185,7 +185,7 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_publisher_put( - publisher: z_publisher_t, + publisher: &z_publisher_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_publisher_put_options_t>, ) -> errors::z_error_t { @@ -231,8 +231,8 @@ pub struct z_publisher_delete_options_t { /// Returns the constructed :c:type:`z_publisher_delete_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_delete_options_default() -> z_publisher_delete_options_t { - z_publisher_delete_options_t { __dummy: 0 } +pub extern "C" fn z_publisher_delete_options_default(this: &mut z_publisher_delete_options_t) { + *this = z_publisher_delete_options_t { __dummy: 0 } } /// Sends a `DELETE` message onto the publisher's key expression. /// @@ -241,7 +241,7 @@ pub extern "C" fn z_publisher_delete_options_default() -> z_publisher_delete_opt #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_delete( - publisher: z_publisher_t, + publisher: &z_publisher_t, _options: z_publisher_delete_options_t, ) -> errors::z_error_t { let publisher = publisher.transmute_ref(); @@ -256,7 +256,7 @@ pub extern "C" fn z_publisher_delete( /// Returns the key expression of the publisher #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_keyexpr_t { +pub extern "C" fn z_publisher_keyexpr(publisher: &z_publisher_t) -> &z_keyexpr_t { let publisher = publisher.transmute_ref(); publisher.key_expr().transmute_handle() } @@ -281,9 +281,9 @@ pub struct zcu_matching_status_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn zcu_publisher_matching_listener_callback( - publisher: z_publisher_t, - callback: &mut zcu_owned_closure_matching_status_t, this: *mut MaybeUninit, + publisher: &z_publisher_t, + callback: &mut zcu_owned_closure_matching_status_t, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); @@ -313,8 +313,8 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( /// Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> errors::z_error_t { - if let Some(p) = publisher.transmute_mut().extract().take() { +pub extern "C" fn z_undeclare_publisher(this: &mut z_owned_publisher_t) -> errors::z_error_t { + if let Some(p) = this.transmute_mut().extract().take() { if let Err(e) = p.undeclare().res_sync() { log::error!("{}", e); return errors::Z_EGENERIC; diff --git a/src/put.rs b/src/put.rs index 728499034..2bb950087 100644 --- a/src/put.rs +++ b/src/put.rs @@ -46,13 +46,13 @@ pub struct z_put_options_t { /// Constructs the default value for :c:type:`z_put_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_put_options_default() -> z_put_options_t { - z_put_options_t { +pub extern "C" fn z_put_options_default(this: &mut z_put_options_t) { + *this = z_put_options_t { encoding: null_mut(), congestion_control: CongestionControl::default().into(), priority: Priority::default().into(), attachment: null_mut(), - } + }; } /// Put data, transfering its ownership. @@ -71,8 +71,8 @@ pub extern "C" fn z_put_options_default() -> z_put_options_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_put( - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_put_options_t>, ) -> errors::z_error_t { @@ -117,11 +117,11 @@ pub struct z_delete_options_t { /// Constructs the default value for :c:type:`z_put_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { - z_delete_options_t { +pub unsafe extern "C" fn z_delete_options_default(this: *mut z_delete_options_t) { + *this = z_delete_options_t { congestion_control: CongestionControl::default().into(), priority: Priority::default().into(), - } + }; } /// Delete data. @@ -135,8 +135,8 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_delete( - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, options: Option<&mut z_delete_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); diff --git a/src/queryable.rs b/src/queryable.rs index 17b5a82bc..e27178983 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -20,7 +20,7 @@ use crate::{ z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, }; use std::mem::MaybeUninit; -use std::ptr::null_mut; +use std::ptr::{null, null_mut}; use zenoh::prelude::SessionDeclarations; use zenoh::prelude::SyncResolve; use zenoh::prelude::{Query, Queryable}; @@ -66,7 +66,7 @@ pub extern "C" fn z_query_check(query: &z_owned_query_t) -> bool { /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] -pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> z_query_t { +pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> &z_query_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -82,11 +82,11 @@ pub extern "C" fn z_query_drop(this: &mut z_owned_query_t) { /// /// This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). #[no_mangle] -pub extern "C" fn z_query_clone(this: *mut MaybeUninit, query: z_query_t) { - let query = query.transmute_ref(); - let query = query.clone(); - let this = this.transmute_uninit_ptr(); - Inplace::init(this, Some(query)); +pub extern "C" fn z_query_clone(this: &z_query_t, dst: *mut MaybeUninit) { + let this = this.transmute_ref(); + let this = this.clone(); + let dst = dst.transmute_uninit_ptr(); + Inplace::init(dst, Some(this)); } /// Options passed to the :c:func:`z_declare_queryable` function. @@ -101,8 +101,8 @@ pub struct z_queryable_options_t { /// Constructs the default value for :c:type:`z_query_reply_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_queryable_options_default() -> z_queryable_options_t { - z_queryable_options_t { complete: false } +pub extern "C" fn z_queryable_options_default(this: &mut z_queryable_options_t) { + *this = z_queryable_options_t { complete: false }; } /// Represents the set of options that can be applied to a query reply, @@ -121,11 +121,11 @@ pub struct z_query_reply_options_t { /// Constructs the default value for :c:type:`z_query_reply_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { - z_query_reply_options_t { +pub extern "C" fn z_query_reply_options_default(this: &mut z_query_reply_options_t) { + *this = z_query_reply_options_t { encoding: null_mut(), attachment: null_mut(), - } + }; } /// Creates a Queryable for the given key expression. @@ -142,8 +142,8 @@ pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { #[no_mangle] pub extern "C" fn z_declare_queryable( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_query_t, options: Option<&mut z_queryable_options_t>, ) -> errors::z_error_t { @@ -248,14 +248,14 @@ pub unsafe extern "C" fn z_query_reply( /// Get a query's key by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_keyexpr(query: z_query_t) -> z_keyexpr_t { +pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { query.transmute_ref().key_expr().transmute_handle() } /// Get a query's `value selector `_ by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_parameters(query: z_query_t) -> z_slice_t { +pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_slice_t { let query = query.transmute_ref(); let params = query.parameters().as_str(); z_slice_t { @@ -265,21 +265,17 @@ pub extern "C" fn z_query_parameters(query: z_query_t) -> z_slice_t { } /// Checks if query contains a payload value. -pub extern "C" fn z_query_has_value(query: z_query_t) -> bool { +#[no_mangle] +pub extern "C" fn z_query_has_value(query: &z_query_t) -> bool { query.transmute_ref().value().is_some() } -/// Checks if query contains an attachment. -pub extern "C" fn z_query_has_attachment(query: z_query_t) -> bool { - query.transmute_ref().attachment().is_some() -} - /// Gets a query's `payload value `_ by aliasing it. /// /// **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** /// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] -pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { +pub extern "C" fn z_query_value(query: &z_query_t) -> &z_value_t { query .transmute_ref() .value() @@ -289,12 +285,11 @@ pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { /// Gets the attachment to the query by aliasing. /// -/// Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. +/// Returns NULL if query does not contain an attachment. #[no_mangle] -pub extern "C" fn z_query_attachment(query: z_query_t) -> z_bytes_t { - query - .transmute_ref() - .attachment() - .expect("Query does not contain an attachment") - .transmute_handle() +pub extern "C" fn z_query_attachment(query: &z_query_t) -> *const z_bytes_t { + match query.transmute_ref().attachment() { + Some(attachment) => attachment.transmute_handle() as *const _, + None => null(), + } } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 9bc8e2459..d6a5e3696 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -83,8 +83,8 @@ pub struct ze_querying_subscriber_options_t { /// Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. #[no_mangle] -pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscriber_options_t { - ze_querying_subscriber_options_t { +pub extern "C" fn ze_querying_subscriber_options_default(this: &mut ze_querying_subscriber_options_t) { + *this = ze_querying_subscriber_options_t { reliability: Reliability::DEFAULT.into(), allowed_origin: zcu_locality_default(), query_selector: null(), @@ -92,7 +92,7 @@ pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscr query_consolidation: z_query_consolidation_none(), query_accept_replies: zcu_reply_keyexpr_default(), query_timeout_ms: 0, - } + }; } /// Declares a Querying Subscriber for a given key expression. @@ -130,8 +130,8 @@ pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscr #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn ze_declare_querying_subscriber( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&mut ze_querying_subscriber_options_t>, ) -> errors::z_error_t { @@ -179,8 +179,8 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn ze_querying_subscriber_get( - sub: ze_querying_subscriber_t, - selector: z_keyexpr_t, + sub: &ze_querying_subscriber_t, + selector: &z_keyexpr_t, options: Option<&z_get_options_t>, ) -> errors::z_error_t { unsafe impl Sync for z_get_options_t {} @@ -235,7 +235,7 @@ pub extern "C" fn ze_querying_subscriber_check(this: &ze_owned_querying_subscrib #[no_mangle] pub extern "C" fn ze_querying_subscriber_loan( this: &ze_owned_querying_subscriber_t, -) -> ze_querying_subscriber_t { +) -> &ze_querying_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/scouting.rs b/src/scouting.rs index 3d593852d..0f2f29c34 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -42,9 +42,9 @@ pub struct z_owned_str_array_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_str_array_drop(strs: &mut z_owned_str_array_t) { - let locators = Vec::from_raw_parts(strs.val as *mut *const c_char, strs.len, strs.len); - for locator in locators { - std::mem::drop(CString::from_raw(locator as *mut c_char)); + let vals = Vec::from_raw_parts(strs.val as *mut *const c_char, strs.len, strs.len); + for val in vals { + std::mem::drop(CString::from_raw(val as *mut c_char)); } strs.val = std::ptr::null_mut(); strs.len = 0; @@ -67,11 +67,8 @@ pub struct z_str_array_t { /// Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_str_array_loan(strs: &z_owned_str_array_t) -> z_str_array_t { - z_str_array_t { - val: strs.val as *const _, - len: strs.len, - } +pub unsafe extern "C" fn z_str_array_loan(strs: &z_owned_str_array_t) -> &z_str_array_t { + std::mem::transmute(strs) } /// A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. /// @@ -146,26 +143,23 @@ pub unsafe extern "C" fn z_hello_drop(hello: &mut z_owned_hello_t) { /// Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_hello_loan(hello: &z_owned_hello_t) -> z_hello_t { - z_hello_t { - whatami: hello._whatami, - pid: hello._pid, - locators: z_str_array_loan(&hello._locators), - } +pub unsafe extern "C" fn z_hello_loan(hello: &z_owned_hello_t) -> &z_hello_t { + std::mem::transmute(hello) } /// Constructs a gravestone value for hello, useful to steal one from a callback #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_hello_null() -> z_owned_hello_t { - z_owned_hello_t { +pub unsafe extern "C" fn z_hello_null(this: *mut MaybeUninit) { + let h = z_owned_hello_t { _whatami: 0, _pid: [0; 16].into(), _locators: z_owned_str_array_t { val: std::ptr::null_mut(), len: 0, }, - } + }; + (*this).write(h); } impl Drop for z_owned_hello_t { fn drop(&mut self) { @@ -224,8 +218,8 @@ pub unsafe extern "C" fn z_scouting_config_default( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_scouting_config_from( - config: z_config_t, this: *mut MaybeUninit, + config: &z_config_t, ) { let mut dst = MaybeUninit::uninit(); z_config_clone(&config, &mut dst as *mut _); @@ -281,7 +275,7 @@ pub extern "C" fn z_scout( std::mem::swap(&mut closure, callback); task::block_on(async move { - let scout = zenoh::scout(what, *config) + let scout = zenoh::scout(what, config) .callback(move |h| { let mut hello = h.into(); z_closure_hello_call(&closure, &mut hello) @@ -307,10 +301,10 @@ pub extern "C" fn z_scout( #[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; + return errors::Z_EINVAL; } match WhatAmIMatcher::try_from(whatami) { - Err(_) => -1, + Err(_) => errors::Z_EINVAL, Ok(w) => { let s = w.to_str(); let res = s.copy_to_c_array(buf as *mut c_void, len - 1); diff --git a/src/session.rs b/src/session.rs index 5079c50f0..194779201 100644 --- a/src/session.rs +++ b/src/session.rs @@ -38,7 +38,7 @@ decl_transmute_handle!(Session, z_session_t); /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(this: &'static z_owned_session_t) -> z_session_t { +pub extern "C" fn z_session_loan(this: & z_owned_session_t) -> &z_session_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); let this = this.as_ref(); @@ -64,7 +64,7 @@ pub extern "C" fn z_open( if cfg!(feature = "logger-autoinit") { zc_init_logger(); } - let config = match config.transmute_mut().take() { + let config = match config.transmute_mut().extract() { Some(c) => c, None => { log::error!("Config not provided"); @@ -72,7 +72,7 @@ pub extern "C" fn z_open( return errors::Z_EINVAL; } }; - match zenoh::open(*config).res() { + match zenoh::open(config).res() { Ok(s) => { Inplace::init(this, Some(Arc::new(s))); errors::Z_OK @@ -98,10 +98,10 @@ pub extern "C" fn z_session_check(this: &z_owned_session_t) -> bool { /// Returns the remaining reference count of the session otherwise, saturating at i8::MAX. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { +pub extern "C" fn z_close(session: &mut z_owned_session_t) -> errors::z_error_t { let session = session.transmute_mut(); let Some(s) = session.take() else { - return 0; + return errors::Z_OK; }; let s = match Arc::try_unwrap(s) { Ok(s) => s, @@ -111,22 +111,22 @@ pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { }; match s.close().res() { Err(e) => e.errno().get(), - Ok(_) => 0, + Ok(_) => errors::Z_OK, } } /// Increments the session's reference count, returning a new owning handle. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_session_rcinc( +pub extern "C" fn zc_session_clone( dst: *mut MaybeUninit, src: &z_owned_session_t, -) -> i8 { +) -> errors::z_error_t { // session.as_ref().as_ref().and_then(|s| s.upgrade()).into() let dst = dst.transmute_uninit_ptr(); let Some(src) = src.transmute_ref() else { - return -1; + return errors::Z_EINVAL; }; Inplace::init(dst, Some(src.clone())); - 0 + errors::Z_OK } diff --git a/src/subscriber.rs b/src/subscriber.rs index 81b1a8c4c..ad5d73e4d 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -77,7 +77,7 @@ pub extern "C" fn z_subscriber_null(this: *mut MaybeUninit /// Returns a :c:type:`z_subscriber_t` loaned from `this`. #[no_mangle] -pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> z_subscriber_t { +pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> &z_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -95,8 +95,8 @@ pub struct z_subscriber_options_t { /// Constructs the default value for :c:type:`z_subscriber_options_t`. #[no_mangle] -pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { - z_subscriber_options_t { +pub extern "C" fn z_subscriber_options_default(this: &mut z_subscriber_options_t) { + *this = z_subscriber_options_t { reliability: Reliability::DEFAULT.into(), } } @@ -136,8 +136,8 @@ pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_subscriber( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&mut z_subscriber_options_t>, ) -> errors::z_error_t { @@ -171,7 +171,7 @@ pub extern "C" fn z_declare_subscriber( /// Returns the key expression of the subscriber. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_keyexpr_t { +pub extern "C" fn z_subscriber_keyexpr(subscriber: &z_subscriber_t) -> &z_keyexpr_t { let subscriber = subscriber.transmute_ref(); subscriber.key_expr().transmute_handle() } diff --git a/src/transmute.rs b/src/transmute.rs index 5951a7137..b5d88a6dc 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -23,18 +23,24 @@ pub fn unwrap_ref_unchecked(value: &Option) -> &T { unsafe { value.as_ref().unwrap_unchecked() } } +pub fn unwrap_ref_unchecked_mut(value: &mut Option) -> &mut T { + debug_assert!(value.is_some()); + unsafe { value.as_mut().unwrap_unchecked() } +} + pub(crate) trait TransmuteRef: Sized { fn transmute_ref(&self) -> &T; fn transmute_mut(&mut self) -> &mut T; } pub(crate) trait TransmuteFromHandle: Sized { - fn transmute_ref(self) -> &'static T; - fn transmute_mut(self) -> &'static mut T; + fn transmute_ref(&self) -> &'static T; + fn transmute_mut(&mut self) -> &'static mut T; } pub(crate) trait TransmuteIntoHandle: Sized { - fn transmute_handle(&self) -> T; + fn transmute_handle(&self) -> &'static T; + fn transmute_handle_mut(&mut self) -> &'static mut T; } pub(crate) trait TransmuteCopy { @@ -200,16 +206,19 @@ macro_rules! impl_transmute_uninit_ptr { macro_rules! impl_transmute_handle { ($c_type:ty, $zenoh_type:ty) => { impl $crate::transmute::TransmuteFromHandle<$zenoh_type> for $c_type { - fn transmute_ref(self) -> &'static $zenoh_type { - unsafe { std::mem::transmute::<$c_type, &'static $zenoh_type>(self) } + fn transmute_ref(&self) -> &'static $zenoh_type { + unsafe { std::mem::transmute::<& $c_type, &'static $zenoh_type>(self) } } - fn transmute_mut(self) -> &'static mut $zenoh_type { - unsafe { std::mem::transmute::<$c_type, &'static mut $zenoh_type>(self) } + fn transmute_mut(&mut self) -> &'static mut $zenoh_type { + unsafe { std::mem::transmute::<&mut $c_type, &'static mut $zenoh_type>(self) } } } impl $crate::transmute::TransmuteIntoHandle<$c_type> for $zenoh_type { - fn transmute_handle(&self) -> $c_type { - unsafe { std::mem::transmute::<&$zenoh_type, $c_type>(self) } + fn transmute_handle(&self) -> &'static $c_type { + unsafe { std::mem::transmute::<&$zenoh_type, &'static $c_type>(self) } + } + fn transmute_handle_mut(&mut self) -> &'static mut $c_type { + unsafe { std::mem::transmute::<&mut $zenoh_type, &'static mut $c_type>(self) } } } }; From d0c513c7041dc1810e0d902696e0ec828e6b2bfe Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 25 Apr 2024 17:28:17 +0200 Subject: [PATCH 059/377] fixed api for view types --- build-resources/opaque-types/src/lib.rs | 17 + include/zenoh_commons.h | 262 ++++++++++----- include/zenoh_concrete.h | 1 + src/collections.rs | 429 ++++++++++-------------- src/config.rs | 31 +- src/errors.rs | 1 + src/keyexpr.rs | 87 +++-- src/payload.rs | 61 ++-- src/queryable.rs | 9 +- 9 files changed, 492 insertions(+), 406 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 3781c062c..4aba1525b 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -46,6 +46,21 @@ get_opaque_type_data!(Option, z_owned_bytes_t); /// A loaned payload. get_opaque_type_data!(ZBytes, z_bytes_t); +/// A contiguous view of bytes owned by some other entity. +/// +/// `start` being `null` is considered a gravestone value, +/// and empty slices are represented using a possibly dangling pointer for `start`. +get_opaque_type_data!(Option>, z_owned_slice_t); +get_opaque_type_data!(Option<&'static [u8]>, z_view_slice_t); +get_opaque_type_data!(&'static [u8], z_slice_t); + +/// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` +/// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with +/// `z_check` and `z_str_check` correspondently +get_opaque_type_data!(Option>, z_owned_str_t); +get_opaque_type_data!(Option<&'static [u8]>, z_view_str_t); +get_opaque_type_data!(&'static [u8], z_str_t); + /// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher @@ -141,6 +156,8 @@ get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Sess /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_keyexpr_t); +get_opaque_type_data!(Option>, z_view_keyexpr_t); + /// A loaned key expression. /// /// Key expressions can identify a single key or a set of keys. diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 0a3a59df7..7a3f071e8 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -129,9 +129,14 @@ typedef struct ALIGN(8) z_bytes_t { uint8_t _0[40]; } z_bytes_t; typedef int8_t z_error_t; -typedef struct z_owned_slice_t { - const uint8_t *start; - size_t len; +/** + * A contiguous view of bytes owned by some other entity. + * + * `start` being `null` is considered a gravestone value, + * and empty slices are represented using a possibly dangling pointer for `start`. + */ +typedef struct ALIGN(8) z_owned_slice_t { + uint8_t _0[16]; } z_owned_slice_t; /** * A map of maybe-owned vector of bytes to maybe-owned vector of bytes. @@ -146,22 +151,18 @@ typedef struct ALIGN(8) z_owned_slice_map_t { * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with * `z_check` and `z_str_check` correspondently */ -typedef struct z_owned_str_t { - char *_cstr; +typedef struct ALIGN(8) z_owned_str_t { + uint8_t _0[16]; } z_owned_str_t; -/** - * A contiguous view of bytes owned by some other entity. - * - * `start` being `null` is considered a gravestone value, - * and empty slices are represented using a possibly dangling pointer for `start`. - */ -typedef struct z_slice_t { - const uint8_t *start; - size_t len; +typedef struct ALIGN(8) z_slice_t { + uint8_t _0[16]; } z_slice_t; typedef struct ALIGN(8) z_slice_map_t { uint8_t _0[48]; } z_slice_map_t; +typedef struct ALIGN(8) z_str_t { + uint8_t _0[16]; +} z_str_t; /** * A reader for payload data. */ @@ -545,6 +546,12 @@ typedef struct z_hello_t { struct z_id_t pid; struct z_str_array_t locators; } z_hello_t; +typedef struct ALIGN(8) z_view_slice_t { + uint8_t _0[16]; +} z_view_slice_t; +typedef struct ALIGN(8) z_view_keyexpr_t { + uint8_t _0[32]; +} z_view_keyexpr_t; typedef struct ALIGN(8) z_owned_mutex_t { uint8_t _0[32]; } z_owned_mutex_t; @@ -705,6 +712,9 @@ typedef struct z_task_attr_t { typedef struct z_time_t { uint64_t t; } z_time_t; +typedef struct ALIGN(8) z_view_str_t { + uint8_t _0[16]; +} z_view_str_t; /** * The options for `zc_liveliness_declare_token` */ @@ -913,7 +923,7 @@ void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, /** * Encodes a null-terminated string by aliasing. */ -ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const char *cstr); +ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const struct z_str_t *s); /** * Returns total number bytes in the payload. */ @@ -1328,25 +1338,12 @@ z_error_t z_info_routers_zid(struct z_session_t session, * to pass it a valid session. */ ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API z_error_t z_keyexpr(struct z_keyexpr_t *this_, const char *name); /** * Returns the key expression's internal string by aliasing it. * * Currently exclusive to zenoh-c */ -ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(const struct z_keyexpr_t *ke); -/** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. - * 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 -z_error_t z_keyexpr_autocanonize(struct z_keyexpr_t *this_, - char *name); +ZENOHC_API void z_keyexpr_as_bytes(const struct z_keyexpr_t *ke, struct z_view_slice_t *b); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. * @@ -1453,7 +1450,7 @@ enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_keyexpr * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. * The user is responsible of droping the returned string using `z_drop` */ -ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(const struct z_keyexpr_t *ke); +ZENOHC_API void z_keyexpr_to_string(const struct z_keyexpr_t *ke, struct z_owned_str_t *s); /** * Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: * @@ -1467,7 +1464,7 @@ ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(const struct z_keyexpr_t *ke * It is a loaned key expression that aliases `name`. */ ZENOHC_API -void z_keyexpr_unchecked(struct z_keyexpr_t *this_, +void z_keyexpr_unchecked(struct z_view_keyexpr_t *this_, const char *name); ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); @@ -1484,6 +1481,10 @@ ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t this_); ZENOHC_API z_error_t z_open(struct z_owned_session_t *this_, struct z_owned_config_t *config); +/** + * Returns ``true`` if `this` is initialized. + */ +ZENOHC_API bool z_owned_slice_check(const struct z_owned_slice_t *this_); /** * Returns ``true`` if `pub` is valid. */ @@ -1665,7 +1666,8 @@ ZENOHC_API void z_query_null(struct z_owned_query_t *this_); * Get a query's `value selector `_ by aliasing it. */ ZENOHC_API -struct z_slice_t z_query_parameters(const struct z_query_t *query); +void z_query_parameters(const struct z_query_t *query, + struct z_view_slice_t *parameters); /** * Send a reply to a query. * @@ -1873,30 +1875,26 @@ ZENOHC_API void z_session_null(struct z_owned_session_t *this_); ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); -ZENOHC_API void z_slice_clone(struct z_owned_slice_t *this_, const struct z_slice_t *s); +ZENOHC_API void z_slice_clone(const struct z_slice_t *this_, struct z_owned_slice_t *dst); +ZENOHC_API const uint8_t *z_slice_data(const struct z_slice_t *this_); /** * Frees `this` and invalidates it for double-drop safety. */ ZENOHC_API void z_slice_drop(struct z_owned_slice_t *this_); /** - * Returns the gravestone value for `z_slice_t` + * Returns an empty `z_owned_slice_t` */ -ZENOHC_API struct z_slice_t z_slice_empty(void); +ZENOHC_API void z_slice_empty(struct z_owned_slice_t *this_); /** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * Copies a string into `z_owned_slice_t` using `strlen` (this should therefore not be used with untrusted inputs). * - * `str == NULL` will cause this to return `z_slice_empty()` + * Calling this with `str == NULL` is equivalent to `z_slice_null`. */ -ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *this_); -ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); +ZENOHC_API +void z_slice_from_str(struct z_owned_slice_t *this_, + const char *str); +ZENOHC_API size_t z_slice_len(const struct z_slice_t *this_); +ZENOHC_API const struct z_slice_t *z_slice_loan(const struct z_owned_slice_t *this_); /** * Returns `true` if the map is not in its gravestone state */ @@ -1908,18 +1906,19 @@ ZENOHC_API bool z_slice_map_check(const struct z_owned_slice_map_t *map); */ ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); /** - * Returns the value associated with `key`, returning a gravestone value if: - * - `key` is in gravestone state. + * Returns the value associated with `key`. + * + * Will return NULL if the key is not present in the map. */ ZENOHC_API -struct z_slice_t z_slice_map_get(const struct z_slice_map_t *this_, - const struct z_slice_t *key); +const struct z_slice_t *z_slice_map_get(const struct z_slice_map_t *this_, + const struct z_slice_t *key); /** * Associates `value` to `key` in the map, aliasing them. * * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. * - * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t *this_, @@ -1928,12 +1927,12 @@ z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t *this_, /** * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. * - * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API -z_error_t z_slice_map_insert_by_copy(struct z_slice_map_t *this_, - const struct z_slice_t *key, - const struct z_slice_t *value); +uint8_t z_slice_map_insert_by_copy(struct z_slice_map_t *this_, + const struct z_slice_t *key, + const struct z_slice_t *value); /** * Returns true if the map is empty, false otherwise. */ @@ -1956,14 +1955,11 @@ ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); * Constructs the gravestone value for `z_owned_slice_map_t` */ ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); -/** - * Returns the gravestone value for `z_owned_slice_t` - */ ZENOHC_API void z_slice_null(struct z_owned_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. */ -ZENOHC_API struct z_slice_t z_slice_wrap(uint8_t *start, size_t len); +ZENOHC_API void z_slice_wrap(struct z_owned_slice_t *this_, const uint8_t *start, size_t len); /** * Returns ``true`` if `strs` is valid. */ @@ -1979,19 +1975,35 @@ ZENOHC_API const struct z_str_array_t *z_str_array_loan(const struct z_owned_str /** * Returns ``true`` if `s` is a valid string */ -ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); +ZENOHC_API bool z_str_check(const struct z_owned_str_t *this_); +ZENOHC_API void z_str_clone(const struct z_str_t *this_, struct z_owned_str_t *dst); /** * Frees `z_owned_str_t`, invalidating it for double-drop safety. */ -ZENOHC_API void z_str_drop(struct z_owned_str_t *s); +ZENOHC_API void z_str_drop(struct z_owned_str_t *this_); +ZENOHC_API void z_str_empty(struct z_owned_str_t *this_); +/** + * Copies a a substring of length `len`into `z_owned_str_t`. + * + * Calling this with `str == NULL` is equivalent to `z_str_null`. + */ +ZENOHC_API void z_str_from_substring(struct z_owned_str_t *this_, const char *str, size_t len); /** * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. */ -ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); +ZENOHC_API const struct z_str_t *z_str_loan(const struct z_owned_str_t *this_); /** * Returns undefined `z_owned_str_t` */ ZENOHC_API void z_str_null(struct z_owned_str_t *this_); +/** + * Copies a string into `z_owned_str_t` using `strlen` (this should therefore not be used with untrusted inputs). + * + * Calling this with `str == NULL` is equivalent to `z_str_null`. + */ +ZENOHC_API +void z_str_wrap(struct z_owned_slice_t *this_, + const char *str); /** * Returns ``true`` if `sub` is valid. */ @@ -2058,6 +2070,95 @@ ZENOHC_API z_error_t z_undeclare_queryable(struct z_owned_queryable_t *qable); */ ZENOHC_API z_error_t z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API z_error_t z_view_keyexpr(struct z_view_keyexpr_t *this_, const char *name); +/** + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * 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 +z_error_t z_view_keyexpr_autocanonize(struct z_view_keyexpr_t *this_, + char *name); +/** + * Returns ``true`` if `keyexpr` is valid. + */ +ZENOHC_API bool z_view_keyexpr_check(const struct z_view_keyexpr_t *keyexpr); +/** + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + */ +ZENOHC_API +z_error_t z_view_keyexpr_from_slice(struct z_view_keyexpr_t *this_, + const char *name, + size_t len); +/** + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * 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 +z_error_t z_view_keyexpr_from_slice_autocanonize(struct z_view_keyexpr_t *this_, + char *name, + size_t *len); +/** + * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. + * - any instance of ``**`` may only be lead or followed by ``/``. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +void z_view_keyexpr_from_slice_unchecked(struct z_view_keyexpr_t *this_, + const char *start, + size_t len); +/** + * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + */ +ZENOHC_API const struct z_keyexpr_t *z_view_keyexpr_loan(const struct z_view_keyexpr_t *key_expr); +ZENOHC_API void z_view_keyexpr_null(struct z_view_keyexpr_t *this_); +/** + * Returns ``true`` if `this` is initialized. + */ +ZENOHC_API bool z_view_slice_check(const struct z_view_slice_t *this_); +/** + * Returns an empty `z_view_slice_t` + */ +ZENOHC_API void z_view_slice_empty(struct z_view_slice_t *this_); +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * Calling this with `str == NULL` is equivalent to `z_view_slice_null`. + */ +ZENOHC_API void z_view_slice_from_str(struct z_view_slice_t *this_, const char *str); +ZENOHC_API const struct z_slice_t *z_view_slice_loan(const struct z_view_slice_t *this_); +ZENOHC_API void z_view_slice_null(struct z_view_slice_t *this_); +/** + * Constructs a `len` bytes long view starting at `start`. + */ +ZENOHC_API void z_view_slice_wrap(struct z_view_slice_t *this_, const uint8_t *start, size_t len); +ZENOHC_API const char *z_view_str_data(const struct z_str_t *this_); +ZENOHC_API void z_view_str_empty(struct z_view_str_t *this_); +ZENOHC_API size_t z_view_str_len(const struct z_str_t *this_); +/** + * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_view_str_t`. + */ +ZENOHC_API const struct z_str_t *z_view_str_loan(const struct z_view_str_t *this_); +/** + * Returns undefined `z_owned_str_t` + */ +ZENOHC_API void z_view_str_null(struct z_view_str_t *this_); +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * Calling this with `str == NULL` is equivalent to `z_view_str_null`. + */ +ZENOHC_API void z_view_str_wrap(struct z_view_slice_t *this_, const char *str); /** * Converts the kind of zenoh entity into a string. * @@ -2089,8 +2190,9 @@ z_error_t zc_config_from_str(struct z_owned_config_t *this_, * Use `z_drop` to safely deallocate this string */ ZENOHC_API -struct z_owned_str_t zc_config_get(struct z_config_t config, - const char *key); +z_error_t zc_config_get(struct z_config_t config, + const char *key, + struct z_owned_str_t *value_string); /** * Inserts a JSON-serialized `value` at the `key` position of the configuration. * @@ -2104,7 +2206,8 @@ z_error_t zc_config_insert_json(const struct z_config_t *config, * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. */ ZENOHC_API -struct z_owned_str_t zc_config_to_string(const struct z_config_t *config); +z_error_t zc_config_to_string(const struct z_config_t *config, + struct z_owned_str_t *config_string); /** * Initialises the zenoh runtime logger. * @@ -2112,33 +2215,6 @@ struct z_owned_str_t zc_config_to_string(const struct z_config_t *config); * this will be performed automatically by `z_open` and `z_scout`. */ ZENOHC_API void zc_init_logger(void); -/** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. - */ -ZENOHC_API z_error_t zc_keyexpr_from_slice(struct z_keyexpr_t *this_, const char *name, size_t len); -/** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. - * 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 -z_error_t zc_keyexpr_from_slice_autocanonize(struct z_keyexpr_t *this_, - char *name, - size_t *len); -/** - * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. - * - any instance of ``**`` may only be lead or followed by ``/``. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -void zc_keyexpr_from_slice_unchecked(struct z_keyexpr_t *this_, - const char *start, - size_t len); ZENOHC_API void zc_liveliness_declaration_options_default(struct zc_liveliness_declaration_options_t *this_); /** diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 03f29535b..a7cc575ab 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -78,6 +78,7 @@ typedef struct ALIGN(8) z_owned_subscriber_t { #define Z_EIO -3 #define Z_ENETWORK -4 #define Z_ENULL -5 +#define Z_EUNAVAILABLE -6 #define Z_EBUSY_MUTEX -16 #define Z_EINVAL_MUTEX -22 #define Z_EAGAIN_MUTEX -11 diff --git a/src/collections.rs b/src/collections.rs index f24d7d075..e8c9039ee 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -16,136 +16,108 @@ use std::borrow::Cow; use std::collections::HashMap; use std::mem::MaybeUninit; use std::ptr::{null, null_mut}; +use std::slice::from_raw_parts; -use libc::{c_char, c_void, size_t}; +use libc::{c_char, c_void, size_t, strlen}; use zenoh::prelude::ZenohId; -use crate::errors; +use crate::{errors, transmute, z_owned_bytes_t}; use crate::transmute::{ unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; -/// A contiguous view of bytes owned by some other entity. -/// -/// `start` being `null` is considered a gravestone value, -/// and empty slices are represented using a possibly dangling pointer for `start`. -#[repr(C)] -#[derive(Clone, Copy, Debug)] -pub struct z_slice_t { - pub start: *const u8, - pub len: size_t, -} - -impl z_slice_t { - pub fn as_slice(&self) -> Option<&'static [u8]> { - if self.start.is_null() { - return None; - } - Some(unsafe { core::slice::from_raw_parts(self.start, self.len) }) - } - pub fn empty() -> Self { - z_slice_t { - start: std::ptr::null_mut(), - len: 0, - } - } -} +pub use crate::opaque_types::z_owned_slice_t; +pub use crate::opaque_types::z_view_slice_t; +pub use crate::opaque_types::z_slice_t; -impl Default for z_slice_t { - fn default() -> Self { - Self::empty() - } -} +decl_transmute_owned!(Option>, z_owned_slice_t); +decl_transmute_owned!(Option<&'static [u8]>, z_view_slice_t); +decl_transmute_handle!(&'static [u8], z_slice_t); -#[repr(C)] -#[derive(Clone, Debug)] -pub struct z_owned_slice_t { - pub start: *const u8, - pub len: size_t, +/// Returns an empty `z_view_slice_t` +#[no_mangle] +pub unsafe extern "C" fn z_view_slice_empty(this: *mut MaybeUninit) { + let slice: &'static [u8] = &[]; + Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } -impl Drop for z_owned_slice_t { - fn drop(&mut self) { - unsafe { z_slice_drop(self) } - } +#[no_mangle] +pub unsafe extern "C" fn z_view_slice_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } -impl z_owned_slice_t { - pub fn null() -> z_owned_slice_t { - z_owned_slice_t { - start: null(), - len: 0 - } - } - pub fn new(data: &[u8]) -> z_owned_slice_t { - if data.is_empty() { - return Self::null(); - } - let data = data.to_vec().into_boxed_slice(); - z_owned_slice_t { - len: data.len(), - start: Box::leak(data).as_mut_ptr(), - } - } - - pub fn preallocate(len: usize) -> z_owned_slice_t { - let data = vec![0u8; len].into_boxed_slice(); - z_owned_slice_t { - len, - start: Box::leak(data).as_mut_ptr(), - } +/// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +/// +/// Calling this with `str == NULL` is equivalent to `z_view_slice_null`. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_view_slice_from_str(this: *mut MaybeUninit, str: *const c_char) { + if str.is_null() { + z_view_slice_null(this) + } else { + z_view_slice_wrap(this, str as *const u8, libc::strlen(str)) } +} - #[allow(clippy::missing_safety_doc)] - pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping(value.as_ptr(), self.start.add(start) as *mut u8, value.len()); +/// Constructs a `len` bytes long view starting at `start`. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_view_slice_wrap(this: *mut MaybeUninit, start: *const u8, len: usize) { + if len == 0 { + z_view_slice_empty(this) + } else if start.is_null() { + z_view_slice_null(this) + } else { + let slice: &'static [u8] = from_raw_parts(start, len).into(); + Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } } -impl Default for z_owned_slice_t { - fn default() -> Self { - Self::null() +#[no_mangle] +pub const extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_slice_t { + match this.transmute_ref() { + Some(s) => s.transmute_handle(), + None => null(), } } -/// Returns ``true`` if `b` is initialized. +/// Returns an empty `z_owned_slice_t` #[no_mangle] -pub extern "C" fn z_slice_is_initialized(this: &z_slice_t) -> bool { - !this.start.is_null() +pub unsafe extern "C" fn z_slice_empty(this: *mut MaybeUninit) { + let slice = Box::new([]); + Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } -/// Returns the gravestone value for `z_slice_t` #[no_mangle] -pub const extern "C" fn z_slice_empty() -> z_slice_t { - z_slice_t::empty() +pub extern "C" fn z_slice_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } -/// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +/// Copies a string into `z_owned_slice_t` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_slice_empty()` +/// Calling this with `str == NULL` is equivalent to `z_slice_null`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_from_str(str: *const c_char) -> z_slice_t { +pub unsafe extern "C" fn z_slice_from_str(this: *mut MaybeUninit, str: *const c_char) { if str.is_null() { - z_slice_empty() + z_slice_null(this) } else { - let len = unsafe { libc::strlen(str) }; - z_slice_t { - len, - start: str.cast_mut() as *mut u8, - } + z_slice_wrap(this, str as *const u8, libc::strlen(str)) } } /// Constructs a `len` bytes long view starting at `start`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_wrap(start: *mut u8, len: usize) -> z_slice_t { - if start.is_null() { - z_slice_empty() +pub unsafe extern "C" fn z_slice_wrap(this: *mut MaybeUninit, start: *const u8, len: usize) { + if len == 0 { + z_slice_empty(this) + } else if start.is_null() { + z_slice_null(this) } else { - z_slice_t { len, start } + let slice = from_raw_parts(start, len).to_owned().into_boxed_slice(); + Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } } @@ -153,182 +125,146 @@ pub unsafe extern "C" fn z_slice_wrap(start: *mut u8, len: usize) -> z_slice_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { - if !this.start.is_null() { - std::mem::drop(Box::from_raw( - core::ptr::slice_from_raw_parts(this.start, this.len).cast_mut(), - )); - this.start = std::ptr::null_mut(); - this.len = 0; - } + let this = this.transmute_mut(); + Inplace::drop(this); } -/// Returns the gravestone value for `z_owned_slice_t` #[no_mangle] -pub unsafe extern "C" fn z_slice_null(this: *mut MaybeUninit) { - (*this).as_mut_ptr().write(z_owned_slice_t { - len: 0, - start: core::ptr::null_mut(), - }); +pub const extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { + match this.transmute_ref() { + Some(s) => (&&*s.as_ref()) as *const &[u8] as *const z_slice_t, + None => null(), + } } #[no_mangle] -pub const extern "C" fn z_slice_loan(b: &z_owned_slice_t) -> z_slice_t { - z_slice_t { - len: b.len, - start: b.start, - } +pub unsafe extern "C" fn z_slice_clone(this: &z_slice_t, dst: *mut MaybeUninit) { + let slice = this.transmute_ref().to_vec().into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); } +/// Returns ``true`` if `this` is initialized. #[no_mangle] -pub unsafe extern "C" fn z_slice_clone(this: *mut MaybeUninit, s: &z_slice_t) { - if !z_slice_is_initialized(s) { - z_slice_null(this); - } else { - (*this).as_mut_ptr().write(z_owned_slice_t::new(unsafe { std::slice::from_raw_parts(s.start, s.len) })); - } +pub extern "C" fn z_owned_slice_check(this: &z_owned_slice_t) -> bool { + this.transmute_ref().is_some() } -/// Returns ``true`` if `b` is initialized. +/// Returns ``true`` if `this` is initialized. #[no_mangle] -pub extern "C" fn z_slice_check(b: &z_owned_slice_t) -> bool { - !b.start.is_null() +pub extern "C" fn z_view_slice_check(this: &z_view_slice_t) -> bool { + this.transmute_ref().is_some() } -impl From for z_slice_t { - #[inline] - fn from(pid: ZenohId) -> Self { - let pid = pid.to_le_bytes().to_vec().into_boxed_slice(); - let res = z_slice_t { - start: pid.as_ptr(), - len: pid.len() as size_t, - }; - std::mem::forget(pid); - res - } +#[no_mangle] +pub extern "C" fn z_slice_len(this: &z_slice_t) -> usize { + this.transmute_ref().len() } -impl From> for z_slice_t { - #[inline] - fn from(pid: Option) -> Self { - match pid { - Some(pid) => pid.into(), - None => z_slice_t { - start: std::ptr::null(), - len: 0, - }, - } - } +#[no_mangle] +pub extern "C" fn z_slice_data(this: &z_slice_t) -> *const u8 { + this.transmute_ref().as_ptr() } -impl From for String { - fn from(s: z_slice_t) -> Self { - unsafe { - String::from_utf8( - Box::from_raw(std::slice::from_raw_parts_mut(s.start as *mut u8, s.len)).into(), - ) - .unwrap() - } - } + +pub use crate::opaque_types::z_owned_str_t; +pub use crate::opaque_types::z_view_str_t; +pub use crate::opaque_types::z_str_t; + +decl_transmute_owned!(custom_inplace_init Option>, z_owned_str_t); +decl_transmute_owned!(custom_inplace_init Option<&'static [u8]>, z_view_str_t); +decl_transmute_handle!(&'static [u8], z_str_t); + + +/// Frees `z_owned_str_t`, invalidating it for double-drop safety. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_str_drop(this: &mut z_owned_str_t) { + z_slice_drop(this.transmute_mut().transmute_mut()); } -impl From<&[u8]> for z_slice_t { - fn from(s: &[u8]) -> Self { - z_slice_t { - start: s.as_ptr(), - len: s.len(), - } - } +/// Returns ``true`` if `s` is a valid string +#[no_mangle] +pub extern "C" fn z_str_check(this: &z_owned_str_t) -> bool { + z_owned_slice_check(this.transmute_ref().transmute_ref()) } -impl InplaceDefault for z_owned_slice_t {} +/// Returns undefined `z_owned_str_t` +#[no_mangle] +pub extern "C" fn z_str_null(this: *mut MaybeUninit) { + z_slice_null(this as *mut _) +} -/// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` -/// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with -/// `z_check` and `z_str_check` correspondently -#[repr(C)] -pub struct z_owned_str_t { - pub _cstr: *mut libc::c_char, +/// Returns undefined `z_owned_str_t` +#[no_mangle] +pub extern "C" fn z_view_str_null(this: *mut MaybeUninit) { + z_slice_null(this as *mut _) } -impl z_owned_str_t { - pub fn null() -> z_owned_str_t { - z_owned_str_t { - _cstr: null_mut() - } - } - #[allow(clippy::missing_safety_doc)] - pub unsafe fn preallocate(len: usize) -> z_owned_str_t { - let cstr = libc::malloc(len + 1) as *mut libc::c_char; - *cstr.add(len) = 0; - z_owned_str_t { _cstr: cstr } - } +#[no_mangle] +pub unsafe extern "C" fn z_str_empty(this: *mut MaybeUninit) { + z_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) +} - #[allow(clippy::missing_safety_doc)] - pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping( - value.as_ptr(), - (self._cstr as *mut u8).add(start), - value.len(), - ); - } +#[no_mangle] +pub unsafe extern "C" fn z_view_str_empty(this: *mut MaybeUninit) { + z_view_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) } -impl From<&[u8]> for z_owned_str_t { - fn from(value: &[u8]) -> Self { - unsafe { - let mut cstr = Self::preallocate(value.len()); - cstr.insert_unchecked(0, value); - cstr - } - } +/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. +#[no_mangle] +pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> *const z_str_t { + z_slice_loan(this.transmute_ref().transmute_ref()) as _ } -impl Drop for z_owned_str_t { - fn drop(&mut self) { - unsafe { z_str_drop(self) } - } +/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_view_str_t`. +#[no_mangle] +pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_str_t { + z_view_slice_loan(this.transmute_ref().transmute_ref()) as _ } -impl Default for z_owned_str_t { - fn default() -> Self { - Self::null() - } + +/// Copies a string into `z_owned_str_t` using `strlen` (this should therefore not be used with untrusted inputs). +/// +/// Calling this with `str == NULL` is equivalent to `z_str_null`. +#[no_mangle] +pub unsafe extern "C" fn z_str_wrap(this: *mut MaybeUninit, str: *const libc::c_char) { + z_slice_wrap(this as *mut _, str as _, strlen(str) + 1) } -/// Frees `z_owned_str_t`, invalidating it for double-drop safety. +/// Copies a a substring of length `len`into `z_owned_str_t`. +/// +/// Calling this with `str == NULL` is equivalent to `z_str_null`. #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_str_drop(s: &mut z_owned_str_t) { - if s._cstr.is_null() { - return; - } - libc::free(std::mem::transmute(s._cstr)); - s._cstr = std::ptr::null_mut(); +pub unsafe extern "C" fn z_str_from_substring(this: *mut MaybeUninit, str: *const libc::c_char, len: usize) { + let mut v = vec![0u8; len + 1]; + v[0..len].copy_from_slice(from_raw_parts(str as *const u8, len)); + let b = v.into_boxed_slice(); + Inplace::init(this.transmute_uninit_ptr(), Some(b)); } -/// Returns ``true`` if `s` is a valid string +/// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +/// +/// Calling this with `str == NULL` is equivalent to `z_view_str_null`. #[no_mangle] -pub extern "C" fn z_str_check(s: &z_owned_str_t) -> bool { - !s._cstr.is_null() +pub unsafe extern "C" fn z_view_str_wrap(this: *mut MaybeUninit, str: *const libc::c_char) { + z_view_slice_wrap(this as *mut _, str as _, strlen(str) + 1) } -/// Returns undefined `z_owned_str_t` #[no_mangle] -pub unsafe extern "C" fn z_str_null(this: *mut MaybeUninit) { - (*this).as_mut_ptr().write( - z_owned_str_t { - _cstr: std::ptr::null_mut(), - } - ); +pub extern "C" fn z_view_str_len(this: &z_str_t) -> usize { + z_slice_len(this.transmute_ref().transmute_handle()) - 1 } -/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. #[no_mangle] -pub extern "C" fn z_str_loan(s: &z_owned_str_t) -> *const libc::c_char { - s._cstr +pub extern "C" fn z_view_str_data(this: &z_str_t) -> *const libc::c_char { + z_slice_data(&this.transmute_ref().transmute_handle()) as _ } -impl InplaceDefault for z_owned_str_t {} +#[no_mangle] +pub extern "C" fn z_str_clone(this: &z_str_t, dst: *mut MaybeUninit) { + let slice = this.transmute_ref().to_vec().into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); +} pub use crate::opaque_types::z_owned_slice_map_t; pub use crate::opaque_types::z_slice_map_t; @@ -421,43 +357,42 @@ pub extern "C" fn z_slice_map_iterate( ) { let this = this.transmute_ref(); for (key, value) in this { - let key_slice = key.as_ref().into(); - let value_slice = value.as_ref().into(); - if !body(&key_slice, &value_slice, context) { + let key_slice = key.as_ref(); + let value_slice = value.as_ref(); + if !body(key_slice.transmute_handle(), value_slice.transmute_handle(), context) { break; } } } -/// Returns the value associated with `key`, returning a gravestone value if: -/// - `key` is in gravestone state. +/// Returns the value associated with `key`. +/// +/// Will return NULL if the key is not present in the map. #[no_mangle] -pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> z_slice_t { - if !z_slice_is_initialized(&key) { - return z_slice_empty(); - } +pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *const z_slice_t { let m = this.transmute_ref(); - let key = key.as_slice().unwrap(); - m.get(key) - .map(|s| s.as_ref().into()) - .unwrap_or(z_slice_empty()) + let key = *key.transmute_ref(); + let k = Cow::Borrowed(key); + m.get(&k) + .map(|s| s.as_ref().transmute_handle() as *const _) + .unwrap_or(null()) } /// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. -/// -/// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. +/// +/// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_copy( this: &mut z_slice_map_t, key: &z_slice_t, value: &z_slice_t, -) -> errors::z_error_t { +) -> u8 { let this = this.transmute_mut(); - if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { - this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); - errors::Z_OK - } else { - errors::Z_EINVAL + let key = *key.transmute_ref(); + let value = *value.transmute_ref(); + match this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())) { + Some(_) => 1, + None => 0, } } @@ -465,7 +400,7 @@ pub extern "C" fn z_slice_map_insert_by_copy( /// /// Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. /// -/// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. +/// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_alias( this: &mut z_slice_map_t, @@ -473,10 +408,10 @@ pub extern "C" fn z_slice_map_insert_by_alias( value: &z_slice_t, ) -> errors::z_error_t { let this = this.transmute_mut(); - if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { - this.insert(Cow::Borrowed(key), Cow::Borrowed(value)); - errors::Z_OK - } else { - errors::Z_EINVAL + let key = key.transmute_ref(); + let value = value.transmute_ref(); + match this.insert(Cow::Borrowed(key), Cow::Borrowed(value)) { + Some(_) => 1, + None => 0, } } diff --git a/src/config.rs b/src/config.rs index a837136ec..73ac24b02 100644 --- a/src/config.rs +++ b/src/config.rs @@ -21,7 +21,7 @@ use crate::transmute::{ unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; -use crate::{errors, z_owned_str_t}; +use crate::{errors, z_owned_str_t, z_str_from_substring, z_str_null}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -114,16 +114,25 @@ pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit z_owned_str_t { +pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char, value_string: *mut MaybeUninit) -> errors::z_error_t { let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, - Err(_) => return z_owned_str_t::null(), + Err(_) => { + z_str_null(value_string); + return errors::Z_EINVAL; + } }; let val = config.get_json(key).ok(); match val { - Some(val) => val.as_bytes().into(), - None => z_owned_str_t::null(), + Some(val) => { + z_str_from_substring(value_string, val.as_ptr() as *const libc::c_char, val.len()); + errors::Z_OK + } + None => { + z_str_null(value_string); + errors::Z_EUNAVAILABLE + } } } @@ -189,11 +198,17 @@ pub unsafe extern "C" fn zc_config_from_str( /// Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_config_to_string(config: &z_config_t) -> z_owned_str_t { +pub extern "C" fn zc_config_to_string(config: &z_config_t, config_string: *mut MaybeUninit) -> errors::z_error_t { let config: &Config = config.transmute_ref(); match json5::to_string(config) { - Ok(s) => s.as_bytes().into(), - Err(_) => z_owned_str_t::null(), + Ok(s) => { + unsafe { z_str_from_substring(config_string, s.as_ptr() as *const libc::c_char, s.len()) }; + errors::Z_OK + } + Err(_) => { + z_str_null(config_string); + errors::Z_EPARSE + }, } } diff --git a/src/errors.rs b/src/errors.rs index cf494f4e0..c2abfbff4 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -5,6 +5,7 @@ pub const Z_EPARSE: z_error_t = -2; pub const Z_EIO: z_error_t = -3; pub const Z_ENETWORK: z_error_t = -4; pub const Z_ENULL: z_error_t = -5; +pub const Z_EUNAVAILABLE: z_error_t = -6; // negativ pthread error codes (due to convention to return negative values on error) pub const Z_EBUSY_MUTEX: z_error_t = -16; pub const Z_EINVAL_MUTEX: z_error_t = -22; diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 4f07fd624..a930b8cc6 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -23,9 +23,14 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; +use crate::z_owned_slice_t; use crate::z_owned_str_t; use crate::z_session_t; use crate::z_slice_t; +use crate::z_str_from_substring; +use crate::z_view_slice_from_str; +use crate::z_view_slice_t; +use crate::z_view_slice_wrap; use libc::c_char; use std::error::Error; use zenoh::core::SyncResolve; @@ -34,15 +39,21 @@ use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; pub use crate::opaque_types::z_owned_keyexpr_t; +pub use crate::opaque_types::z_view_keyexpr_t; decl_transmute_owned!(Option>, z_owned_keyexpr_t); +decl_transmute_owned!(custom_inplace_init Option>, z_view_keyexpr_t); /// Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type #[no_mangle] -#[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } +#[no_mangle] +pub extern "C" fn z_view_keyexpr_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); +} + fn keyexpr_create_inner( mut name: &'static mut str, should_auto_canonize: bool, @@ -91,11 +102,12 @@ pub unsafe extern "C" fn z_keyexpr_new( name: *const c_char, this: *mut MaybeUninit, ) -> errors::z_error_t { + let this = this.transmute_uninit_ptr(); if name.is_null() { + Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); - let this = this.transmute_uninit_ptr(); match keyexpr_create(name, false, true) { Ok(ke) => { Inplace::init(this, Some(ke)); @@ -115,11 +127,12 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize( name: *const c_char, this: *mut MaybeUninit, ) -> z_error_t { + let this = this.transmute_uninit_ptr(); if name.is_null() { + Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); - let this = this.transmute_uninit_ptr(); match keyexpr_create(name, true, true) { Ok(ke) => { Inplace::init(this, Some(ke)); @@ -138,20 +151,30 @@ pub extern "C" fn z_keyexpr_loan(key_expr: &z_owned_keyexpr_t) -> &z_keyexpr_t { unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } +/// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. +#[no_mangle] +pub extern "C" fn z_view_keyexpr_loan(key_expr: &z_view_keyexpr_t) -> &z_keyexpr_t { + unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() +} + /// Frees `keyexpr` and invalidates it for double-drop safety. #[no_mangle] -#[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_drop(keyexpr: &mut z_owned_keyexpr_t) { Inplace::drop(keyexpr.transmute_mut()); } /// Returns ``true`` if `keyexpr` is valid. #[no_mangle] -#[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { keyexpr.transmute_ref().is_some() } +/// Returns ``true`` if `keyexpr` is valid. +#[no_mangle] +pub extern "C" fn z_view_keyexpr_check(keyexpr: &z_view_keyexpr_t) -> bool { + keyexpr.transmute_ref().is_some() +} + /// A loaned key expression. /// /// Key expressions can identify a single key or a set of keys. @@ -219,21 +242,24 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) /// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_keyexpr_from_slice( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr_from_slice( + this: *mut MaybeUninit, name: *const c_char, len: usize, ) -> z_error_t { + let this = this.transmute_uninit_ptr(); if name.is_null() { + Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, len); match keyexpr_create(name, false, false) { Ok(ke) => { - (*this).write(std::mem::transmute(ke)); + Inplace::init(this, Some(ke)); errors::Z_OK } Err(e) => { + Inplace::empty(this); e } } @@ -244,12 +270,14 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice( /// 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( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr_from_slice_autocanonize( + this: *mut MaybeUninit, name: *mut c_char, len: &mut usize, ) -> z_error_t { + let this = this.transmute_uninit_ptr(); if name.is_null() { + Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); @@ -257,10 +285,11 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( match keyexpr_create(name, true, false) { Ok(ke) => { *len = ke.len(); - (*this).write(std::mem::transmute(ke)); + Inplace::init(this, Some(ke)); errors::Z_OK } Err(e) => { + Inplace::empty(this); e } } @@ -270,15 +299,16 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr( + this: *mut MaybeUninit, name: *const c_char, ) -> z_error_t { if name.is_null() { + Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL } else { let len = libc::strlen(name); - zc_keyexpr_from_slice(this, name, len) + z_view_keyexpr_from_slice(this, name, len) } } @@ -287,15 +317,16 @@ pub unsafe extern "C" fn z_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( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr_autocanonize( + this: *mut MaybeUninit, name: *mut c_char, ) -> z_error_t { if name.is_null() { + Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL } else { let mut len = libc::strlen(name); - let res = zc_keyexpr_from_slice_autocanonize(this, name, &mut len); + let res = z_view_keyexpr_from_slice_autocanonize(this, name, &mut len); if res == errors::Z_OK { *name.add(len) = 0; } @@ -313,15 +344,15 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr_from_slice_unchecked( + this: *mut MaybeUninit, start: *const c_char, len: usize, ) { let name = std::slice::from_raw_parts(start as _, len); let name = std::str::from_utf8_unchecked(name); let name: KeyExpr = keyexpr::from_str_unchecked(name).into(); - (*this).write(std::mem::transmute(name)); + Inplace::init(this.transmute_uninit_ptr(), Some(name)) } /// Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: @@ -337,18 +368,19 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr_unchecked( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *const c_char, ) { - zc_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) + z_view_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) } /// Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t) -> z_owned_str_t { - ke.transmute_ref().as_bytes().into() +pub extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { + let ke = ke.transmute_ref(); + unsafe { z_str_from_substring(s, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) } ; } /// Returns the key expression's internal string by aliasing it. @@ -356,12 +388,9 @@ pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t) -> z_owned_str_t /// Currently exclusive to zenoh-c #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t) -> z_slice_t { +pub extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUninit) { let ke = ke.transmute_ref(); - z_slice_t { - start: ke.as_ptr(), - len: ke.len(), - } + unsafe { z_view_slice_wrap(b, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) } ; } /**************************************/ diff --git a/src/payload.rs b/src/payload.rs index 7f3556b27..59a09ad9f 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -4,9 +4,9 @@ use crate::transmute::{ TransmuteUninitPtr, }; use crate::{ - z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap, + z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, ZHashMap }; -use core::slice; +use core::{fmt, slice}; use std::any::Any; use std::io::{Read, Seek, SeekFrom}; use std::mem::MaybeUninit; @@ -73,18 +73,25 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( dst: *mut MaybeUninit, ) -> z_error_t { let len = z_bytes_len(payload); - let cstr = z_owned_str_t::preallocate(len); let payload = payload.transmute_ref(); + let mut out = vec![0u8; len + 1]; if let Err(e) = payload .reader() - .read(from_raw_parts_mut(cstr._cstr as *mut u8, len)) + .read(out.as_mut_slice()) { log::error!("Failed to read the payload: {}", e); - Inplace::empty(dst); + Inplace::empty(dst.transmute_uninit_ptr()); errors::Z_EIO } else { - Inplace::init(dst, cstr); - errors::Z_OK + if let Err(e) = std::str::from_utf8(out.as_slice()) { + log::error!("Payload is not a valid utf-8 string: {}", e); + Inplace::empty(dst.transmute_uninit_ptr()); + errors::Z_EPARSE + } else { + let b = out.into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(b)); + errors::Z_OK + } } } @@ -113,25 +120,34 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes( payload: &z_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { - let len = z_bytes_len(payload); - let b = z_owned_slice_t::preallocate(len); let payload = payload.transmute_ref(); - if let Err(e) = payload.reader().read(from_raw_parts_mut(b.start as *mut _, len)) { - log::error!("Failed to read the payload: {}", e); - Inplace::empty(dst); - errors::Z_EIO - } else { - Inplace::init(dst, b); - errors::Z_OK + match payload.deserialize::>() { + Ok(v) => { + let b = v.into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(b)); + errors::Z_OK + }, + Err(e) => { + log::error!("Failed to read the payload: {}", e); + Inplace::empty(dst.transmute_uninit_ptr()); + errors::Z_EIO + } } } unsafe impl Send for z_slice_t {} unsafe impl Sync for z_slice_t {} +impl fmt::Debug for z_slice_t { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s = self.transmute_ref(); + f.debug_struct("z_slice_t").field("_0", s).finish() + } +} + impl ZSliceBuffer for z_slice_t { fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.start, self.len) } + self.transmute_ref() } fn as_any(&self) -> &dyn Any { self @@ -172,13 +188,12 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_string( this: *mut MaybeUninit, - cstr: *const libc::c_char, + s: &z_str_t, ) { - let bytes = z_slice_t { - start: cstr as *const u8, - len: libc::strlen(cstr), - }; - z_bytes_encode_from_bytes(this, &bytes); + let s = s.transmute_ref(); + let ss = &s[0..s.len() - 1]; + let b = ss.transmute_handle(); + z_bytes_encode_from_bytes(this, &b); } pub use crate::opaque_types::z_owned_bytes_reader_t; diff --git a/src/queryable.rs b/src/queryable.rs index e27178983..e34927b40 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -17,7 +17,7 @@ use crate::transmute::{ }; use crate::{ errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, - z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, + z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, z_view_slice_t, z_view_slice_wrap, }; use std::mem::MaybeUninit; use std::ptr::{null, null_mut}; @@ -255,13 +255,10 @@ pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { /// Get a query's `value selector `_ by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_slice_t { +pub extern "C" fn z_query_parameters(query: &z_query_t, parameters: *mut MaybeUninit) { let query = query.transmute_ref(); let params = query.parameters().as_str(); - z_slice_t { - start: params.as_ptr(), - len: params.len(), - } + unsafe { z_view_slice_wrap(parameters, params.as_ptr(), params.len()) }; } /// Checks if query contains a payload value. From 923c6f0ba6d3b2c4f65953a4a1121e90e6576844 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 25 Apr 2024 18:49:18 +0200 Subject: [PATCH 060/377] builds --- build-resources/opaque-types/src/lib.rs | 6 ++-- include/zenoh_commons.h | 40 ++++++++++++++----------- src/collections.rs | 9 +++--- src/config.rs | 15 +++++++--- src/keyexpr.rs | 12 ++++++-- src/payload.rs | 16 ++++++---- src/platform/synchronization.rs | 32 ++++++++++++-------- src/publication_cache.rs | 10 +++---- src/transmute.rs | 2 +- 9 files changed, 86 insertions(+), 56 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 4aba1525b..7797578d5 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -263,13 +263,13 @@ get_opaque_type_data!(LivelinessToken<'static>, zc_liveliness_token_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, ze_owned_publication_cache_t); -get_opaque_type_data!(&'static zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); +get_opaque_type_data!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); get_opaque_type_data!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); -get_opaque_type_data!(&'static (Mutex<()>, Option>), z_mutex_t); +get_opaque_type_data!((Mutex<()>, Option>), z_mutex_t); get_opaque_type_data!(Option, z_owned_condvar_t); -get_opaque_type_data!(&'static Condvar, z_condvar_t); +get_opaque_type_data!(Condvar, z_condvar_t); get_opaque_type_data!(Option>, z_owned_task_t); \ No newline at end of file diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 7a3f071e8..3944d26e1 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -364,10 +364,10 @@ typedef struct ALIGN(8) z_owned_condvar_t { uint8_t _0[24]; } z_owned_condvar_t; typedef struct ALIGN(8) z_condvar_t { - uint8_t _0[8]; + uint8_t _0[16]; } z_condvar_t; typedef struct ALIGN(8) z_mutex_t { - uint8_t _0[8]; + uint8_t _0[32]; } z_mutex_t; /** * An owned zenoh configuration. @@ -940,6 +940,7 @@ ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_reader_t *this_) ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_reader_t *this_); ZENOHC_API const struct z_bytes_reader_t *z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); +ZENOHC_API struct z_bytes_reader_t *z_bytes_reader_loan_mut(struct z_owned_bytes_reader_t *reader); /** * Creates a reader for the specified `payload`. * @@ -954,7 +955,7 @@ ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. */ ZENOHC_API -size_t z_bytes_reader_read(const struct z_bytes_reader_t *this_, +size_t z_bytes_reader_read(struct z_bytes_reader_t *this_, uint8_t *dest, size_t len); /** @@ -964,14 +965,14 @@ size_t z_bytes_reader_read(const struct z_bytes_reader_t *this_, * Return ​0​ upon success, negative error code otherwise. */ ZENOHC_API -z_error_t z_bytes_reader_seek(const struct z_bytes_reader_t *this_, +z_error_t z_bytes_reader_seek(struct z_bytes_reader_t *this_, int64_t offset, int origin); /** * Returns the read position indicator. * Returns read position indicator on success or -1L if failure occurs. */ -ZENOHC_API int64_t z_bytes_reader_tell(const struct z_bytes_reader_t *this_); +ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t *this_); ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); @@ -1070,10 +1071,11 @@ ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); -ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); +ZENOHC_API const struct z_condvar_t *z_condvar_loan(const struct z_owned_condvar_t *this_); +ZENOHC_API struct z_condvar_t *z_condvar_loan_mut(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); -ZENOHC_API z_error_t z_condvar_signal(struct z_condvar_t this_); -ZENOHC_API z_error_t z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); +ZENOHC_API z_error_t z_condvar_signal(const struct z_condvar_t *this_); +ZENOHC_API z_error_t z_condvar_wait(const struct z_condvar_t *this_, struct z_mutex_t *m); /** * Returns ``true`` if `config` is valid. */ @@ -1112,6 +1114,10 @@ ZENOHC_API void z_config_drop(struct z_owned_config_t *config); * Returns a :c:type:`z_config_t` loaned from `s`. */ ZENOHC_API const struct z_config_t *z_config_loan(const struct z_owned_config_t *this_); +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t *z_config_loan_mut(struct z_owned_config_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_config_t' type */ @@ -1469,11 +1475,11 @@ void z_keyexpr_unchecked(struct z_view_keyexpr_t *this_, ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); ZENOHC_API z_error_t z_mutex_init(struct z_owned_mutex_t *this_); -ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_lock(struct z_mutex_t this_); +ZENOHC_API struct z_mutex_t *z_mutex_loan_mut(struct z_owned_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_lock(struct z_mutex_t *this_); ZENOHC_API void z_mutex_null(struct z_owned_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_try_lock(struct z_mutex_t this_); -ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t this_); +ZENOHC_API z_error_t z_mutex_try_lock(struct z_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t *this_); /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. * Config value is always consumed upon function return. @@ -2190,7 +2196,7 @@ z_error_t zc_config_from_str(struct z_owned_config_t *this_, * Use `z_drop` to safely deallocate this string */ ZENOHC_API -z_error_t zc_config_get(struct z_config_t config, +z_error_t zc_config_get(const struct z_config_t *config, const char *key, struct z_owned_str_t *value_string); /** @@ -2199,7 +2205,7 @@ z_error_t zc_config_get(struct z_config_t config, * Returns 0 if successful, a negative value otherwise. */ ZENOHC_API -z_error_t zc_config_insert_json(const struct z_config_t *config, +z_error_t zc_config_insert_json(struct z_config_t *config, const char *key, const char *value); /** @@ -2403,8 +2409,8 @@ ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); */ ZENOHC_API z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct ze_publication_cache_options_t *options); /** * Declares a Querying Subscriber for a given key expression. @@ -2456,7 +2462,7 @@ ZENOHC_API void ze_publication_cache_null(struct ze_owned_publication_cache_t *t /** * Constructs the default value for :c:type:`ze_publication_cache_options_t`. */ -ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); +ZENOHC_API void ze_publication_cache_options_default(struct ze_publication_cache_options_t *this_); /** * Returns ``true`` if `this` is valid. */ diff --git a/src/collections.rs b/src/collections.rs index e8c9039ee..ef47a8393 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -23,8 +23,7 @@ use zenoh::prelude::ZenohId; use crate::{errors, transmute, z_owned_bytes_t}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, - TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; pub use crate::opaque_types::z_owned_slice_t; @@ -75,7 +74,7 @@ pub unsafe extern "C" fn z_view_slice_wrap(this: *mut MaybeUninit *const z_slice_t { +pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_slice_t { match this.transmute_ref() { Some(s) => s.transmute_handle(), None => null(), @@ -130,7 +129,7 @@ pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { } #[no_mangle] -pub const extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { +pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { match this.transmute_ref() { Some(s) => (&&*s.as_ref()) as *const &[u8] as *const z_slice_t, None => null(), @@ -323,7 +322,7 @@ pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_slice_map_t #[no_mangle] pub extern "C" fn z_slice_map_loan_mut(this: &mut z_owned_slice_map_t) -> &mut z_slice_map_t { let this = this.transmute_mut(); - let this = unwrap_ref_unchecked(this); + let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() } diff --git a/src/config.rs b/src/config.rs index 73ac24b02..77ef6bfd9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,8 +18,7 @@ use zenoh::config::{Config, ValidatedMap, WhatAmI}; use crate::errors::z_error_t; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, - TransmuteUninitPtr, + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; use crate::{errors, z_owned_str_t, z_str_from_substring, z_str_null}; @@ -77,6 +76,14 @@ pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_config_t this.transmute_handle() } +/// Returns a :c:type:`z_config_t` loaned from `s`. +#[no_mangle] +pub extern "C" fn z_config_loan_mut(this: &mut z_owned_config_t) -> &mut z_config_t { + let this = this.transmute_mut(); + let this = unwrap_ref_unchecked_mut(this); + this.transmute_handle_mut() +} + /// Return a new, zenoh-allocated, empty configuration. /// /// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. @@ -114,7 +121,7 @@ pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) -> errors::z_error_t { +pub unsafe extern "C" fn zc_config_get(config: &z_config_t, key: *const c_char, value_string: *mut MaybeUninit) -> errors::z_error_t { let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, @@ -142,7 +149,7 @@ pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char, v #[no_mangle] #[allow(clippy::missing_safety_doc, unused_must_use)] pub unsafe extern "C" fn zc_config_insert_json( - config: &z_config_t, + config: &mut z_config_t, key: *const c_char, value: *const c_char, ) -> errors::z_error_t { diff --git a/src/keyexpr.rs b/src/keyexpr.rs index a930b8cc6..fee889892 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -55,19 +55,25 @@ pub extern "C" fn z_view_keyexpr_null(this: *mut MaybeUninit) } fn keyexpr_create_inner( - mut name: &'static mut str, + name: &'static mut str, should_auto_canonize: bool, should_copy: bool, ) -> Result, Box> { if should_copy { - let s = name.to_owned(); + let s = name.to_string(); match should_auto_canonize { true => KeyExpr::<'static>::autocanonize(s), false => KeyExpr::<'static>::try_from(s), } } else { match should_auto_canonize { - true => keyexpr::autocanonize(&mut name).map(|k| k.into()), + true => { + // hack to fix issue with autocanonize requiring &&str instead of &str + // to be removed after this issue is resolved on zenoh-rust side + let n = &name as *const &'static mut str as *mut &'static mut str; + let n = unsafe { &mut *n }; + keyexpr::autocanonize(n).map(|k| k.into()) + }, false => keyexpr::new(name).map(|k| k.into()) } } diff --git a/src/payload.rs b/src/payload.rs index 59a09ad9f..96ef100ca 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,7 +1,6 @@ use crate::errors::{self, z_error_t}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, - TransmuteUninitPtr, + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; use crate::{ z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, ZHashMap @@ -243,6 +242,13 @@ extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_r reader.transmute_handle() } +#[no_mangle] +extern "C" fn z_bytes_reader_loan_mut(reader: &mut z_owned_bytes_reader_t) -> &mut z_bytes_reader_t { + let reader = reader.transmute_mut(); + let reader = unwrap_ref_unchecked_mut(reader); + reader.transmute_handle_mut() +} + /// Reads data into specified destination. /// /// Will read at most `len` bytes. @@ -250,7 +256,7 @@ extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_r #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_read( - this: &z_bytes_reader_t, + this: &mut z_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { @@ -266,7 +272,7 @@ pub unsafe extern "C" fn z_bytes_reader_read( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_seek( - this: &z_bytes_reader_t, + this: &mut z_bytes_reader_t, offset: i64, origin: libc::c_int, ) -> z_error_t { @@ -289,7 +295,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( /// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_tell(this: &z_bytes_reader_t) -> i64 { +pub unsafe extern "C" fn z_bytes_reader_tell(this: &mut z_bytes_reader_t) -> i64 { let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index cd1c016e3..aa00c3090 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -11,8 +11,7 @@ pub use crate::opaque_types::z_owned_mutex_t; use crate::{ errors, transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, - TransmuteUninitPtr, + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }, }; @@ -46,14 +45,14 @@ pub extern "C" fn z_mutex_null(this: *mut MaybeUninit) { } #[no_mangle] -pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { - let this = this.transmute_ref(); - let this = unwrap_ref_unchecked(this); - this.transmute_handle() +pub extern "C" fn z_mutex_loan_mut(this: &mut z_owned_mutex_t) -> &mut z_mutex_t { + let this = this.transmute_mut(); + let this = unwrap_ref_unchecked_mut(this); + this.transmute_handle_mut() } #[no_mangle] -pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::z_error_t { +pub extern "C" fn z_mutex_lock(this: &mut z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.lock() { @@ -69,7 +68,7 @@ pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::z_error_t { } #[no_mangle] -pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::z_error_t { +pub extern "C" fn z_mutex_unlock(this: &mut z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); if this.1.is_none() { return errors::Z_EINVAL_MUTEX; @@ -81,7 +80,7 @@ pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::z_error_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::z_error_t { +pub unsafe extern "C" fn z_mutex_try_lock(this: &mut z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.try_lock() { Ok(new_lock) => { @@ -124,23 +123,30 @@ pub extern "C" fn z_condvar_check(this: &z_owned_condvar_t) -> bool { } #[no_mangle] -pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> z_condvar_t { +pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> &z_condvar_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } #[no_mangle] -pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::z_error_t { +pub extern "C" fn z_condvar_loan_mut(this: &mut z_owned_condvar_t) -> &mut z_condvar_t { let this = this.transmute_mut(); + let this = unwrap_ref_unchecked_mut(this); + this.transmute_handle_mut() +} + +#[no_mangle] +pub extern "C" fn z_condvar_signal(this: &z_condvar_t) -> errors::z_error_t { + let this = this.transmute_ref(); this.notify_one(); errors::Z_OK } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_wait(this: z_condvar_t, m: z_mutex_t) -> errors::z_error_t { - let this = this.transmute_mut(); +pub unsafe extern "C" fn z_condvar_wait(this: &z_condvar_t, m: &mut z_mutex_t) -> errors::z_error_t { + let this = this.transmute_ref(); let m = m.transmute_mut(); if m.1.is_none() { return errors::Z_EINVAL_MUTEX; // lock was not aquired prior to wait call diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 7f8f9e9e6..84278e3d8 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -41,14 +41,14 @@ pub struct ze_publication_cache_options_t { /// Constructs the default value for :c:type:`ze_publication_cache_options_t`. #[no_mangle] -pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache_options_t { - ze_publication_cache_options_t { +pub extern "C" fn ze_publication_cache_options_default(this: &mut ze_publication_cache_options_t) { + *this = ze_publication_cache_options_t { queryable_prefix: null(), queryable_origin: zcu_locality_default(), queryable_complete: false, history: 1, resources_limit: 0, - } + }; } pub use crate::opaque_types::ze_owned_publication_cache_t; @@ -87,8 +87,8 @@ decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cach #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_declare_publication_cache( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, options: Option<&mut ze_publication_cache_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); diff --git a/src/transmute.rs b/src/transmute.rs index b5d88a6dc..92fb45f45 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -165,7 +165,7 @@ macro_rules! decl_transmute_copy { #[macro_export] macro_rules! decl_transmute_handle { ($zenoh_type:ty, $c_type:ty) => { - validate_equivalence!(&'static $zenoh_type, $c_type); + validate_equivalence!($zenoh_type, $c_type); impl_transmute_handle!($c_type, $zenoh_type); }; } From 6842d59feef28f1d7d11cda9efc1f53a2b2f604f Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 26 Apr 2024 09:45:41 +0200 Subject: [PATCH 061/377] fmt and clippy --- build.rs | 4 +- src/collections.rs | 93 ++++++++++++++++++++++----------- src/commons.rs | 5 +- src/config.rs | 28 ++++++---- src/get.rs | 2 +- src/keyexpr.rs | 31 +++++------ src/liveliness.rs | 9 ++-- src/payload.rs | 41 +++++++-------- src/platform/synchronization.rs | 8 ++- src/put.rs | 6 +-- src/queryable.rs | 7 ++- src/querying_subscriber.rs | 4 +- src/scouting.rs | 2 +- src/session.rs | 2 +- src/transmute.rs | 2 +- 15 files changed, 141 insertions(+), 103 deletions(-) diff --git a/build.rs b/build.rs index 01fc61a4a..72fd1ab4c 100644 --- a/build.rs +++ b/build.rs @@ -85,9 +85,7 @@ fn produce_opaque_types_data() -> PathBuf { } fn generate_opaque_types() { - let type_to_inner_field_name = HashMap::from([ - ("z_id_t", "id"), - ]); + let type_to_inner_field_name = HashMap::from([("z_id_t", "id")]); let current_folder = get_build_rs_path(); let path_in = produce_opaque_types_data(); let path_out = current_folder.join("./src/opaque_types/mod.rs"); diff --git a/src/collections.rs b/src/collections.rs index ef47a8393..0add96fff 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -15,20 +15,20 @@ use std::borrow::Cow; use std::collections::HashMap; use std::mem::MaybeUninit; -use std::ptr::{null, null_mut}; +use std::ptr::null; use std::slice::from_raw_parts; -use libc::{c_char, c_void, size_t, strlen}; -use zenoh::prelude::ZenohId; +use libc::{c_char, c_void, strlen}; -use crate::{errors, transmute, z_owned_bytes_t}; +use crate::errors; use crate::transmute::{ - unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, + TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; pub use crate::opaque_types::z_owned_slice_t; -pub use crate::opaque_types::z_view_slice_t; pub use crate::opaque_types::z_slice_t; +pub use crate::opaque_types::z_view_slice_t; decl_transmute_owned!(Option>, z_owned_slice_t); decl_transmute_owned!(Option<&'static [u8]>, z_view_slice_t); @@ -36,13 +36,13 @@ decl_transmute_handle!(&'static [u8], z_slice_t); /// Returns an empty `z_view_slice_t` #[no_mangle] -pub unsafe extern "C" fn z_view_slice_empty(this: *mut MaybeUninit) { +pub extern "C" fn z_view_slice_empty(this: *mut MaybeUninit) { let slice: &'static [u8] = &[]; Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } #[no_mangle] -pub unsafe extern "C" fn z_view_slice_null(this: *mut MaybeUninit) { +pub extern "C" fn z_view_slice_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } @@ -51,7 +51,10 @@ pub unsafe extern "C" fn z_view_slice_null(this: *mut MaybeUninit, str: *const c_char) { +pub unsafe extern "C" fn z_view_slice_from_str( + this: *mut MaybeUninit, + str: *const c_char, +) { if str.is_null() { z_view_slice_null(this) } else { @@ -62,13 +65,17 @@ pub unsafe extern "C" fn z_view_slice_from_str(this: *mut MaybeUninit, start: *const u8, len: usize) { +pub unsafe extern "C" fn z_view_slice_wrap( + this: *mut MaybeUninit, + start: *const u8, + len: usize, +) { if len == 0 { z_view_slice_empty(this) } else if start.is_null() { z_view_slice_null(this) } else { - let slice: &'static [u8] = from_raw_parts(start, len).into(); + let slice: &'static [u8] = from_raw_parts(start, len); Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } } @@ -83,7 +90,7 @@ pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_slice_t { /// Returns an empty `z_owned_slice_t` #[no_mangle] -pub unsafe extern "C" fn z_slice_empty(this: *mut MaybeUninit) { +pub extern "C" fn z_slice_empty(this: *mut MaybeUninit) { let slice = Box::new([]); Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } @@ -98,7 +105,10 @@ pub extern "C" fn z_slice_null(this: *mut MaybeUninit) { /// Calling this with `str == NULL` is equivalent to `z_slice_null`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_from_str(this: *mut MaybeUninit, str: *const c_char) { +pub unsafe extern "C" fn z_slice_from_str( + this: *mut MaybeUninit, + str: *const c_char, +) { if str.is_null() { z_slice_null(this) } else { @@ -109,7 +119,11 @@ pub unsafe extern "C" fn z_slice_from_str(this: *mut MaybeUninit, start: *const u8, len: usize) { +pub unsafe extern "C" fn z_slice_wrap( + this: *mut MaybeUninit, + start: *const u8, + len: usize, +) { if len == 0 { z_slice_empty(this) } else if start.is_null() { @@ -131,14 +145,14 @@ pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { #[no_mangle] pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { match this.transmute_ref() { - Some(s) => (&&*s.as_ref()) as *const &[u8] as *const z_slice_t, + Some(s) => (&s.as_ref()) as *const &[u8] as *const z_slice_t, None => null(), } } #[no_mangle] -pub unsafe extern "C" fn z_slice_clone(this: &z_slice_t, dst: *mut MaybeUninit) { - let slice = this.transmute_ref().to_vec().into_boxed_slice(); +pub extern "C" fn z_slice_clone(this: &z_slice_t, dst: *mut MaybeUninit) { + let slice = this.transmute_ref().to_vec().into_boxed_slice(); Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); } @@ -164,16 +178,14 @@ pub extern "C" fn z_slice_data(this: &z_slice_t) -> *const u8 { this.transmute_ref().as_ptr() } - pub use crate::opaque_types::z_owned_str_t; -pub use crate::opaque_types::z_view_str_t; pub use crate::opaque_types::z_str_t; +pub use crate::opaque_types::z_view_str_t; decl_transmute_owned!(custom_inplace_init Option>, z_owned_str_t); decl_transmute_owned!(custom_inplace_init Option<&'static [u8]>, z_view_str_t); decl_transmute_handle!(&'static [u8], z_str_t); - /// Frees `z_owned_str_t`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -200,11 +212,13 @@ pub extern "C" fn z_view_str_null(this: *mut MaybeUninit) { } #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_empty(this: *mut MaybeUninit) { z_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) } #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_view_str_empty(this: *mut MaybeUninit) { z_view_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) } @@ -221,20 +235,28 @@ pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_str_t { z_view_slice_loan(this.transmute_ref().transmute_ref()) as _ } - /// Copies a string into `z_owned_str_t` using `strlen` (this should therefore not be used with untrusted inputs). /// /// Calling this with `str == NULL` is equivalent to `z_str_null`. #[no_mangle] -pub unsafe extern "C" fn z_str_wrap(this: *mut MaybeUninit, str: *const libc::c_char) { - z_slice_wrap(this as *mut _, str as _, strlen(str) + 1) +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_str_wrap( + this: *mut MaybeUninit, + str: *const libc::c_char, +) { + z_slice_wrap(this as *mut _, str as _, strlen(str) + 1) } /// Copies a a substring of length `len`into `z_owned_str_t`. /// /// Calling this with `str == NULL` is equivalent to `z_str_null`. #[no_mangle] -pub unsafe extern "C" fn z_str_from_substring(this: *mut MaybeUninit, str: *const libc::c_char, len: usize) { +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_str_from_substring( + this: *mut MaybeUninit, + str: *const libc::c_char, + len: usize, +) { let mut v = vec![0u8; len + 1]; v[0..len].copy_from_slice(from_raw_parts(str as *const u8, len)); let b = v.into_boxed_slice(); @@ -245,8 +267,12 @@ pub unsafe extern "C" fn z_str_from_substring(this: *mut MaybeUninit, str: *const libc::c_char) { - z_view_slice_wrap(this as *mut _, str as _, strlen(str) + 1) +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_view_str_wrap( + this: *mut MaybeUninit, + str: *const libc::c_char, +) { + z_view_slice_wrap(this as *mut _, str as _, strlen(str) + 1) } #[no_mangle] @@ -255,8 +281,9 @@ pub extern "C" fn z_view_str_len(this: &z_str_t) -> usize { } #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub extern "C" fn z_view_str_data(this: &z_str_t) -> *const libc::c_char { - z_slice_data(&this.transmute_ref().transmute_handle()) as _ + z_slice_data(this.transmute_ref().transmute_handle()) as _ } #[no_mangle] @@ -358,14 +385,18 @@ pub extern "C" fn z_slice_map_iterate( for (key, value) in this { let key_slice = key.as_ref(); let value_slice = value.as_ref(); - if !body(key_slice.transmute_handle(), value_slice.transmute_handle(), context) { + if !body( + key_slice.transmute_handle(), + value_slice.transmute_handle(), + context, + ) { break; } } } -/// Returns the value associated with `key`. -/// +/// Returns the value associated with `key`. +/// /// Will return NULL if the key is not present in the map. #[no_mangle] pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *const z_slice_t { @@ -378,7 +409,7 @@ pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *con } /// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. -/// +/// /// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_copy( diff --git a/src/commons.rs b/src/commons.rs index 27eaafec8..86f5bad69 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -137,7 +137,6 @@ pub extern "C" fn z_sample_timestamp( /// The qos with which the sample was received. /// TODO: split to methods (priority, congestion_control, express) - /// Gets sample's attachment. /// /// Returns NULL if sample does not contain an attachement. @@ -148,7 +147,6 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> *const z_bytes_t { Some(attachment) => attachment.transmute_handle() as *const _, None => null(), } - } pub use crate::opaque_types::zc_owned_sample_t; @@ -163,7 +161,6 @@ pub extern "C" fn z_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit z_priority_t { let sample = sample.transmute_ref(); @@ -196,7 +193,7 @@ pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: & zc_owned_sample_t) -> &z_sample_t { +pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> &z_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } diff --git a/src/config.rs b/src/config.rs index 77ef6bfd9..9e207bbbe 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,7 +18,8 @@ use zenoh::config::{Config, ValidatedMap, WhatAmI}; use crate::errors::z_error_t; use crate::transmute::{ - unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, + TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{errors, z_owned_str_t, z_str_from_substring, z_str_null}; @@ -121,7 +122,11 @@ pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) -> errors::z_error_t { +pub unsafe extern "C" fn zc_config_get( + config: &z_config_t, + key: *const c_char, + value_string: *mut MaybeUninit, +) -> errors::z_error_t { let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, @@ -192,8 +197,7 @@ pub unsafe extern "C" fn zc_config_from_str( res = errors::Z_EINVAL; } else { let conf_str = CStr::from_ptr(s); - let props: Option = json5::from_str(&conf_str.to_string_lossy()) - .ok(); + let props: Option = json5::from_str(&conf_str.to_string_lossy()).ok(); if props.is_none() { res = errors::Z_EPARSE; } @@ -205,17 +209,22 @@ pub unsafe extern "C" fn zc_config_from_str( /// Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_config_to_string(config: &z_config_t, config_string: *mut MaybeUninit) -> errors::z_error_t { +pub unsafe extern "C" fn zc_config_to_string( + config: &z_config_t, + config_string: *mut MaybeUninit, +) -> errors::z_error_t { let config: &Config = config.transmute_ref(); match json5::to_string(config) { Ok(s) => { - unsafe { z_str_from_substring(config_string, s.as_ptr() as *const libc::c_char, s.len()) }; + unsafe { + z_str_from_substring(config_string, s.as_ptr() as *const libc::c_char, s.len()) + }; errors::Z_OK } Err(_) => { z_str_null(config_string); errors::Z_EPARSE - }, + } } } @@ -251,10 +260,7 @@ pub unsafe extern "C" fn zc_config_from_file( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { - Inplace::init( - this.transmute_uninit_ptr(), - Some(zenoh::config::peer()), - ); + Inplace::init(this.transmute_uninit_ptr(), Some(zenoh::config::peer())); } /// Constructs a default, zenoh-allocated, client mode configuration. diff --git a/src/get.rs b/src/get.rs index cba2370d1..3586e50a2 100644 --- a/src/get.rs +++ b/src/get.rs @@ -71,7 +71,7 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_reply_t) -> *const z_sample_t { /// Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_err(reply: &z_reply_t) -> *const z_value_t{ +pub unsafe extern "C" fn z_reply_err(reply: &z_reply_t) -> *const z_value_t { let reply = reply.transmute_ref(); match reply.result() { Ok(_) => null(), diff --git a/src/keyexpr.rs b/src/keyexpr.rs index fee889892..61fefacd5 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -23,12 +23,9 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_owned_slice_t; use crate::z_owned_str_t; use crate::z_session_t; -use crate::z_slice_t; use crate::z_str_from_substring; -use crate::z_view_slice_from_str; use crate::z_view_slice_t; use crate::z_view_slice_wrap; use libc::c_char; @@ -37,6 +34,7 @@ use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; +use zenoh_protocol::core::key_expr::canon::Canonizable; pub use crate::opaque_types::z_owned_keyexpr_t; pub use crate::opaque_types::z_view_keyexpr_t; @@ -55,7 +53,7 @@ pub extern "C" fn z_view_keyexpr_null(this: *mut MaybeUninit) } fn keyexpr_create_inner( - name: &'static mut str, + mut name: &'static mut str, should_auto_canonize: bool, should_copy: bool, ) -> Result, Box> { @@ -66,16 +64,10 @@ fn keyexpr_create_inner( false => KeyExpr::<'static>::try_from(s), } } else { - match should_auto_canonize { - true => { - // hack to fix issue with autocanonize requiring &&str instead of &str - // to be removed after this issue is resolved on zenoh-rust side - let n = &name as *const &'static mut str as *mut &'static mut str; - let n = unsafe { &mut *n }; - keyexpr::autocanonize(n).map(|k| k.into()) - }, - false => keyexpr::new(name).map(|k| k.into()) + if should_auto_canonize { + name.canonize(); } + return keyexpr::new(name).map(|k| k.into()); } } @@ -384,9 +376,9 @@ pub unsafe extern "C" fn z_keyexpr_unchecked( /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { +pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { let ke = ke.transmute_ref(); - unsafe { z_str_from_substring(s, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) } ; + unsafe { z_str_from_substring(s, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) }; } /// Returns the key expression's internal string by aliasing it. @@ -394,9 +386,9 @@ pub extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { +pub unsafe extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUninit) { let ke = ke.transmute_ref(); - unsafe { z_view_slice_wrap(b, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) } ; + unsafe { z_view_slice_wrap(b, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) }; } /**************************************/ @@ -433,7 +425,10 @@ pub extern "C" fn z_declare_keyexpr( /// The keyxpr is consumed. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_keyexpr(session: &z_session_t, kexpr: &mut z_owned_keyexpr_t) -> errors::z_error_t { +pub extern "C" fn z_undeclare_keyexpr( + session: &z_session_t, + kexpr: &mut z_owned_keyexpr_t, +) -> errors::z_error_t { let Some(kexpr) = kexpr.transmute_mut().take() else { log::debug!("Attempted to undeclare dropped keyexpr"); return errors::Z_EINVAL; diff --git a/src/liveliness.rs b/src/liveliness.rs index 88e0966b3..8fefb253d 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -54,8 +54,9 @@ pub struct zc_liveliness_declaration_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_default(this: &mut zc_liveliness_declaration_options_t) -{ +pub extern "C" fn zc_liveliness_declaration_options_default( + this: &mut zc_liveliness_declaration_options_t, +) { *this = zc_liveliness_declaration_options_t { _dummy: 0 }; } @@ -110,7 +111,9 @@ pub struct zc_liveliness_declare_subscriber_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_default(this: &mut zc_liveliness_declare_subscriber_options_t) { +pub extern "C" fn zc_liveliness_subscriber_options_default( + this: &mut zc_liveliness_declare_subscriber_options_t, +) { *this = zc_liveliness_declare_subscriber_options_t { _dummy: 0 }; } diff --git a/src/payload.rs b/src/payload.rs index 96ef100ca..665ae0d24 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,11 +1,13 @@ use crate::errors::{self, z_error_t}; use crate::transmute::{ - unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, + TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{ - z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, ZHashMap + z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, + ZHashMap, }; -use core::{fmt, slice}; +use core::fmt; use std::any::Any; use std::io::{Read, Seek, SeekFrom}; use std::mem::MaybeUninit; @@ -40,7 +42,7 @@ extern "C" fn z_bytes_check(payload: &z_owned_bytes_t) -> bool { /// Loans the payload, allowing you to call functions that only need a loan of it. #[no_mangle] -extern "C" fn z_bytes_loan(payload: & z_owned_bytes_t) -> &z_bytes_t { +extern "C" fn z_bytes_loan(payload: &z_owned_bytes_t) -> &z_bytes_t { let payload = payload.transmute_ref(); let payload = unwrap_ref_unchecked(payload); payload.transmute_handle() @@ -74,23 +76,18 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( let len = z_bytes_len(payload); let payload = payload.transmute_ref(); let mut out = vec![0u8; len + 1]; - if let Err(e) = payload - .reader() - .read(out.as_mut_slice()) - { + if let Err(e) = payload.reader().read(out.as_mut_slice()) { log::error!("Failed to read the payload: {}", e); Inplace::empty(dst.transmute_uninit_ptr()); errors::Z_EIO + } else if let Err(e) = std::str::from_utf8(out.as_slice()) { + log::error!("Payload is not a valid utf-8 string: {}", e); + Inplace::empty(dst.transmute_uninit_ptr()); + errors::Z_EPARSE } else { - if let Err(e) = std::str::from_utf8(out.as_slice()) { - log::error!("Payload is not a valid utf-8 string: {}", e); - Inplace::empty(dst.transmute_uninit_ptr()); - errors::Z_EPARSE - } else { - let b = out.into_boxed_slice(); - Inplace::init(dst.transmute_uninit_ptr(), Some(b)); - errors::Z_OK - } + let b = out.into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(b)); + errors::Z_OK } } @@ -125,7 +122,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes( let b = v.into_boxed_slice(); Inplace::init(dst.transmute_uninit_ptr(), Some(b)); errors::Z_OK - }, + } Err(e) => { log::error!("Failed to read the payload: {}", e); Inplace::empty(dst.transmute_uninit_ptr()); @@ -165,7 +162,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes( bytes: &z_slice_t, ) { let this = this.transmute_uninit_ptr(); - let payload = ZBytes::from(ZSlice::from(bytes.clone())); + let payload = ZBytes::from(ZSlice::from(*bytes)); Inplace::init(this, Some(payload)); } @@ -192,7 +189,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( let s = s.transmute_ref(); let ss = &s[0..s.len() - 1]; let b = ss.transmute_handle(); - z_bytes_encode_from_bytes(this, &b); + z_bytes_encode_from_bytes(this, b); } pub use crate::opaque_types::z_owned_bytes_reader_t; @@ -243,7 +240,9 @@ extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_r } #[no_mangle] -extern "C" fn z_bytes_reader_loan_mut(reader: &mut z_owned_bytes_reader_t) -> &mut z_bytes_reader_t { +extern "C" fn z_bytes_reader_loan_mut( + reader: &mut z_owned_bytes_reader_t, +) -> &mut z_bytes_reader_t { let reader = reader.transmute_mut(); let reader = unwrap_ref_unchecked_mut(reader); reader.transmute_handle_mut() diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index aa00c3090..9c2adf78f 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -11,7 +11,8 @@ pub use crate::opaque_types::z_owned_mutex_t; use crate::{ errors, transmute::{ - unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, + TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }, }; @@ -145,7 +146,10 @@ pub extern "C" fn z_condvar_signal(this: &z_condvar_t) -> errors::z_error_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_wait(this: &z_condvar_t, m: &mut z_mutex_t) -> errors::z_error_t { +pub unsafe extern "C" fn z_condvar_wait( + this: &z_condvar_t, + m: &mut z_mutex_t, +) -> errors::z_error_t { let this = this.transmute_ref(); let m = m.transmute_mut(); if m.1.is_none() { diff --git a/src/put.rs b/src/put.rs index 2bb950087..74b63b4b8 100644 --- a/src/put.rs +++ b/src/put.rs @@ -141,10 +141,10 @@ pub extern "C" fn z_delete( ) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let mut del = session - .delete(key_expr); + let mut del = session.delete(key_expr); if let Some(options) = options { - del = del.congestion_control(options.congestion_control.into()) + del = del + .congestion_control(options.congestion_control.into()) .priority(options.priority.into()); } diff --git a/src/queryable.rs b/src/queryable.rs index e34927b40..0f2de51ce 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -17,7 +17,7 @@ use crate::transmute::{ }; use crate::{ errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, - z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, z_view_slice_t, z_view_slice_wrap, + z_owned_encoding_t, z_session_t, z_value_t, z_view_slice_t, z_view_slice_wrap, }; use std::mem::MaybeUninit; use std::ptr::{null, null_mut}; @@ -255,7 +255,10 @@ pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { /// Get a query's `value selector `_ by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_parameters(query: &z_query_t, parameters: *mut MaybeUninit) { +pub unsafe extern "C" fn z_query_parameters( + query: &z_query_t, + parameters: *mut MaybeUninit, +) { let query = query.transmute_ref(); let params = query.parameters().as_str(); unsafe { z_view_slice_wrap(parameters, params.as_ptr(), params.len()) }; diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index d6a5e3696..0166314f1 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -83,7 +83,9 @@ pub struct ze_querying_subscriber_options_t { /// Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. #[no_mangle] -pub extern "C" fn ze_querying_subscriber_options_default(this: &mut ze_querying_subscriber_options_t) { +pub extern "C" fn ze_querying_subscriber_options_default( + this: &mut ze_querying_subscriber_options_t, +) { *this = ze_querying_subscriber_options_t { reliability: Reliability::DEFAULT.into(), allowed_origin: zcu_locality_default(), diff --git a/src/scouting.rs b/src/scouting.rs index 0f2f29c34..7609c3a38 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -222,7 +222,7 @@ pub unsafe extern "C" fn z_scouting_config_from( config: &z_config_t, ) { let mut dst = MaybeUninit::uninit(); - z_config_clone(&config, &mut dst as *mut _); + z_config_clone(config, &mut dst as *mut _); let _config = dst.assume_init(); let config = z_owned_scouting_config_t { diff --git a/src/session.rs b/src/session.rs index 194779201..049fd7ca3 100644 --- a/src/session.rs +++ b/src/session.rs @@ -38,7 +38,7 @@ decl_transmute_handle!(Session, z_session_t); /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(this: & z_owned_session_t) -> &z_session_t { +pub extern "C" fn z_session_loan(this: &z_owned_session_t) -> &z_session_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); let this = this.as_ref(); diff --git a/src/transmute.rs b/src/transmute.rs index 92fb45f45..136069535 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -207,7 +207,7 @@ macro_rules! impl_transmute_handle { ($c_type:ty, $zenoh_type:ty) => { impl $crate::transmute::TransmuteFromHandle<$zenoh_type> for $c_type { fn transmute_ref(&self) -> &'static $zenoh_type { - unsafe { std::mem::transmute::<& $c_type, &'static $zenoh_type>(self) } + unsafe { std::mem::transmute::<&$c_type, &'static $zenoh_type>(self) } } fn transmute_mut(&mut self) -> &'static mut $zenoh_type { unsafe { std::mem::transmute::<&mut $c_type, &'static mut $zenoh_type>(self) } From 155aa60036a20bf54a996ba2f5730618121dd108 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 26 Apr 2024 10:31:53 +0200 Subject: [PATCH 062/377] explicitely named loaned types --- build-resources/opaque-types/src/lib.rs | 46 +-- docs/api.rst | 18 +- docs/examples.rst | 8 +- examples/z_get.c | 4 +- examples/z_get_liveliness.c | 4 +- examples/z_liveliness.c | 2 +- examples/z_non_blocking_get.c | 6 +- examples/z_ping.c | 12 +- examples/z_pong.c | 8 +- examples/z_pub_thr.c | 2 +- examples/z_query_sub.c | 4 +- examples/z_queryable.c | 10 +- examples/z_queryable_with_channels.c | 12 +- examples/z_sub.c | 4 +- examples/z_sub_attachment.c | 10 +- examples/z_sub_liveliness.c | 6 +- examples/z_sub_thr.c | 2 +- include/zenoh_commons.h | 523 +++++++++++++----------- include/zenoh_concrete.h | 8 +- include/zenoh_macros.h | 62 +-- splitguide.yaml | 4 +- src/closures/query_channel.rs | 8 +- src/closures/query_closure.rs | 20 +- src/closures/reply_closure.rs | 16 +- src/closures/response_channel.rs | 8 +- src/closures/sample_closure.rs | 18 +- src/collections.rs | 71 ++-- src/commons.rs | 79 ++-- src/config.rs | 20 +- src/get.rs | 36 +- src/info.rs | 8 +- src/keyexpr.rs | 68 +-- src/liveliness.rs | 24 +- src/payload.rs | 52 +-- src/platform/synchronization.rs | 29 +- src/publication_cache.rs | 21 +- src/publisher.rs | 24 +- src/pull_subscriber.rs | 6 +- src/put.rs | 14 +- src/queryable.rs | 31 +- src/querying_subscriber.rs | 36 +- src/scouting.rs | 6 +- src/session.rs | 10 +- src/shm.rs | 4 +- src/subscriber.rs | 16 +- tests/z_api_alignment_test.c | 34 +- tests/z_api_attachment_test.c | 24 +- tests/z_api_double_drop_test.c | 4 +- tests/z_api_keyexpr_drop_test.c | 8 +- tests/z_api_keyexpr_test.c | 24 +- tests/z_api_payload_test.c | 2 +- tests/z_api_unitinialized_check.c | 2 +- tests/z_int_pub_cache_query_sub_test.c | 4 +- tests/z_int_pub_sub_attachment_test.c | 8 +- tests/z_int_pub_sub_test.c | 4 +- tests/z_int_queryable_attachment_test.c | 20 +- tests/z_int_queryable_test.c | 12 +- 57 files changed, 800 insertions(+), 726 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 7797578d5..512ea8b00 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -44,7 +44,7 @@ macro_rules! get_opaque_type_data { /// To minimize copies and reallocations, Zenoh may provide you data in split buffers. get_opaque_type_data!(Option, z_owned_bytes_t); /// A loaned payload. -get_opaque_type_data!(ZBytes, z_bytes_t); +get_opaque_type_data!(ZBytes, z_loaned_bytes_t); /// A contiguous view of bytes owned by some other entity. /// @@ -52,36 +52,36 @@ get_opaque_type_data!(ZBytes, z_bytes_t); /// and empty slices are represented using a possibly dangling pointer for `start`. get_opaque_type_data!(Option>, z_owned_slice_t); get_opaque_type_data!(Option<&'static [u8]>, z_view_slice_t); -get_opaque_type_data!(&'static [u8], z_slice_t); +get_opaque_type_data!(&'static [u8], z_loaned_slice_t); /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` /// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with /// `z_check` and `z_str_check` correspondently get_opaque_type_data!(Option>, z_owned_str_t); get_opaque_type_data!(Option<&'static [u8]>, z_view_str_t); -get_opaque_type_data!(&'static [u8], z_str_t); +get_opaque_type_data!(&'static [u8], z_loaned_str_t); /// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher get_opaque_type_data!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); -get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_slice_map_t); +get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_loaned_slice_map_t); /// An owned sample. /// -/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. get_opaque_type_data!(Option, zc_owned_sample_t); -get_opaque_type_data!(Sample, z_sample_t); +get_opaque_type_data!(Sample, z_loaned_sample_t); /// A reader for payload data. get_opaque_type_data!(Option>, z_owned_bytes_reader_t); -get_opaque_type_data!(ZBytesReader<'static>, z_bytes_reader_t); +get_opaque_type_data!(ZBytesReader<'static>, z_loaned_bytes_reader_t); /// The encoding of a payload, in a MIME-like format. /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. -get_opaque_type_data!(Encoding, z_encoding_t); +get_opaque_type_data!(Encoding, z_loaned_encoding_t); get_opaque_type_data!(Encoding, z_owned_encoding_t); /// An owned reply to a :c:func:`z_get`. @@ -92,18 +92,18 @@ get_opaque_type_data!(Encoding, z_owned_encoding_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. get_opaque_type_data!(Option, z_owned_reply_t); -get_opaque_type_data!(Reply, z_reply_t); +get_opaque_type_data!(Reply, z_loaned_reply_t); /// A zenoh value. get_opaque_type_data!(Value, z_owned_value_t); -get_opaque_type_data!(Value, z_value_t); +get_opaque_type_data!(Value, z_loaned_value_t); // Loaned variant of a Query received by a Queryable. /// /// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. -/// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. +/// `z_loaned_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. get_opaque_type_data!(Option, z_owned_query_t); -get_opaque_type_data!(Query, z_query_t); +get_opaque_type_data!(Query, z_loaned_query_t); /// An owned zenoh queryable. /// @@ -116,7 +116,7 @@ get_opaque_type_data!(Query, z_query_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_queryable_t); -get_opaque_type_data!(Queryable<'static, ()>, z_queryable_t); +get_opaque_type_data!(Queryable<'static, ()>, z_loaned_queryable_t); /// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. /// @@ -129,7 +129,7 @@ get_opaque_type_data!(Queryable<'static, ()>, z_queryable_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); -get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); +get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_loaned_querying_subscriber_t); /// A zenoh-allocated key expression. /// @@ -168,7 +168,7 @@ get_opaque_type_data!(Option>, z_view_keyexpr_t); /// /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. -get_opaque_type_data!(KeyExpr<'_>, z_keyexpr_t); +get_opaque_type_data!(KeyExpr<'_>, z_loaned_keyexpr_t); /// An owned zenoh session. /// @@ -181,7 +181,7 @@ get_opaque_type_data!(KeyExpr<'_>, z_keyexpr_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_session_t); -get_opaque_type_data!(Session, z_session_t); +get_opaque_type_data!(Session, z_loaned_session_t); /// An owned zenoh configuration. /// @@ -195,7 +195,7 @@ get_opaque_type_data!(Session, z_session_t); /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option, z_owned_config_t); /// A loaned zenoh configuration. -get_opaque_type_data!(Config, z_config_t); +get_opaque_type_data!(Config, z_loaned_config_t); /// Represents a Zenoh ID. /// @@ -215,7 +215,7 @@ get_opaque_type_data!(Timestamp, z_timestamp_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_publisher_t); -get_opaque_type_data!(Publisher<'static>, z_publisher_t); +get_opaque_type_data!(Publisher<'static>, z_loaned_publisher_t); /// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. /// @@ -241,7 +241,7 @@ get_opaque_type_data!(Option>, zcu_own /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_subscriber_t); -get_opaque_type_data!(Subscriber<'static, ()>, z_subscriber_t); +get_opaque_type_data!(Subscriber<'static, ()>, z_loaned_subscriber_t); /// A liveliness token that can be used to provide the network with information about connectivity to its /// declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key @@ -249,7 +249,7 @@ get_opaque_type_data!(Subscriber<'static, ()>, z_subscriber_t); /// /// A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. get_opaque_type_data!(Option>, zc_owned_liveliness_token_t); -get_opaque_type_data!(LivelinessToken<'static>, zc_liveliness_token_t); +get_opaque_type_data!(LivelinessToken<'static>, zc_loaned_liveliness_token_t); /// An owned zenoh publication_cache. @@ -263,13 +263,13 @@ get_opaque_type_data!(LivelinessToken<'static>, zc_liveliness_token_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, ze_owned_publication_cache_t); -get_opaque_type_data!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); +get_opaque_type_data!(zenoh_ext::PublicationCache<'static>, ze_loaned_publication_cache_t); get_opaque_type_data!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); -get_opaque_type_data!((Mutex<()>, Option>), z_mutex_t); +get_opaque_type_data!((Mutex<()>, Option>), z_loaned_mutex_t); get_opaque_type_data!(Option, z_owned_condvar_t); -get_opaque_type_data!(Condvar, z_condvar_t); +get_opaque_type_data!(Condvar, z_loaned_condvar_t); get_opaque_type_data!(Option>, z_owned_task_t); \ No newline at end of file diff --git a/docs/api.rst b/docs/api.rst index 046ede892..a5b0e1eea 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -22,7 +22,7 @@ Generic types Bytes ----- -.. autocstruct:: zenoh_commons.h::z_slice_t +.. autocstruct:: zenoh_commons.h::z_loaned_slice_t .. autocfunction:: zenoh_commons.h::z_slice_new .. autocfunction:: zenoh_commons.h::z_slice_check @@ -56,7 +56,7 @@ Session configuration --------------------- -.. autocstruct:: zenoh_commons.h::z_config_t +.. autocstruct:: zenoh_commons.h::z_loaned_config_t .. autocstruct:: zenoh_commons.h::z_owned_config_t .. autocstruct:: zenoh_commons.h::z_owned_scouting_config_t @@ -79,7 +79,7 @@ Session management Types ^^^^^ -.. autocstruct:: zenoh_concrete.h::z_session_t +.. autocstruct:: zenoh_concrete.h::z_loaned_session_t .. autocstruct:: zenoh_concrete.h::z_owned_session_t .. autocstruct:: zenoh_commons.h::z_owned_closure_zid_t @@ -104,13 +104,13 @@ Functions Key expression ============== -.. autocstruct:: zenoh_commons.h::z_keyexpr_t +.. autocstruct:: zenoh_commons.h::z_loaned_keyexpr_t .. 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_loaned_keyexpr_to_string .. autocfunction:: zenoh_commons.h::z_keyexpr_as_bytes .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize_null_terminated @@ -133,7 +133,7 @@ Key expression Encoding ======== -.. autocstruct:: zenoh_commons.h::z_encoding_t +.. autocstruct:: zenoh_commons.h::z_loaned_encoding_t .. autocstruct:: zenoh_commons.h::z_owned_encoding_t .. autocfunction:: zenoh_commons.h::z_encoding_default @@ -147,12 +147,12 @@ Encoding Value ===== -.. autocstruct:: zenoh_commons.h::z_value_t +.. autocstruct:: zenoh_commons.h::z_loaned_value_t Sample ====== -.. autocstruct:: zenoh_commons.h::z_sample_t +.. autocstruct:: zenoh_commons.h::z_loaned_sample_t Attachment ========== @@ -237,7 +237,7 @@ Types .. autocstruct:: zenoh_commons.h::z_get_options_t -.. autocenum:: zenoh_commons.h::z_query_target_t +.. autocenum:: zenoh_commons.h::z_loaned_query_target_t .. autocenum:: zenoh_commons.h::z_consolidation_mode_t diff --git a/docs/examples.rst b/docs/examples.rst index bea19cbbe..1aab457a6 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -43,8 +43,8 @@ Subscribe #include #include "zenoh.h" - void data_handler(const z_sample_t *sample, const void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + void data_handler(const z_loaned_sample_t *sample, const void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(sample->keyexpr); printf(">> Received (%s, %.*s)\n", keystr, (int)sample->payload.len, sample->payload.start); z_drop(z_move(keystr)); @@ -86,8 +86,8 @@ Query { if (z_reply_is_ok(&reply)) { - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + z_loaned_sample_t sample = z_reply_ok(&reply); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(sample.keyexpr); printf(">> Received ('%s': '%.*s')\n", keystr, (int)sample.payload.len, sample.payload.start); z_drop(z_move(keystr)); } diff --git a/examples/z_get.c b/examples/z_get.c index 90291189c..00eb2a524 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -68,8 +68,8 @@ int main(int argc, char **argv) { z_owned_str_t reply_str; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(z_loan(reply))) { - z_sample_t sample = z_reply_ok(z_loan(reply)); - z_owned_str_t key_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); z_bytes_decode_into_string(z_sample_payload(&sample), &reply_str); printf(">> Received ('%s': '%s')\n", z_loan(key_str), z_loan(reply_str)); z_drop(z_move(reply_str)); diff --git a/examples/z_get_liveliness.c b/examples/z_get_liveliness.c index 08ed225f1..025b09db3 100644 --- a/examples/z_get_liveliness.c +++ b/examples/z_get_liveliness.c @@ -53,8 +53,8 @@ int main(int argc, char **argv) { z_owned_reply_t reply; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(z_loan(reply))) { - z_sample_t sample = z_reply_ok(z_loan(reply)); - z_owned_str_t key_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); printf(">> Alive token ('%s')\n", z_loan(key_str)); z_drop(z_move(key_str)); } else { diff --git a/examples/z_liveliness.c b/examples/z_liveliness.c index 4191b0496..bc71da8eb 100644 --- a/examples/z_liveliness.c +++ b/examples/z_liveliness.c @@ -21,7 +21,7 @@ int main(int argc, char **argv) { expr = argv[1]; } - z_keyexpr_t keyexpr = z_keyexpr(expr); + z_loaned_keyexpr_t keyexpr = z_keyexpr(expr); if (!z_check(keyexpr)) { printf("%s is not a valid key expression\n", expr); exit(-1); diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index 30df45daf..c84074e67 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -21,7 +21,7 @@ int main(int argc, char **argv) { if (argc > 1) { expr = argv[1]; } - z_keyexpr_t keyexpr = z_keyexpr(expr); + z_loaned_keyexpr_t keyexpr = z_keyexpr(expr); if (!z_check(keyexpr)) { printf("%s is not a valid key expression", expr); exit(-1); @@ -58,8 +58,8 @@ int main(int argc, char **argv) { continue; } if (z_reply_is_ok(&reply)) { - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(&reply); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); diff --git a/examples/z_ping.c b/examples/z_ping.c index 8f8adb2f7..87dc697ab 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -13,10 +13,10 @@ #define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) -z_condvar_t cond; -z_mutex_t mutex; +z_loaned_condvar_t cond; +z_loaned_mutex_t mutex; -void callback(const z_sample_t* sample, void* context) { z_condvar_signal(&cond); } +void callback(const z_loaned_sample_t* sample, void* context) { z_condvar_signal(&cond); } void drop(void* context) { z_condvar_free(&cond); } struct args_t { @@ -45,8 +45,8 @@ int main(int argc, char** argv) { z_condvar_init(&cond); z_owned_config_t config = args.config_path ? zc_config_from_file(args.config_path) : z_config_default(); z_owned_session_t session = z_open(z_move(config)); - z_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); - z_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); + z_loaned_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); + z_loaned_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); z_owned_publisher_t pub = z_declare_publisher(z_loan(session), ping, NULL); z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)(&pub)); z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), pong, z_move(respond), NULL); @@ -54,7 +54,7 @@ int main(int argc, char** argv) { for (int i = 0; i < args.size; i++) { data[i] = i % 10; } - z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_slice_t){.start = data, .len = args.size}); + z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_loaned_slice_t){.start = data, .len = args.size}); z_mutex_lock(&mutex); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); diff --git a/examples/z_pong.c b/examples/z_pong.c index 3da1150bb..b8920f70d 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -3,8 +3,8 @@ #include "zenoh.h" -void callback(const z_sample_t* sample, void* context) { - z_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); +void callback(const z_loaned_sample_t* sample, void* context) { + z_loaned_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); #ifdef ZENOH_C // The z_owned_bytes_t API is exclusive to zenoh-c, but allows avoiding some copies. z_owned_bytes_t payload = z_sample_owned_payload(sample); z_publisher_put(pub, z_move(payload), NULL); @@ -34,8 +34,8 @@ int main(int argc, char** argv) { } z_owned_config_t config = args.config_path ? zc_config_from_file(args.config_path) : z_config_default(); z_owned_session_t session = z_open(z_move(config)); - z_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); - z_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); + z_loaned_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); + z_loaned_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); z_owned_publisher_t pub = z_declare_publisher(z_loan(session), pong, NULL); z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)z_move(pub)); z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), ping, z_move(respond), NULL); diff --git a/examples/z_pub_thr.c b/examples/z_pub_thr.c index 0298ceacf..c59f3f6c7 100644 --- a/examples/z_pub_thr.c +++ b/examples/z_pub_thr.c @@ -54,7 +54,7 @@ int main(int argc, char **argv) { } while (1) { - z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_slice_t){.start = value, .len = len}); + z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_loaned_slice_t){.start = value, .len = len}); z_publisher_put(z_loan(pub), z_move(payload), NULL); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index a2f878019..4a2d72cc9 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -16,8 +16,8 @@ const char *kind_to_str(z_sample_kind_t kind); -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); +void data_handler(const z_loaned_sample_t *sample, void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 4342c6746..191daf413 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -17,12 +17,12 @@ const char *expr = "demo/example/zenoh-c-queryable"; const char *value = "Queryable from C!"; -z_keyexpr_t keyexpr; +z_loaned_keyexpr_t keyexpr; -void query_handler(const z_query_t *query, void *context) { - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_slice_t pred = z_query_parameters(query); - z_bytes_t payload = z_query_value(query).payload; +void query_handler(const z_loaned_query_t *query, void *context) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); + z_loaned_slice_t pred = z_query_parameters(query); + z_loaned_bytes_t payload = z_query_value(query).payload; if (z_bytes_len(payload) > 0) { z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(payload, &payload_value); diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 422ad3971..0fec21120 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -18,9 +18,9 @@ const char *expr = "demo/example/zenoh-c-queryable"; const char *value = "Queryable from C!"; -z_keyexpr_t keyexpr; +z_loaned_keyexpr_t keyexpr; -void query_handler(const z_query_t *query, void *context) { +void query_handler(const z_loaned_query_t *query, void *context) { z_owned_closure_owned_query_t *channel = (z_owned_closure_owned_query_t *)context; z_owned_query_t oquery = z_query_clone(query); z_call(*channel, &oquery); @@ -65,10 +65,10 @@ int main(int argc, char **argv) { printf("^C to quit...\n"); z_owned_query_t oquery = z_query_null(); for (z_call(channel.recv, &oquery); z_check(oquery); z_call(channel.recv, &oquery)) { - z_query_t query = z_loan(oquery); - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(&query)); - z_slice_t pred = z_query_parameters(&query); - z_bytes_t payload = z_query_value(&query).payload; + z_loaned_query_t query = z_loan(oquery); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(&query)); + z_loaned_slice_t pred = z_query_parameters(&query); + z_loaned_bytes_t payload = z_query_value(&query).payload; if (z_bytes_len(payload) > 0) { z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(payload, &payload_value); diff --git a/examples/z_sub.c b/examples/z_sub.c index f549d1561..f5b986634 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -16,8 +16,8 @@ const char *kind_to_str(z_sample_kind_t kind); -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); +void data_handler(const z_loaned_sample_t *sample, void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 6c1ea68be..13412321a 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -17,26 +17,26 @@ const char *kind_to_str(z_sample_kind_t kind); -int8_t attachment_reader(z_slice_t key, z_slice_t val, void *ctx) { +int8_t attachment_reader(z_loaned_slice_t key, z_loaned_slice_t val, void *ctx) { printf(" attachment: %.*s: '%.*s'\n", (int)key.len, key.start, (int)val.len, val.start); return 0; } -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); +void data_handler(const z_loaned_sample_t *sample, void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); - z_bytes_t attachment = z_sample_attachment(sample); + z_loaned_bytes_t attachment = z_sample_attachment(sample); // checks if attachment exists if (z_check(attachment)) { // reads full attachment z_attachment_iterate(attachment, attachment_reader, NULL); // reads particular attachment item - z_slice_t index = z_attachment_get(attachment, z_slice_from_str("index")); + z_loaned_slice_t index = z_attachment_get(attachment, z_slice_from_str("index")); if (z_slice_is_initialized(&index)) { printf(" message number: %.*s\n", (int)index.len, index.start); } diff --git a/examples/z_sub_liveliness.c b/examples/z_sub_liveliness.c index 5916200b2..5c6b49d6a 100644 --- a/examples/z_sub_liveliness.c +++ b/examples/z_sub_liveliness.c @@ -14,8 +14,8 @@ #include #include "zenoh.h" -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); +void data_handler(const z_loaned_sample_t *sample, void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); switch (z_sample_kind(sample)) { case Z_SAMPLE_KIND_PUT: printf(">> [LivelinessSubscriber] New alive token ('%s')\n", z_loan(keystr)); @@ -33,7 +33,7 @@ int main(int argc, char **argv) { expr = argv[1]; } - z_keyexpr_t keyexpr = z_keyexpr(expr); + z_loaned_keyexpr_t keyexpr = z_keyexpr(expr); if (!z_check(keyexpr)) { printf("%s is not a valid key expression\n", expr); exit(-1); diff --git a/examples/z_sub_thr.c b/examples/z_sub_thr.c index 3fdfe1e2a..d7e69a29f 100644 --- a/examples/z_sub_thr.c +++ b/examples/z_sub_thr.c @@ -34,7 +34,7 @@ z_stats_t *z_stats_make() { return stats; } -void on_sample(z_sample_t sample, void *context) { +void on_sample(z_loaned_sample_t sample, void *context) { z_stats_t *stats = (z_stats_t *)context; if (stats->count == 0) { stats->start = z_clock_now(); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 3944d26e1..35429b0d6 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -59,6 +59,18 @@ typedef enum z_keyexpr_intersection_level_t { Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, } z_keyexpr_intersection_level_t; +/** + * The Queryables that should be target of a :c:func:`z_get`. + * + * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. + * - **ALL_COMPLETE**: All complete queryables. + * - **ALL**: All matching queryables. + */ +typedef enum z_loaned_query_target_t { + Z_LOANED_QUERY_TARGET_BEST_MATCHING, + Z_LOANED_QUERY_TARGET_ALL, + Z_LOANED_QUERY_TARGET_ALL_COMPLETE, +} z_loaned_query_target_t; /** * The priority of zenoh messages. * @@ -79,18 +91,6 @@ typedef enum z_priority_t { Z_PRIORITY_DATA_LOW = 6, Z_PRIORITY_BACKGROUND = 7, } z_priority_t; -/** - * The Queryables that should be target of a :c:func:`z_get`. - * - * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. - * - **ALL_COMPLETE**: All complete queryables. - * - **ALL**: All matching queryables. - */ -typedef enum z_query_target_t { - Z_QUERY_TARGET_BEST_MATCHING, - Z_QUERY_TARGET_ALL, - Z_QUERY_TARGET_ALL_COMPLETE, -} z_query_target_t; /** * The subscription reliability. * @@ -125,9 +125,9 @@ typedef struct ALIGN(8) z_owned_bytes_t { /** * A loaned payload. */ -typedef struct ALIGN(8) z_bytes_t { +typedef struct ALIGN(8) z_loaned_bytes_t { uint8_t _0[40]; -} z_bytes_t; +} z_loaned_bytes_t; typedef int8_t z_error_t; /** * A contiguous view of bytes owned by some other entity. @@ -154,24 +154,24 @@ typedef struct ALIGN(8) z_owned_slice_map_t { typedef struct ALIGN(8) z_owned_str_t { uint8_t _0[16]; } z_owned_str_t; -typedef struct ALIGN(8) z_slice_t { +typedef struct ALIGN(8) z_loaned_slice_t { uint8_t _0[16]; -} z_slice_t; -typedef struct ALIGN(8) z_slice_map_t { +} z_loaned_slice_t; +typedef struct ALIGN(8) z_loaned_slice_map_t { uint8_t _0[48]; -} z_slice_map_t; -typedef struct ALIGN(8) z_str_t { +} z_loaned_slice_map_t; +typedef struct ALIGN(8) z_loaned_str_t { uint8_t _0[16]; -} z_str_t; +} z_loaned_str_t; /** * A reader for payload data. */ typedef struct ALIGN(8) z_owned_bytes_reader_t { uint8_t _0[24]; } z_owned_bytes_reader_t; -typedef struct ALIGN(8) z_bytes_reader_t { +typedef struct ALIGN(8) z_loaned_bytes_reader_t { uint8_t _0[24]; -} z_bytes_reader_t; +} z_loaned_bytes_reader_t; /** * Clock * Uses monotonic clock @@ -244,7 +244,7 @@ typedef struct z_owned_closure_hello_t { /** * * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. - * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. + * `z_loaned_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. */ typedef struct ALIGN(8) z_owned_query_t { uint8_t _0[16]; @@ -254,7 +254,7 @@ typedef struct ALIGN(8) z_owned_query_t { * * Members: * void *context: a pointer to an arbitrary state. - * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *call(const struct z_loaned_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. * void *drop(void*): allows the callback's state to be freed. * * Closures are not guaranteed not to be called concurrently. @@ -275,7 +275,7 @@ typedef struct z_owned_closure_owned_query_t { * * Members: * void *context: a pointer to an arbitrary state. - * void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *call(z_loaned_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. * void *drop(void*): allows the callback's state to be freed. * * Closures are not guaranteed not to be called concurrently. @@ -288,12 +288,12 @@ typedef struct z_owned_closure_owned_query_t { */ typedef struct z_owned_closure_query_t { void *context; - void (*call)(const struct z_query_t*, void *context); + void (*call)(const struct z_loaned_query_t*, void *context); void (*drop)(void*); } z_owned_closure_query_t; -typedef struct ALIGN(8) z_reply_t { +typedef struct ALIGN(8) z_loaned_reply_t { uint8_t _0[256]; -} z_reply_t; +} z_loaned_reply_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * @@ -312,18 +312,18 @@ typedef struct ALIGN(8) z_reply_t { */ typedef struct z_owned_closure_reply_t { void *context; - void (*call)(const struct z_reply_t*, void*); + void (*call)(const struct z_loaned_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; -typedef struct ALIGN(8) z_sample_t { +typedef struct ALIGN(8) z_loaned_sample_t { uint8_t _0[240]; -} z_sample_t; +} z_loaned_sample_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. * * Members: * void *context: a pointer to an arbitrary state. - * void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *call(struct z_loaned_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. * void *drop(void*): allows the callback's state to be freed. * * Closures are not guaranteed not to be called concurrently. @@ -336,7 +336,7 @@ typedef struct ALIGN(8) z_sample_t { */ typedef struct z_owned_closure_sample_t { void *context; - void (*call)(const struct z_sample_t*, void *context); + void (*call)(const struct z_loaned_sample_t*, void *context); void (*drop)(void*); } z_owned_closure_sample_t; /** @@ -363,12 +363,12 @@ typedef struct z_owned_closure_zid_t { typedef struct ALIGN(8) z_owned_condvar_t { uint8_t _0[24]; } z_owned_condvar_t; -typedef struct ALIGN(8) z_condvar_t { +typedef struct ALIGN(8) z_loaned_condvar_t { uint8_t _0[16]; -} z_condvar_t; -typedef struct ALIGN(8) z_mutex_t { +} z_loaned_condvar_t; +typedef struct ALIGN(8) z_loaned_mutex_t { uint8_t _0[32]; -} z_mutex_t; +} z_loaned_mutex_t; /** * An owned zenoh configuration. * @@ -387,9 +387,9 @@ typedef struct ALIGN(8) z_owned_config_t { /** * A loaned zenoh configuration. */ -typedef struct ALIGN(8) z_config_t { +typedef struct ALIGN(8) z_loaned_config_t { uint8_t _0[1544]; -} z_config_t; +} z_loaned_config_t; /** * A zenoh-allocated key expression. * @@ -431,9 +431,9 @@ typedef struct ALIGN(8) z_owned_keyexpr_t { * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, * both for local processing and network-wise. */ -typedef struct ALIGN(8) z_keyexpr_t { +typedef struct ALIGN(8) z_loaned_keyexpr_t { uint8_t _0[32]; -} z_keyexpr_t; +} z_loaned_keyexpr_t; /** * An owned zenoh publisher. * @@ -493,9 +493,9 @@ typedef struct ALIGN(8) z_owned_encoding_t { * * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. */ -typedef struct ALIGN(8) z_encoding_t { +typedef struct ALIGN(8) z_loaned_encoding_t { uint8_t _0[48]; -} z_encoding_t; +} z_loaned_encoding_t; /** * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. */ @@ -506,14 +506,14 @@ typedef struct z_query_consolidation_t { * Options passed to the :c:func:`z_get` function. * * Members: - * z_query_target_t target: The Queryables that should be target of the query. + * z_loaned_query_target_t target: The Queryables that should be target of the query. * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. - * z_value_t value: An optional value to attach to the query. - * z_bytes_t attachment: The attachment to attach to the query. + * z_loaned_value_t value: An optional value to attach to the query. + * z_loaned_bytes_t attachment: The attachment to attach to the query. * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. */ typedef struct z_get_options_t { - enum z_query_target_t target; + enum z_loaned_query_target_t target; struct z_query_consolidation_t consolidation; struct z_owned_bytes_t *payload; struct z_owned_encoding_t *encoding; @@ -552,12 +552,15 @@ typedef struct ALIGN(8) z_view_slice_t { typedef struct ALIGN(8) z_view_keyexpr_t { uint8_t _0[32]; } z_view_keyexpr_t; +typedef struct ALIGN(8) z_timestamp_t { + uint8_t _0[24]; +} z_timestamp_t; typedef struct ALIGN(8) z_owned_mutex_t { uint8_t _0[32]; } z_owned_mutex_t; -typedef struct ALIGN(8) z_publisher_t { +typedef struct ALIGN(8) z_loaned_publisher_t { uint8_t _0[56]; -} z_publisher_t; +} z_loaned_publisher_t; /** * Represents the set of options that can be applied to the delete operation by a previously declared publisher, * whenever issued via :c:func:`z_publisher_delete`. @@ -580,10 +583,10 @@ typedef struct z_publisher_put_options_t { * Options passed to the :c:func:`z_put` function. * * Members: - * z_encoding_t encoding: The encoding of the payload. + * z_loaned_encoding_t encoding: The encoding of the payload. * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. * z_priority_t priority: The priority of this message. - * z_bytes_t attachment: The attachment to this message. + * z_loaned_bytes_t attachment: The attachment to this message. */ typedef struct z_put_options_t { struct z_owned_encoding_t *encoding; @@ -628,9 +631,9 @@ typedef struct z_query_reply_options_t { struct z_owned_encoding_t *encoding; struct z_owned_bytes_t *attachment; } z_query_reply_options_t; -typedef struct ALIGN(8) z_value_t { +typedef struct ALIGN(8) z_loaned_value_t { uint8_t _0[88]; -} z_value_t; +} z_loaned_value_t; /** * An owned reply to a :c:func:`z_get`. * @@ -671,15 +674,12 @@ typedef struct z_owned_reply_channel_t { /** * An owned sample. * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. */ typedef struct ALIGN(8) zc_owned_sample_t { uint8_t _0[240]; } zc_owned_sample_t; -typedef struct ALIGN(8) z_timestamp_t { - uint8_t _0[24]; -} z_timestamp_t; typedef struct z_owned_scouting_config_t { struct z_owned_config_t _config; unsigned long zc_timeout_ms; @@ -693,12 +693,12 @@ typedef struct z_owned_scouting_config_t { * * Returning `true` is treated as `continue`. */ -typedef bool (*z_slice_map_iter_body_t)(const struct z_slice_t *key, - const struct z_slice_t *value, +typedef bool (*z_slice_map_iter_body_t)(const struct z_loaned_slice_t *key, + const struct z_loaned_slice_t *value, void *context); -typedef struct ALIGN(8) z_subscriber_t { +typedef struct ALIGN(8) z_loaned_subscriber_t { uint8_t _0[32]; -} z_subscriber_t; +} z_loaned_subscriber_t; typedef struct ALIGN(8) z_owned_task_t { uint8_t _0[24]; } z_owned_task_t; @@ -807,7 +807,7 @@ typedef struct ALIGN(8) ze_owned_publication_cache_t { * Options passed to the :c:func:`ze_declare_publication_cache` function. * * Members: - * z_keyexpr_t queryable_prefix: The prefix used for queryable + * z_loaned_keyexpr_t queryable_prefix: The prefix used for queryable * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this * publication cache * bool queryable_complete: the `complete` option for the queryable @@ -815,7 +815,7 @@ typedef struct ALIGN(8) ze_owned_publication_cache_t { * size_t resources_limit: The limit number of cached resources */ typedef struct ze_publication_cache_options_t { - const struct z_keyexpr_t *queryable_prefix; + const struct z_loaned_keyexpr_t *queryable_prefix; enum zcu_locality_t queryable_origin; bool queryable_complete; size_t history; @@ -844,8 +844,8 @@ typedef struct ALIGN(8) ze_owned_querying_subscriber_t { * z_reliability_t reliability: The subscription reliability. * zcu_locality_t allowed_origin: The restriction for the matching publications that will be * receive by this subscriber. - * z_keyexpr_t query_selector: The selector to be used for queries. - * z_query_target_t query_target: The target to be used for queries. + * z_loaned_keyexpr_t query_selector: The selector to be used for queries. + * z_loaned_query_target_t query_target: The target to be used for queries. * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. * uint64_t query_timeout_ms: The timeout to be used for queries. @@ -853,15 +853,15 @@ typedef struct ALIGN(8) ze_owned_querying_subscriber_t { typedef struct ze_querying_subscriber_options_t { enum z_reliability_t reliability; enum zcu_locality_t allowed_origin; - const struct z_keyexpr_t *query_selector; - enum z_query_target_t query_target; + const struct z_loaned_keyexpr_t *query_selector; + enum z_loaned_query_target_t query_target; struct z_query_consolidation_t query_consolidation; enum zcu_reply_keyexpr_t query_accept_replies; uint64_t query_timeout_ms; } ze_querying_subscriber_options_t; -typedef struct ALIGN(8) ze_querying_subscriber_t { +typedef struct ALIGN(8) ze_loaned_querying_subscriber_t { uint8_t _0[64]; -} ze_querying_subscriber_t; +} ze_loaned_querying_subscriber_t; ZENOHC_API extern const unsigned int Z_ROUTER; ZENOHC_API extern const unsigned int Z_PEER; ZENOHC_API extern const unsigned int Z_CLIENT; @@ -883,24 +883,24 @@ ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); /** * Increments the payload's reference count, returning an owned version of it. */ -ZENOHC_API void z_bytes_clone(const struct z_bytes_t *src, struct z_owned_bytes_t *dst); +ZENOHC_API void z_bytes_clone(const struct z_loaned_bytes_t *src, struct z_owned_bytes_t *dst); /** * Decodes payload into owned bytes */ ZENOHC_API -z_error_t z_bytes_decode_into_bytes(const struct z_bytes_t *payload, +z_error_t z_bytes_decode_into_bytes(const struct z_loaned_bytes_t *payload, struct z_owned_slice_t *dst); /** * Decodes payload into bytes map. */ ZENOHC_API -z_error_t z_bytes_decode_into_bytes_map(struct z_bytes_t payload, +z_error_t z_bytes_decode_into_bytes_map(struct z_loaned_bytes_t payload, struct z_owned_slice_map_t *dst); /** * Decodes payload into null-terminated string. */ ZENOHC_API -z_error_t z_bytes_decode_into_string(const struct z_bytes_t *payload, +z_error_t z_bytes_decode_into_string(const struct z_loaned_bytes_t *payload, struct z_owned_str_t *dst); /** * Decrements the payload's reference counter, destroying it if applicable. @@ -913,25 +913,27 @@ ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); */ ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, - const struct z_slice_t *bytes); + const struct z_loaned_slice_t *bytes); /** * Encodes bytes map by copying. */ ZENOHC_API void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, - const struct z_slice_map_t *bytes_map); + const struct z_loaned_slice_map_t *bytes_map); /** * Encodes a null-terminated string by aliasing. */ -ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const struct z_str_t *s); +ZENOHC_API +void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, + const struct z_loaned_str_t *s); /** * Returns total number bytes in the payload. */ -ZENOHC_API size_t z_bytes_len(const struct z_bytes_t *payload); +ZENOHC_API size_t z_bytes_len(const struct z_loaned_bytes_t *payload); /** * Loans the payload, allowing you to call functions that only need a loan of it. */ -ZENOHC_API const struct z_bytes_t *z_bytes_loan(const struct z_owned_bytes_t *payload); +ZENOHC_API const struct z_loaned_bytes_t *z_bytes_loan(const struct z_owned_bytes_t *payload); /** * The gravestone value for `z_owned_bytes_t`. */ @@ -939,14 +941,17 @@ ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_reader_t *this_); ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_reader_t *this_); ZENOHC_API -const struct z_bytes_reader_t *z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); -ZENOHC_API struct z_bytes_reader_t *z_bytes_reader_loan_mut(struct z_owned_bytes_reader_t *reader); +const struct z_loaned_bytes_reader_t *z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); +ZENOHC_API +struct z_loaned_bytes_reader_t *z_bytes_reader_loan_mut(struct z_owned_bytes_reader_t *reader); /** * Creates a reader for the specified `payload`. * * Returns 0 in case of success, -1 if `payload` is not valid. */ -ZENOHC_API void z_bytes_reader_new(struct z_bytes_t payload, struct z_owned_bytes_reader_t *this_); +ZENOHC_API +void z_bytes_reader_new(struct z_loaned_bytes_t payload, + struct z_owned_bytes_reader_t *this_); ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); /** * Reads data into specified destination. @@ -955,7 +960,7 @@ ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. */ ZENOHC_API -size_t z_bytes_reader_read(struct z_bytes_reader_t *this_, +size_t z_bytes_reader_read(struct z_loaned_bytes_reader_t *this_, uint8_t *dest, size_t len); /** @@ -965,14 +970,9 @@ size_t z_bytes_reader_read(struct z_bytes_reader_t *this_, * Return ​0​ upon success, negative error code otherwise. */ ZENOHC_API -z_error_t z_bytes_reader_seek(struct z_bytes_reader_t *this_, +z_error_t z_bytes_reader_seek(struct z_loaned_bytes_reader_t *this_, int64_t offset, int origin); -/** - * Returns the read position indicator. - * Returns read position indicator on success or -1L if failure occurs. - */ -ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t *this_); ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); @@ -1017,7 +1017,7 @@ ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void) */ ZENOHC_API void z_closure_query_call(const struct z_owned_closure_query_t *closure, - const struct z_query_t *query); + const struct z_loaned_query_t *query); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1031,7 +1031,7 @@ ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); */ ZENOHC_API void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, - const struct z_reply_t *reply); + const struct z_loaned_reply_t *reply); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1045,7 +1045,7 @@ ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); */ ZENOHC_API void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - const struct z_sample_t *sample); + const struct z_loaned_sample_t *sample); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1071,11 +1071,13 @@ ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); -ZENOHC_API const struct z_condvar_t *z_condvar_loan(const struct z_owned_condvar_t *this_); -ZENOHC_API struct z_condvar_t *z_condvar_loan_mut(struct z_owned_condvar_t *this_); +ZENOHC_API const struct z_loaned_condvar_t *z_condvar_loan(const struct z_owned_condvar_t *this_); +ZENOHC_API struct z_loaned_condvar_t *z_condvar_loan_mut(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); -ZENOHC_API z_error_t z_condvar_signal(const struct z_condvar_t *this_); -ZENOHC_API z_error_t z_condvar_wait(const struct z_condvar_t *this_, struct z_mutex_t *m); +ZENOHC_API z_error_t z_condvar_signal(const struct z_loaned_condvar_t *this_); +ZENOHC_API +z_error_t z_condvar_wait(const struct z_loaned_condvar_t *this_, + struct z_loaned_mutex_t *m); /** * Returns ``true`` if `config` is valid. */ @@ -1091,7 +1093,7 @@ z_error_t z_config_client(struct z_owned_config_t *this_, /** * Clones the config. */ -ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); +ZENOHC_API void z_config_clone(const struct z_loaned_config_t *src, struct z_owned_config_t *dst); /** * Return a new, zenoh-allocated, empty configuration. * @@ -1111,13 +1113,13 @@ void z_config_default(struct z_owned_config_t *this_); */ ZENOHC_API void z_config_drop(struct z_owned_config_t *config); /** - * Returns a :c:type:`z_config_t` loaned from `s`. + * Returns a :c:type:`z_loaned_config_t` loaned from `s`. */ -ZENOHC_API const struct z_config_t *z_config_loan(const struct z_owned_config_t *this_); +ZENOHC_API const struct z_loaned_config_t *z_config_loan(const struct z_owned_config_t *this_); /** - * Returns a :c:type:`z_config_t` loaned from `s`. + * Returns a :c:type:`z_loaned_config_t` loaned from `s`. */ -ZENOHC_API struct z_config_t *z_config_loan_mut(struct z_owned_config_t *this_); +ZENOHC_API struct z_loaned_config_t *z_config_loan_mut(struct z_owned_config_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_config_t' type */ @@ -1127,15 +1129,15 @@ ZENOHC_API void z_config_null(struct z_owned_config_t *this_); */ ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); /** - * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. + * Declare a key expression. The id is returned as a :c:type:`z_loaned_keyexpr_t` with a nullptr suffix. * * This numerical id will be used on the network to save bandwidth and * ease the retrieval of the concerned resource in the routing tables. */ ZENOHC_API z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr); + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr); /** * Declares a publisher for the given key expression. * @@ -1173,8 +1175,8 @@ z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, */ ZENOHC_API z_error_t z_declare_publisher(struct z_owned_publisher_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, const struct z_publisher_options_t *options); /** * Creates a Queryable for the given key expression. @@ -1190,8 +1192,8 @@ z_error_t z_declare_publisher(struct z_owned_publisher_t *this_, */ ZENOHC_API z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_query_t *callback, struct z_queryable_options_t *options); /** @@ -1229,8 +1231,8 @@ z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, */ ZENOHC_API z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct z_subscriber_options_t *options); /** @@ -1244,8 +1246,8 @@ z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -z_error_t z_delete(const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, +z_error_t z_delete(const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_delete_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. @@ -1256,21 +1258,22 @@ ZENOHC_API void z_delete_options_default(struct z_delete_options_t *this_); */ ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); /** - * Constructs a default :c:type:`z_encoding_t`. + * Constructs a default :c:type:`z_loaned_encoding_t`. */ -ZENOHC_API const struct z_encoding_t *z_encoding_default(void); +ZENOHC_API const struct z_loaned_encoding_t *z_encoding_default(void); /** * Frees `encoding`, invalidating it for double-drop safety. */ ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); /** - * Constructs a specific :c:type:`z_encoding_t`. + * Constructs a specific :c:type:`z_loaned_encoding_t`. */ ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); /** - * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + * Returns a :c:type:`z_loaned_encoding_t` loaned from `encoding`. */ -ZENOHC_API const struct z_encoding_t *z_encoding_loan(const struct z_owned_encoding_t *encoding); +ZENOHC_API +const struct z_loaned_encoding_t *z_encoding_loan(const struct z_owned_encoding_t *encoding); /** * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type */ @@ -1292,8 +1295,8 @@ ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); * options: additional options for the get. */ ZENOHC_API -z_error_t z_get(const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, +z_error_t z_get(const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, const char *parameters, struct z_owned_closure_reply_t *callback, struct z_get_options_t *options); @@ -1323,7 +1326,7 @@ ZENOHC_API void z_hello_null(struct z_owned_hello_t *this_); * Retuns 0 on success, negative values on failure */ ZENOHC_API -z_error_t z_info_peers_zid(struct z_session_t session, +z_error_t z_info_peers_zid(struct z_loaned_session_t session, struct z_owned_closure_zid_t *callback); /** * Fetches the Zenoh IDs of all connected routers. @@ -1334,7 +1337,7 @@ z_error_t z_info_peers_zid(struct z_session_t session, * Retuns 0 on success, negative values on failure. */ ZENOHC_API -z_error_t z_info_routers_zid(struct z_session_t session, +z_error_t z_info_routers_zid(struct z_loaned_session_t session, struct z_owned_closure_zid_t *callback); /** * Returns the local Zenoh ID. @@ -1343,13 +1346,13 @@ z_error_t z_info_routers_zid(struct z_session_t session, * In other words, this function returning an array of 16 zeros means you failed * to pass it a valid session. */ -ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); +ZENOHC_API struct z_id_t z_info_zid(struct z_loaned_session_t session); /** * Returns the key expression's internal string by aliasing it. * * Currently exclusive to zenoh-c */ -ZENOHC_API void z_keyexpr_as_bytes(const struct z_keyexpr_t *ke, struct z_view_slice_t *b); +ZENOHC_API void z_keyexpr_as_bytes(const struct z_loaned_keyexpr_t *ke, struct z_view_slice_t *b); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. * @@ -1388,7 +1391,7 @@ ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); */ ZENOHC_API z_error_t z_keyexpr_concat(struct z_owned_keyexpr_t *this_, - const struct z_keyexpr_t *left, + const struct z_loaned_keyexpr_t *left, const char *right_start, size_t right_len); /** @@ -1398,21 +1401,23 @@ ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); /** * Returns ``0`` if both ``left`` and ``right`` are equal. */ -ZENOHC_API bool z_keyexpr_equals(const struct z_keyexpr_t *left, const struct z_keyexpr_t *right); +ZENOHC_API +bool z_keyexpr_equals(const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set * defined by ``right``. */ ZENOHC_API -bool z_keyexpr_includes(const struct z_keyexpr_t *left, - const struct z_keyexpr_t *right); +bool z_keyexpr_includes(const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the * sets defined by ``left`` and ``right``. */ ZENOHC_API -bool z_keyexpr_intersects(const struct z_keyexpr_t *left, - const struct z_keyexpr_t *right); +bool z_keyexpr_intersects(const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** * Returns ``0`` if the passed string is a valid (and canon) key expression. * Otherwise returns error value @@ -1424,12 +1429,13 @@ ZENOHC_API z_error_t z_keyexpr_is_canon(const char *start, size_t len); */ ZENOHC_API z_error_t z_keyexpr_join(struct z_owned_keyexpr_t *this_, - const struct z_keyexpr_t *left, - const struct z_keyexpr_t *right); + const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + * Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. */ -ZENOHC_API const struct z_keyexpr_t *z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. */ @@ -1450,15 +1456,10 @@ ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. */ ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_keyexpr_t *left, - const struct z_keyexpr_t *right); -/** - * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. - * The user is responsible of droping the returned string using `z_drop` - */ -ZENOHC_API void z_keyexpr_to_string(const struct z_keyexpr_t *ke, struct z_owned_str_t *s); +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: * * - `name` MUST be valid UTF8. * - `name` MUST follow the Key Expression specification, ie: @@ -1472,14 +1473,38 @@ ZENOHC_API void z_keyexpr_to_string(const struct z_keyexpr_t *ke, struct z_owned ZENOHC_API void z_keyexpr_unchecked(struct z_view_keyexpr_t *this_, const char *name); +/** + * Returns the read position indicator. + * Returns read position indicator on success or -1L if failure occurs. + */ +ZENOHC_API int64_t z_loaned_bytes_reader_tell(struct z_loaned_bytes_reader_t *this_); +/** + * Constructs a null-terminated string departing from a :c:type:`z_loaned_keyexpr_t`. + * The user is responsible of droping the returned string using `z_drop` + */ +ZENOHC_API +void z_loaned_keyexpr_to_string(const struct z_loaned_keyexpr_t *ke, + struct z_owned_str_t *s); +ZENOHC_API z_error_t z_loaned_mutex_try_lock(struct z_loaned_mutex_t *this_); +/** + * Create a default :c:type:`z_loaned_query_target_t`. + */ +ZENOHC_API enum z_loaned_query_target_t z_loaned_query_target_default(void); +/** + * The samples timestamp + * + * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. + */ +ZENOHC_API +bool z_loaned_sample_timestamp(const struct z_loaned_sample_t *sample, + struct z_timestamp_t *timestamp_out); ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); ZENOHC_API z_error_t z_mutex_init(struct z_owned_mutex_t *this_); -ZENOHC_API struct z_mutex_t *z_mutex_loan_mut(struct z_owned_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_lock(struct z_mutex_t *this_); +ZENOHC_API struct z_loaned_mutex_t *z_mutex_loan_mut(struct z_owned_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_lock(struct z_loaned_mutex_t *this_); ZENOHC_API void z_mutex_null(struct z_owned_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_try_lock(struct z_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_unlock(struct z_loaned_mutex_t *this_); /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. * Config value is always consumed upon function return. @@ -1502,7 +1527,7 @@ ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *this_); * ``0`` in case of success, ``1`` in case of failure. */ ZENOHC_API -z_error_t z_publisher_delete(const struct z_publisher_t *publisher, +z_error_t z_publisher_delete(const struct z_loaned_publisher_t *publisher, struct z_publisher_delete_options_t _options); /** * Constructs the default values for the delete operation via a publisher entity. @@ -1514,11 +1539,13 @@ ZENOHC_API void z_publisher_delete_options_default(struct z_publisher_delete_opt /** * Returns the key expression of the publisher */ -ZENOHC_API const struct z_keyexpr_t *z_publisher_keyexpr(const struct z_publisher_t *publisher); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_publisher_keyexpr(const struct z_loaned_publisher_t *publisher); /** - * Returns a :c:type:`z_publisher_t` loaned from `p`. + * Returns a :c:type:`z_loaned_publisher_t` loaned from `p`. */ -ZENOHC_API const struct z_publisher_t *z_publisher_loan(const struct z_owned_publisher_t *this_); +ZENOHC_API +const struct z_loaned_publisher_t *z_publisher_loan(const struct z_owned_publisher_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type */ @@ -1544,7 +1571,7 @@ ZENOHC_API void z_publisher_options_default(struct z_publisher_options_t *this_) * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -z_error_t z_publisher_put(const struct z_publisher_t *publisher, +z_error_t z_publisher_put(const struct z_loaned_publisher_t *publisher, struct z_owned_bytes_t *payload, struct z_publisher_put_options_t *options); /** @@ -1567,8 +1594,8 @@ ZENOHC_API void z_publisher_put_options_default(struct z_publisher_put_options_t * ``0`` in case of success, negative error values in case of failure. */ ZENOHC_API -z_error_t z_put(const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, +z_error_t z_put(const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_bytes_t *payload, struct z_put_options_t *options); /** @@ -1580,7 +1607,7 @@ ZENOHC_API void z_put_options_default(struct z_put_options_t *this_); * * Returns NULL if query does not contain an attachment. */ -ZENOHC_API const struct z_bytes_t *z_query_attachment(const struct z_query_t *query); +ZENOHC_API const struct z_loaned_bytes_t *z_query_attachment(const struct z_loaned_query_t *query); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1613,7 +1640,7 @@ bool z_query_check(const struct z_owned_query_t *query); * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). */ ZENOHC_API -void z_query_clone(const struct z_query_t *this_, +void z_query_clone(const struct z_loaned_query_t *this_, struct z_owned_query_t *dst); /** * Automatic query consolidation strategy selection. @@ -1652,18 +1679,18 @@ void z_query_drop(struct z_owned_query_t *this_); /** * Checks if query contains a payload value. */ -ZENOHC_API bool z_query_has_value(const struct z_query_t *query); +ZENOHC_API bool z_query_has_value(const struct z_loaned_query_t *query); /** * Get a query's key by aliasing it. */ -ZENOHC_API const struct z_keyexpr_t *z_query_keyexpr(const struct z_query_t *query); +ZENOHC_API const struct z_loaned_keyexpr_t *z_query_keyexpr(const struct z_loaned_query_t *query); /** * Aliases the query. * * This function may not be called with the null pointer, but can be called with the gravestone value. */ ZENOHC_API -const struct z_query_t *z_query_loan(const struct z_owned_query_t *this_); +const struct z_loaned_query_t *z_query_loan(const struct z_owned_query_t *this_); /** * The gravestone value of `z_owned_query_t`. */ @@ -1672,7 +1699,7 @@ ZENOHC_API void z_query_null(struct z_owned_query_t *this_); * Get a query's `value selector `_ by aliasing it. */ ZENOHC_API -void z_query_parameters(const struct z_query_t *query, +void z_query_parameters(const struct z_loaned_query_t *query, struct z_view_slice_t *parameters); /** * Send a reply to a query. @@ -1691,18 +1718,14 @@ void z_query_parameters(const struct z_query_t *query, * The payload and all owned options fields are consumed upon function return. */ ZENOHC_API -z_error_t z_query_reply(struct z_query_t query, - struct z_keyexpr_t key_expr, +z_error_t z_query_reply(struct z_loaned_query_t query, + struct z_loaned_keyexpr_t key_expr, struct z_owned_bytes_t *payload, struct z_query_reply_options_t *options); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ ZENOHC_API void z_query_reply_options_default(struct z_query_reply_options_t *this_); -/** - * Create a default :c:type:`z_query_target_t`. - */ -ZENOHC_API enum z_query_target_t z_query_target_default(void); /** * Gets a query's `payload value `_ by aliasing it. * @@ -1710,7 +1733,7 @@ ZENOHC_API enum z_query_target_t z_query_target_default(void); * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. */ ZENOHC_API -const struct z_value_t *z_query_value(const struct z_query_t *query); +const struct z_loaned_value_t *z_query_value(const struct z_loaned_query_t *query); /** * Returns ``true`` if `qable` is valid. */ @@ -1751,7 +1774,7 @@ ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); * Returns ``true`` if `reply` is valid. */ ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); -ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, const struct z_reply_t *reply); +ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, const struct z_loaned_reply_t *reply); /** * Frees `reply`, invalidating it for double-drop safety. */ @@ -1762,15 +1785,15 @@ ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); * Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). */ ZENOHC_API -const struct z_value_t *z_reply_err(const struct z_reply_t *reply); +const struct z_loaned_value_t *z_reply_err(const struct z_loaned_reply_t *reply); /** * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. * * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. */ ZENOHC_API -bool z_reply_is_ok(const struct z_reply_t *reply); -ZENOHC_API const struct z_reply_t *z_reply_loan(struct z_owned_reply_t *this_); +bool z_reply_is_ok(const struct z_loaned_reply_t *reply); +ZENOHC_API const struct z_loaned_reply_t *z_reply_loan(struct z_owned_reply_t *this_); /** * Returns an invalidated :c:type:`z_owned_reply_t`. * @@ -1787,7 +1810,7 @@ ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); * Returns null if reply does not contains a sample (i. e. if :c:func:`z_reply_is_ok` returns ``false``). */ ZENOHC_API -const struct z_sample_t *z_reply_ok(const struct z_reply_t *reply); +const struct z_loaned_sample_t *z_reply_ok(const struct z_loaned_reply_t *reply); /** * The qos with which the sample was received. * TODO: split to methods (priority, congestion_control, express) @@ -1795,7 +1818,8 @@ const struct z_sample_t *z_reply_ok(const struct z_reply_t *reply); * * Returns NULL if sample does not contain an attachement. */ -ZENOHC_API const struct z_bytes_t *z_sample_attachment(const struct z_sample_t *sample); +ZENOHC_API +const struct z_loaned_bytes_t *z_sample_attachment(const struct z_loaned_sample_t *sample); /** * Returns `true` if `sample` is valid. * @@ -1807,37 +1831,32 @@ bool z_sample_check(const struct zc_owned_sample_t *sample); /** * Clone a sample in the cheapest way available. */ -ZENOHC_API void z_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); -ZENOHC_API enum z_congestion_control_t z_sample_congestion_control(const struct z_sample_t *sample); +ZENOHC_API void z_sample_clone(const struct z_loaned_sample_t *src, struct zc_owned_sample_t *dst); +ZENOHC_API +enum z_congestion_control_t z_sample_congestion_control(const struct z_loaned_sample_t *sample); /** * The encoding of the payload. */ -ZENOHC_API const struct z_encoding_t *z_sample_encoding(const struct z_sample_t *sample); -ZENOHC_API bool z_sample_express(const struct z_sample_t *sample); +ZENOHC_API +const struct z_loaned_encoding_t *z_sample_encoding(const struct z_loaned_sample_t *sample); +ZENOHC_API bool z_sample_express(const struct z_loaned_sample_t *sample); /** * The Key Expression of the sample. * * `sample` is aliased by its return value. */ -ZENOHC_API const struct z_keyexpr_t *z_sample_keyexpr(const struct z_sample_t *sample); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_sample_keyexpr(const struct z_loaned_sample_t *sample); /** * The sample's kind (put or delete). */ -ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_loaned_sample_t *sample); /** * The sample's data, the return value aliases the sample. * */ -ZENOHC_API const struct z_bytes_t *z_sample_payload(const struct z_sample_t *sample); -ZENOHC_API enum z_priority_t z_sample_priority(const struct z_sample_t *sample); -/** - * The samples timestamp - * - * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. - */ -ZENOHC_API -bool z_sample_timestamp(const struct z_sample_t *sample, - struct z_timestamp_t *timestamp_out); +ZENOHC_API const struct z_loaned_bytes_t *z_sample_payload(const struct z_loaned_sample_t *sample); +ZENOHC_API enum z_priority_t z_sample_priority(const struct z_loaned_sample_t *sample); /** * Scout for routers and/or peers. * @@ -1856,24 +1875,24 @@ ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); ZENOHC_API void z_scouting_config_from(struct z_owned_scouting_config_t *this_, - const struct z_config_t *config); + const struct z_loaned_config_t *config); ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); /** * Returns ``true`` if `session` is valid. */ ZENOHC_API bool z_session_check(const struct z_owned_session_t *this_); /** - * Returns a :c:type:`z_session_t` loaned from `s`. + * Returns a :c:type:`z_loaned_session_t` loaned from `s`. * * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. * * # Safety - * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, + * The returned `z_loaned_session_t` aliases `z_owned_session_t`'s internal allocation, * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) * have been destroyed is UB (likely SEGFAULT) */ ZENOHC_API -const struct z_session_t *z_session_loan(const struct z_owned_session_t *this_); +const struct z_loaned_session_t *z_session_loan(const struct z_owned_session_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_session_t' type */ @@ -1881,8 +1900,8 @@ ZENOHC_API void z_session_null(struct z_owned_session_t *this_); ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); -ZENOHC_API void z_slice_clone(const struct z_slice_t *this_, struct z_owned_slice_t *dst); -ZENOHC_API const uint8_t *z_slice_data(const struct z_slice_t *this_); +ZENOHC_API void z_slice_clone(const struct z_loaned_slice_t *this_, struct z_owned_slice_t *dst); +ZENOHC_API const uint8_t *z_slice_data(const struct z_loaned_slice_t *this_); /** * Frees `this` and invalidates it for double-drop safety. */ @@ -1899,8 +1918,8 @@ ZENOHC_API void z_slice_empty(struct z_owned_slice_t *this_); ZENOHC_API void z_slice_from_str(struct z_owned_slice_t *this_, const char *str); -ZENOHC_API size_t z_slice_len(const struct z_slice_t *this_); -ZENOHC_API const struct z_slice_t *z_slice_loan(const struct z_owned_slice_t *this_); +ZENOHC_API size_t z_slice_len(const struct z_loaned_slice_t *this_); +ZENOHC_API const struct z_loaned_slice_t *z_slice_loan(const struct z_owned_slice_t *this_); /** * Returns `true` if the map is not in its gravestone state */ @@ -1917,8 +1936,8 @@ ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); * Will return NULL if the key is not present in the map. */ ZENOHC_API -const struct z_slice_t *z_slice_map_get(const struct z_slice_map_t *this_, - const struct z_slice_t *key); +const struct z_loaned_slice_t *z_slice_map_get(const struct z_loaned_slice_map_t *this_, + const struct z_loaned_slice_t *key); /** * Associates `value` to `key` in the map, aliasing them. * @@ -1927,32 +1946,33 @@ const struct z_slice_t *z_slice_map_get(const struct z_slice_map_t *this_, * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API -z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t *this_, - const struct z_slice_t *key, - const struct z_slice_t *value); +z_error_t z_slice_map_insert_by_alias(struct z_loaned_slice_map_t *this_, + const struct z_loaned_slice_t *key, + const struct z_loaned_slice_t *value); /** * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. * * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API -uint8_t z_slice_map_insert_by_copy(struct z_slice_map_t *this_, - const struct z_slice_t *key, - const struct z_slice_t *value); +uint8_t z_slice_map_insert_by_copy(struct z_loaned_slice_map_t *this_, + const struct z_loaned_slice_t *key, + const struct z_loaned_slice_t *value); /** * Returns true if the map is empty, false otherwise. */ -ZENOHC_API bool z_slice_map_is_empty(const struct z_slice_map_t *this_); +ZENOHC_API bool z_slice_map_is_empty(const struct z_loaned_slice_map_t *this_); ZENOHC_API -void z_slice_map_iterate(const struct z_slice_map_t *this_, +void z_slice_map_iterate(const struct z_loaned_slice_map_t *this_, z_slice_map_iter_body_t body, void *context); /** * Returns number of key-value pairs in the map. */ -ZENOHC_API size_t z_slice_map_len(const struct z_slice_map_t *this_); -ZENOHC_API const struct z_slice_map_t *z_slice_map_loan(const struct z_owned_slice_map_t *this_); -ZENOHC_API struct z_slice_map_t *z_slice_map_loan_mut(struct z_owned_slice_map_t *this_); +ZENOHC_API size_t z_slice_map_len(const struct z_loaned_slice_map_t *this_); +ZENOHC_API +const struct z_loaned_slice_map_t *z_slice_map_loan(const struct z_owned_slice_map_t *this_); +ZENOHC_API struct z_loaned_slice_map_t *z_slice_map_loan_mut(struct z_owned_slice_map_t *this_); /** * Constructs a new empty map. */ @@ -1982,7 +2002,7 @@ ZENOHC_API const struct z_str_array_t *z_str_array_loan(const struct z_owned_str * Returns ``true`` if `s` is a valid string */ ZENOHC_API bool z_str_check(const struct z_owned_str_t *this_); -ZENOHC_API void z_str_clone(const struct z_str_t *this_, struct z_owned_str_t *dst); +ZENOHC_API void z_str_clone(const struct z_loaned_str_t *this_, struct z_owned_str_t *dst); /** * Frees `z_owned_str_t`, invalidating it for double-drop safety. */ @@ -1995,9 +2015,9 @@ ZENOHC_API void z_str_empty(struct z_owned_str_t *this_); */ ZENOHC_API void z_str_from_substring(struct z_owned_str_t *this_, const char *str, size_t len); /** - * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. + * Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_owned_str_t`. */ -ZENOHC_API const struct z_str_t *z_str_loan(const struct z_owned_str_t *this_); +ZENOHC_API const struct z_loaned_str_t *z_str_loan(const struct z_owned_str_t *this_); /** * Returns undefined `z_owned_str_t` */ @@ -2017,11 +2037,13 @@ ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber /** * Returns the key expression of the subscriber. */ -ZENOHC_API const struct z_keyexpr_t *z_subscriber_keyexpr(const struct z_subscriber_t *subscriber); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_subscriber_keyexpr(const struct z_loaned_subscriber_t *subscriber); /** - * Returns a :c:type:`z_subscriber_t` loaned from `this`. + * Returns a :c:type:`z_loaned_subscriber_t` loaned from `this`. */ -ZENOHC_API const struct z_subscriber_t *z_subscriber_loan(const struct z_owned_subscriber_t *this_); +ZENOHC_API +const struct z_loaned_subscriber_t *z_subscriber_loan(const struct z_owned_subscriber_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type */ @@ -2057,7 +2079,7 @@ ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp * The keyxpr is consumed. */ ZENOHC_API -z_error_t z_undeclare_keyexpr(const struct z_session_t *session, +z_error_t z_undeclare_keyexpr(const struct z_loaned_session_t *session, struct z_owned_keyexpr_t *kexpr); /** * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. @@ -2077,12 +2099,12 @@ ZENOHC_API z_error_t z_undeclare_queryable(struct z_owned_queryable_t *qable); ZENOHC_API z_error_t z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); /** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * Constructs a :c:type:`z_loaned_keyexpr_t` departing from a string. * It is a loaned key expression that aliases `name`. */ ZENOHC_API z_error_t z_view_keyexpr(struct z_view_keyexpr_t *this_, const char *name); /** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. * 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). */ @@ -2094,14 +2116,14 @@ z_error_t z_view_keyexpr_autocanonize(struct z_view_keyexpr_t *this_, */ ZENOHC_API bool z_view_keyexpr_check(const struct z_view_keyexpr_t *keyexpr); /** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. */ ZENOHC_API z_error_t z_view_keyexpr_from_slice(struct z_view_keyexpr_t *this_, const char *name, size_t len); /** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. * 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). */ @@ -2110,7 +2132,7 @@ z_error_t z_view_keyexpr_from_slice_autocanonize(struct z_view_keyexpr_t *this_, char *name, size_t *len); /** - * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: * - `name` MUST be valid UTF8. * - `name` MUST follow the Key Expression specification, ie: * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -2124,9 +2146,10 @@ void z_view_keyexpr_from_slice_unchecked(struct z_view_keyexpr_t *this_, const char *start, size_t len); /** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + * Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. */ -ZENOHC_API const struct z_keyexpr_t *z_view_keyexpr_loan(const struct z_view_keyexpr_t *key_expr); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_view_keyexpr_loan(const struct z_view_keyexpr_t *key_expr); ZENOHC_API void z_view_keyexpr_null(struct z_view_keyexpr_t *this_); /** * Returns ``true`` if `this` is initialized. @@ -2142,19 +2165,19 @@ ZENOHC_API void z_view_slice_empty(struct z_view_slice_t *this_); * Calling this with `str == NULL` is equivalent to `z_view_slice_null`. */ ZENOHC_API void z_view_slice_from_str(struct z_view_slice_t *this_, const char *str); -ZENOHC_API const struct z_slice_t *z_view_slice_loan(const struct z_view_slice_t *this_); +ZENOHC_API const struct z_loaned_slice_t *z_view_slice_loan(const struct z_view_slice_t *this_); ZENOHC_API void z_view_slice_null(struct z_view_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. */ ZENOHC_API void z_view_slice_wrap(struct z_view_slice_t *this_, const uint8_t *start, size_t len); -ZENOHC_API const char *z_view_str_data(const struct z_str_t *this_); +ZENOHC_API const char *z_view_str_data(const struct z_loaned_str_t *this_); ZENOHC_API void z_view_str_empty(struct z_view_str_t *this_); -ZENOHC_API size_t z_view_str_len(const struct z_str_t *this_); +ZENOHC_API size_t z_view_str_len(const struct z_loaned_str_t *this_); /** - * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_view_str_t`. + * Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_view_str_t`. */ -ZENOHC_API const struct z_str_t *z_view_str_loan(const struct z_view_str_t *this_); +ZENOHC_API const struct z_loaned_str_t *z_view_str_loan(const struct z_view_str_t *this_); /** * Returns undefined `z_owned_str_t` */ @@ -2196,7 +2219,7 @@ z_error_t zc_config_from_str(struct z_owned_config_t *this_, * Use `z_drop` to safely deallocate this string */ ZENOHC_API -z_error_t zc_config_get(const struct z_config_t *config, +z_error_t zc_config_get(const struct z_loaned_config_t *config, const char *key, struct z_owned_str_t *value_string); /** @@ -2205,14 +2228,14 @@ z_error_t zc_config_get(const struct z_config_t *config, * Returns 0 if successful, a negative value otherwise. */ ZENOHC_API -z_error_t zc_config_insert_json(struct z_config_t *config, +z_error_t zc_config_insert_json(struct z_loaned_config_t *config, const char *key, const char *value); /** * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. */ ZENOHC_API -z_error_t zc_config_to_string(const struct z_config_t *config, +z_error_t zc_config_to_string(const struct z_loaned_config_t *config, struct z_owned_str_t *config_string); /** * Initialises the zenoh runtime logger. @@ -2227,8 +2250,8 @@ void zc_liveliness_declaration_options_default(struct zc_liveliness_declaration_ * Declares a subscriber on liveliness tokens that intersect `key`. * * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t key_expr: The key expression to subscribe. + * z_loaned_session_t session: The zenoh session. + * z_loaned_keyexpr_t key_expr: The key expression to subscribe. * z_owned_closure_sample_t callback: The callback function that will be called each time a * liveliness token status changed. * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. @@ -2241,8 +2264,8 @@ void zc_liveliness_declaration_options_default(struct zc_liveliness_declaration_ */ ZENOHC_API z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct zc_liveliness_declare_subscriber_options_t *_options); /** @@ -2255,8 +2278,8 @@ z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, */ ZENOHC_API z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct zc_liveliness_declaration_options_t *_options); /** * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. @@ -2266,8 +2289,8 @@ z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. */ ZENOHC_API -z_error_t zc_liveliness_get(const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, +z_error_t zc_liveliness_get(const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_reply_t *callback, struct zc_liveliness_get_options_t *options); /** @@ -2349,7 +2372,7 @@ ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); * * Calling this function using a dropped sample is undefined behaviour. */ -ZENOHC_API const struct z_sample_t *zc_sample_loan(const struct zc_owned_sample_t *sample); +ZENOHC_API const struct z_loaned_sample_t *zc_sample_loan(const struct zc_owned_sample_t *sample); ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. @@ -2378,15 +2401,15 @@ ZENOHC_API enum zcu_locality_t zcu_locality_default(void); */ ZENOHC_API z_error_t zcu_publisher_matching_listener_callback(struct zcu_owned_matching_listener_t *this_, - const struct z_publisher_t *publisher, + const struct z_loaned_publisher_t *publisher, struct zcu_owned_closure_matching_status_t *callback); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); /** * Declares a Publication Cache. * * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t key_expr: The key expression to publish. + * z_loaned_session_t session: The zenoh session. + * z_loaned_keyexpr_t key_expr: The key expression to publish. * ze_publication_cache_options_t options: Additional options for the publication_cache. * * Returns: @@ -2409,15 +2432,15 @@ ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); */ ZENOHC_API z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct ze_publication_cache_options_t *options); /** * Declares a Querying Subscriber for a given key expression. * * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to subscribe. + * z_loaned_session_t session: The zenoh session. + * z_loaned_keyexpr_t keyexpr: The key expression to subscribe. * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. * @@ -2447,8 +2470,8 @@ z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this */ ZENOHC_API z_error_t ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct ze_querying_subscriber_options_t *options); /** @@ -2472,14 +2495,14 @@ ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subs * The queried samples will be merged with the received publications and made available in the subscriber callback. */ ZENOHC_API -z_error_t ze_querying_subscriber_get(const struct ze_querying_subscriber_t *sub, - const struct z_keyexpr_t *selector, +z_error_t ze_querying_subscriber_get(const struct ze_loaned_querying_subscriber_t *sub, + const struct z_loaned_keyexpr_t *selector, const struct z_get_options_t *options); /** * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. */ ZENOHC_API -const struct ze_querying_subscriber_t *ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); +const struct ze_loaned_querying_subscriber_t *ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); /** * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type */ diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index a7cc575ab..f9f91304e 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -36,12 +36,12 @@ typedef struct ALIGN(8) z_owned_session_t { uint8_t _0[8]; } z_owned_session_t; -typedef struct ALIGN(8) z_query_t { +typedef struct ALIGN(8) z_loaned_query_t { uint8_t _0[16]; -} z_query_t; -typedef struct ALIGN(8) z_session_t { +} z_loaned_query_t; +typedef struct ALIGN(8) z_loaned_session_t { uint8_t _0[40]; -} z_session_t; +} z_loaned_session_t; /** * An owned zenoh queryable. * diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index fbd60560b..7b6bbe214 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -19,7 +19,7 @@ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ z_owned_reply_t : z_reply_loan, \ z_owned_mutex_t : z_mutex_loan, \ - z_condvar_t : z_condvar_loan, \ + z_loaned_condvar_t : z_condvar_loan, \ z_owned_bytes_reader_t : z_bytes_reader_loan \ )(&x) @@ -137,39 +137,39 @@ template struct zenoh_loan_type { typedef T type; }; template inline typename zenoh_loan_type::type z_loan(const T&); -template<> struct zenoh_loan_type{ typedef z_session_t type; }; -template<> struct zenoh_loan_type{ typedef z_keyexpr_t type; }; -template<> struct zenoh_loan_type{ typedef z_config_t type; }; -template<> struct zenoh_loan_type{ typedef z_publisher_t type; }; -template<> struct zenoh_loan_type{ typedef z_subscriber_t type; }; -template<> struct zenoh_loan_type{ typedef z_query_t type; }; -template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_session_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_keyexpr_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_config_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_publisher_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_subscriber_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_query_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; -template<> struct zenoh_loan_type{ typedef z_bytes_t type; }; -template<> struct zenoh_loan_type{ typedef z_bytes_reader_t type; }; -template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; -template<> struct zenoh_loan_type{ typedef z_slice_t type; }; -template<> struct zenoh_loan_type{ typedef z_slice_map_t type; }; -template<> struct zenoh_loan_type{ typedef z_mutex_t type; }; -template<> struct zenoh_loan_type{ typedef z_condvar_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_bytes_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_bytes_reader_t type; }; +template<> struct zenoh_loan_type{ typedef ze_loaned_querying_subscriber_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_slice_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_slice_map_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_mutex_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_condvar_t type; }; -template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } -template<> inline z_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keyexpr_loan(&x); } -template<> inline z_config_t z_loan(const z_owned_config_t& x) { return z_config_loan(&x); } -template<> inline z_publisher_t z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } -template<> inline z_subscriber_t z_loan(const z_owned_subscriber_t& x) { return z_subscriber_loan(&x); } -template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_encoding_loan(&x); } +template<> inline z_loaned_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } +template<> inline z_loaned_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keyexpr_loan(&x); } +template<> inline z_loaned_config_t z_loan(const z_owned_config_t& x) { return z_config_loan(&x); } +template<> inline z_loaned_publisher_t z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } +template<> inline z_loaned_subscriber_t z_loan(const z_owned_subscriber_t& x) { return z_subscriber_loan(&x); } +template<> inline z_loaned_encoding_t z_loan(const z_owned_encoding_t& x) { return z_encoding_loan(&x); } template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } -template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } +template<> inline z_loaned_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } -template<> inline z_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } -template<> inline z_bytes_reader_t z_loan(const z_owned_bytes_reader_t& x) { return z_bytes_reader_loan(&x); } -template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } -template<> inline z_slice_t z_loan(const z_owned_slice_t& x) { return z_slice_loan(&x); } -template<> inline z_slice_map_t z_loan(const z_owned_slice_map_t& x) { return z_slice_map_loan(&x); } -template<> inline z_mutex_t z_loan(const z_owned_mutex_t& x) { return z_mutex_loan(&x); } -template<> inline z_condvar_t z_loan(const z_owned_condvar_t& x) { return z_condvar_loan(&x); } +template<> inline z_loaned_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } +template<> inline z_loaned_bytes_reader_t z_loan(const z_owned_bytes_reader_t& x) { return z_bytes_reader_loan(&x); } +template<> inline ze_loaned_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } +template<> inline z_loaned_slice_t z_loan(const z_owned_slice_t& x) { return z_slice_loan(&x); } +template<> inline z_loaned_slice_map_t z_loan(const z_owned_slice_map_t& x) { return z_slice_map_loan(&x); } +template<> inline z_loaned_mutex_t z_loan(const z_owned_mutex_t& x) { return z_mutex_loan(&x); } +template<> inline z_loaned_condvar_t z_loan(const z_owned_condvar_t& x) { return z_condvar_loan(&x); } template struct zenoh_drop_type { typedef T type; }; template inline typename zenoh_drop_type::type z_drop(T*); @@ -288,9 +288,9 @@ inline bool z_check(const z_owned_mutex_t& v) { return z_mutex_check(&v); } inline bool z_check(const z_owned_condvar_t& v) { return z_condvar_check(&v); } inline bool z_check(const z_owned_task_t& v) { return z_task_check(&v); } -inline void z_call(const struct z_owned_closure_sample_t &closure, const struct z_sample_t *sample) +inline void z_call(const struct z_owned_closure_sample_t &closure, const struct z_loaned_sample_t *sample) { z_closure_sample_call(&closure, sample); } -inline void z_call(const struct z_owned_closure_query_t &closure, const struct z_query_t *query) +inline void z_call(const struct z_owned_closure_query_t &closure, const struct z_loaned_query_t *query) { z_closure_query_call(&closure, query); } inline void z_call(const struct z_owned_closure_reply_t &closure, struct z_owned_reply_t *sample) { z_closure_reply_call(&closure, sample); } diff --git a/splitguide.yaml b/splitguide.yaml index 5469f25de..6614c0356 100644 --- a/splitguide.yaml +++ b/splitguide.yaml @@ -7,7 +7,7 @@ zenoh_concrete.h: - :includes - :defines - z_owned_session_t! - - z_session_t! + - z_loaned_session_t! - z_owned_subscriber_t! - - z_query_t! + - z_loaned_query_t! - z_owned_queryable_t! diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index 1cd1f063d..c4bf36a2a 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -1,6 +1,6 @@ use crate::{ - z_closure_query_drop, z_owned_closure_query_t, z_owned_query_t, z_query_clone, z_query_null, - z_query_t, + z_closure_query_drop, z_loaned_query_t, z_owned_closure_query_t, z_owned_query_t, + z_query_clone, z_query_null, }; use libc::c_void; use std::{ @@ -50,7 +50,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |query: &z_query_t| { + From::from(move |query: &z_loaned_query_t| { let mut this = MaybeUninit::::uninit(); z_query_clone(query, &mut this as *mut MaybeUninit); let this = this.assume_init(); @@ -63,7 +63,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |query: &z_query_t| { + From::from(move |query: &z_loaned_query_t| { let mut this = MaybeUninit::::uninit(); z_query_clone(query, &mut this as *mut MaybeUninit); let this = this.assume_init(); diff --git a/src/closures/query_closure.rs b/src/closures/query_closure.rs index 0512e28c8..98f774cd8 100644 --- a/src/closures/query_closure.rs +++ b/src/closures/query_closure.rs @@ -1,10 +1,10 @@ -use crate::{z_owned_query_t, z_query_t}; +use crate::{z_loaned_query_t, z_owned_query_t}; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(z_loaned_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_query_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_query_t { @@ -45,7 +45,10 @@ pub extern "C" fn z_closure_query_null() -> z_owned_closure_query_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: &z_query_t) { +pub extern "C" fn z_closure_query_call( + closure: &z_owned_closure_query_t, + query: &z_loaned_query_t, +) { match closure.call { Some(call) => call(query, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -57,10 +60,13 @@ pub extern "C" fn z_closure_query_drop(closure: &mut z_owned_closure_query_t) { let mut empty_closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_query_t { +impl From for z_owned_closure_query_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(query: *const z_query_t, this: *mut c_void) { + extern "C" fn call( + query: *const z_loaned_query_t, + this: *mut c_void, + ) { let this = unsafe { &*(this as *const F) }; unsafe { this(query.as_ref().unwrap()) } } @@ -79,7 +85,7 @@ impl From for z_owned_closure_query_t { /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(const struct z_loaned_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index c070c4bd8..d41c6580a 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -1,4 +1,4 @@ -use crate::z_reply_t; +use crate::z_loaned_reply_t; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_reply_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } @@ -46,7 +46,10 @@ pub extern "C" fn z_closure_reply_null() -> z_owned_closure_reply_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_reply_call(closure: &z_owned_closure_reply_t, reply: &z_reply_t) { +pub extern "C" fn z_closure_reply_call( + closure: &z_owned_closure_reply_t, + reply: &z_loaned_reply_t, +) { match closure.call { Some(call) => call(reply, closure.context), None => { @@ -60,10 +63,13 @@ pub extern "C" fn z_closure_reply_drop(closure: &mut z_owned_closure_reply_t) { let mut empty_closure = z_owned_closure_reply_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_reply_t { +impl From for z_owned_closure_reply_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(response: *const z_reply_t, this: *mut c_void) { + extern "C" fn call( + response: *const z_loaned_reply_t, + this: *mut c_void, + ) { let this = unsafe { &*(this as *const F) }; unsafe { this(response.as_ref().unwrap()) } } diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 4ef56b760..4b0d52123 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -1,6 +1,6 @@ use crate::{ - z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t, z_reply_clone, z_reply_null, - z_reply_t, + z_closure_reply_drop, z_loaned_reply_t, z_owned_closure_reply_t, z_owned_reply_t, + z_reply_clone, z_reply_null, }; use libc::c_void; use std::{ @@ -49,7 +49,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |reply: &z_reply_t| { + From::from(move |reply: &z_loaned_reply_t| { let mut this = MaybeUninit::::uninit(); z_reply_clone(&mut this as *mut MaybeUninit, reply); let this = this.assume_init(); @@ -62,7 +62,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |reply: &z_reply_t| { + From::from(move |reply: &z_loaned_reply_t| { let mut this = MaybeUninit::::uninit(); z_reply_clone(&mut this as *mut MaybeUninit, reply); let this = this.assume_init(); diff --git a/src/closures/sample_closure.rs b/src/closures/sample_closure.rs index 043b59fb8..e706b0b7a 100644 --- a/src/closures/sample_closure.rs +++ b/src/closures/sample_closure.rs @@ -1,10 +1,10 @@ -use crate::z_sample_t; +use crate::z_loaned_sample_t; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(struct z_loaned_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_sample_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_sample_t { @@ -47,7 +47,10 @@ pub extern "C" fn z_closure_sample_null() -> z_owned_closure_sample_t { /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: &z_sample_t) { +pub extern "C" fn z_closure_sample_call( + closure: &z_owned_closure_sample_t, + sample: &z_loaned_sample_t, +) { match closure.call { Some(call) => call(sample, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -60,10 +63,13 @@ pub extern "C" fn z_closure_sample_drop(closure: &mut z_owned_closure_sample_t) let mut empty_closure = z_owned_closure_sample_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_sample_t { +impl From for z_owned_closure_sample_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: *const z_sample_t, this: *mut c_void) { + extern "C" fn call( + sample: *const z_loaned_sample_t, + this: *mut c_void, + ) { let this = unsafe { &*(this as *const F) }; unsafe { this(sample.as_ref().unwrap()) } } diff --git a/src/collections.rs b/src/collections.rs index 0add96fff..395ee57e3 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -26,13 +26,13 @@ use crate::transmute::{ TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; +pub use crate::opaque_types::z_loaned_slice_t; pub use crate::opaque_types::z_owned_slice_t; -pub use crate::opaque_types::z_slice_t; pub use crate::opaque_types::z_view_slice_t; decl_transmute_owned!(Option>, z_owned_slice_t); decl_transmute_owned!(Option<&'static [u8]>, z_view_slice_t); -decl_transmute_handle!(&'static [u8], z_slice_t); +decl_transmute_handle!(&'static [u8], z_loaned_slice_t); /// Returns an empty `z_view_slice_t` #[no_mangle] @@ -81,7 +81,7 @@ pub unsafe extern "C" fn z_view_slice_wrap( } #[no_mangle] -pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_slice_t { +pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_loaned_slice_t { match this.transmute_ref() { Some(s) => s.transmute_handle(), None => null(), @@ -143,15 +143,15 @@ pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { } #[no_mangle] -pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { +pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_loaned_slice_t { match this.transmute_ref() { - Some(s) => (&s.as_ref()) as *const &[u8] as *const z_slice_t, + Some(s) => (&s.as_ref()) as *const &[u8] as *const z_loaned_slice_t, None => null(), } } #[no_mangle] -pub extern "C" fn z_slice_clone(this: &z_slice_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_slice_clone(this: &z_loaned_slice_t, dst: *mut MaybeUninit) { let slice = this.transmute_ref().to_vec().into_boxed_slice(); Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); } @@ -169,22 +169,22 @@ pub extern "C" fn z_view_slice_check(this: &z_view_slice_t) -> bool { } #[no_mangle] -pub extern "C" fn z_slice_len(this: &z_slice_t) -> usize { +pub extern "C" fn z_slice_len(this: &z_loaned_slice_t) -> usize { this.transmute_ref().len() } #[no_mangle] -pub extern "C" fn z_slice_data(this: &z_slice_t) -> *const u8 { +pub extern "C" fn z_slice_data(this: &z_loaned_slice_t) -> *const u8 { this.transmute_ref().as_ptr() } +pub use crate::opaque_types::z_loaned_str_t; pub use crate::opaque_types::z_owned_str_t; -pub use crate::opaque_types::z_str_t; pub use crate::opaque_types::z_view_str_t; decl_transmute_owned!(custom_inplace_init Option>, z_owned_str_t); decl_transmute_owned!(custom_inplace_init Option<&'static [u8]>, z_view_str_t); -decl_transmute_handle!(&'static [u8], z_str_t); +decl_transmute_handle!(&'static [u8], z_loaned_str_t); /// Frees `z_owned_str_t`, invalidating it for double-drop safety. #[no_mangle] @@ -223,15 +223,15 @@ pub unsafe extern "C" fn z_view_str_empty(this: *mut MaybeUninit) z_view_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) } -/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. +/// Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_owned_str_t`. #[no_mangle] -pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> *const z_str_t { +pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> *const z_loaned_str_t { z_slice_loan(this.transmute_ref().transmute_ref()) as _ } -/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_view_str_t`. +/// Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_view_str_t`. #[no_mangle] -pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_str_t { +pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_loaned_str_t { z_view_slice_loan(this.transmute_ref().transmute_ref()) as _ } @@ -276,30 +276,30 @@ pub unsafe extern "C" fn z_view_str_wrap( } #[no_mangle] -pub extern "C" fn z_view_str_len(this: &z_str_t) -> usize { +pub extern "C" fn z_view_str_len(this: &z_loaned_str_t) -> usize { z_slice_len(this.transmute_ref().transmute_handle()) - 1 } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_view_str_data(this: &z_str_t) -> *const libc::c_char { +pub extern "C" fn z_view_str_data(this: &z_loaned_str_t) -> *const libc::c_char { z_slice_data(this.transmute_ref().transmute_handle()) as _ } #[no_mangle] -pub extern "C" fn z_str_clone(this: &z_str_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_str_clone(this: &z_loaned_str_t, dst: *mut MaybeUninit) { let slice = this.transmute_ref().to_vec().into_boxed_slice(); Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); } +pub use crate::opaque_types::z_loaned_slice_map_t; pub use crate::opaque_types::z_owned_slice_map_t; -pub use crate::opaque_types::z_slice_map_t; pub type ZHashMap = HashMap, Cow<'static, [u8]>>; -pub use crate::opaque_types::z_config_t; +pub use crate::opaque_types::z_loaned_config_t; decl_transmute_handle!( HashMap, Cow<'static, [u8]>>, - z_slice_map_t + z_loaned_slice_map_t ); pub use crate::opaque_types::z_owned_config_t; @@ -340,14 +340,16 @@ pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { } #[no_mangle] -pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_slice_map_t { +pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_loaned_slice_map_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } #[no_mangle] -pub extern "C" fn z_slice_map_loan_mut(this: &mut z_owned_slice_map_t) -> &mut z_slice_map_t { +pub extern "C" fn z_slice_map_loan_mut( + this: &mut z_owned_slice_map_t, +) -> &mut z_loaned_slice_map_t { let this = this.transmute_mut(); let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() @@ -355,13 +357,13 @@ pub extern "C" fn z_slice_map_loan_mut(this: &mut z_owned_slice_map_t) -> &mut z /// Returns number of key-value pairs in the map. #[no_mangle] -pub extern "C" fn z_slice_map_len(this: &z_slice_map_t) -> usize { +pub extern "C" fn z_slice_map_len(this: &z_loaned_slice_map_t) -> usize { this.transmute_ref().len() } /// Returns true if the map is empty, false otherwise. #[no_mangle] -pub extern "C" fn z_slice_map_is_empty(this: &z_slice_map_t) -> bool { +pub extern "C" fn z_slice_map_is_empty(this: &z_loaned_slice_map_t) -> bool { z_slice_map_len(this) == 0 } @@ -373,11 +375,11 @@ pub extern "C" fn z_slice_map_is_empty(this: &z_slice_map_t) -> bool { /// Returning `true` is treated as `continue`. #[allow(non_camel_case_types)] pub type z_slice_map_iter_body_t = - extern "C" fn(key: &z_slice_t, value: &z_slice_t, context: *mut c_void) -> bool; + extern "C" fn(key: &z_loaned_slice_t, value: &z_loaned_slice_t, context: *mut c_void) -> bool; #[no_mangle] pub extern "C" fn z_slice_map_iterate( - this: &z_slice_map_t, + this: &z_loaned_slice_map_t, body: z_slice_map_iter_body_t, context: *mut c_void, ) { @@ -399,7 +401,10 @@ pub extern "C" fn z_slice_map_iterate( /// /// Will return NULL if the key is not present in the map. #[no_mangle] -pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *const z_slice_t { +pub extern "C" fn z_slice_map_get( + this: &z_loaned_slice_map_t, + key: &z_loaned_slice_t, +) -> *const z_loaned_slice_t { let m = this.transmute_ref(); let key = *key.transmute_ref(); let k = Cow::Borrowed(key); @@ -413,9 +418,9 @@ pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *con /// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_copy( - this: &mut z_slice_map_t, - key: &z_slice_t, - value: &z_slice_t, + this: &mut z_loaned_slice_map_t, + key: &z_loaned_slice_t, + value: &z_loaned_slice_t, ) -> u8 { let this = this.transmute_mut(); let key = *key.transmute_ref(); @@ -433,9 +438,9 @@ pub extern "C" fn z_slice_map_insert_by_copy( /// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_alias( - this: &mut z_slice_map_t, - key: &z_slice_t, - value: &z_slice_t, + this: &mut z_loaned_slice_map_t, + key: &z_loaned_slice_t, + value: &z_loaned_slice_t, ) -> errors::z_error_t { let this = this.transmute_mut(); let key = key.transmute_ref(); diff --git a/src/commons.rs b/src/commons.rs index 86f5bad69..efc9fc9f0 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -24,9 +24,9 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_bytes_t; use crate::z_id_t; -use crate::z_keyexpr_t; +use crate::z_loaned_bytes_t; +use crate::z_loaned_keyexpr_t; use libc::{c_char, c_ulong}; use unwrap_infallible::UnwrapInfallible; use zenoh::encoding::Encoding; @@ -87,34 +87,34 @@ pub extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t { /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. -use crate::opaque_types::z_sample_t; -decl_transmute_handle!(Sample, z_sample_t); +use crate::opaque_types::z_loaned_sample_t; +decl_transmute_handle!(Sample, z_loaned_sample_t); /// The Key Expression of the sample. /// /// `sample` is aliased by its return value. #[no_mangle] -pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> &z_keyexpr_t { +pub extern "C" fn z_sample_keyexpr(sample: &z_loaned_sample_t) -> &z_loaned_keyexpr_t { let sample = sample.transmute_ref(); sample.key_expr().transmute_handle() } /// The encoding of the payload. #[no_mangle] -pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> &z_encoding_t { +pub extern "C" fn z_sample_encoding(sample: &z_loaned_sample_t) -> &z_loaned_encoding_t { let sample = sample.transmute_ref(); sample.encoding().transmute_handle() } /// The sample's data, the return value aliases the sample. /// #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> &z_bytes_t { +pub extern "C" fn z_sample_payload(sample: &z_loaned_sample_t) -> &z_loaned_bytes_t { let sample = sample.transmute_ref(); sample.payload().transmute_handle() } /// The sample's kind (put or delete). #[no_mangle] -pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { +pub extern "C" fn z_sample_kind(sample: &z_loaned_sample_t) -> z_sample_kind_t { let sample = sample.transmute_ref(); sample.kind().into() } @@ -122,8 +122,8 @@ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { /// /// Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. #[no_mangle] -pub extern "C" fn z_sample_timestamp( - sample: &z_sample_t, +pub extern "C" fn z_loaned_sample_timestamp( + sample: &z_loaned_sample_t, timestamp_out: &mut z_timestamp_t, ) -> bool { let sample = sample.transmute_ref(); @@ -141,7 +141,7 @@ pub extern "C" fn z_sample_timestamp( /// /// Returns NULL if sample does not contain an attachement. #[no_mangle] -pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> *const z_bytes_t { +pub extern "C" fn z_sample_attachment(sample: &z_loaned_sample_t) -> *const z_loaned_bytes_t { let sample = sample.transmute_ref(); match sample.attachment() { Some(attachment) => attachment.transmute_handle() as *const _, @@ -154,7 +154,10 @@ decl_transmute_owned!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] -pub extern "C" fn z_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_sample_clone( + src: &z_loaned_sample_t, + dst: *mut MaybeUninit, +) { let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); @@ -162,19 +165,21 @@ pub extern "C" fn z_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit z_priority_t { +pub extern "C" fn z_sample_priority(sample: &z_loaned_sample_t) -> z_priority_t { let sample = sample.transmute_ref(); sample.priority().into() } #[no_mangle] -pub extern "C" fn z_sample_express(sample: &z_sample_t) -> bool { +pub extern "C" fn z_sample_express(sample: &z_loaned_sample_t) -> bool { let sample = sample.transmute_ref(); sample.express() } #[no_mangle] -pub extern "C" fn z_sample_congestion_control(sample: &z_sample_t) -> z_congestion_control_t { +pub extern "C" fn z_sample_congestion_control( + sample: &z_loaned_sample_t, +) -> z_congestion_control_t { let sample = sample.transmute_ref(); sample.congestion_control().into() } @@ -193,7 +198,7 @@ pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> &z_sample_t { +pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> &z_loaned_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } @@ -208,8 +213,8 @@ pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { Inplace::empty(sample.transmute_uninit_ptr()); } -pub use crate::opaque_types::z_encoding_t; -decl_transmute_handle!(Encoding, z_encoding_t); +pub use crate::opaque_types::z_loaned_encoding_t; +decl_transmute_handle!(Encoding, z_loaned_encoding_t); /// An owned payload encoding. /// @@ -227,7 +232,7 @@ pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit Inplace::empty(encoding.transmute_uninit_ptr()); } -/// Constructs a specific :c:type:`z_encoding_t`. +/// Constructs a specific :c:type:`z_loaned_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_from_str( @@ -246,10 +251,10 @@ pub unsafe extern "C" fn z_encoding_from_str( } } -/// Constructs a default :c:type:`z_encoding_t`. +/// Constructs a default :c:type:`z_loaned_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_default() -> &'static z_encoding_t { +pub extern "C" fn z_encoding_default() -> &'static z_loaned_encoding_t { Encoding::ZENOH_BYTES.transmute_handle() } @@ -267,17 +272,17 @@ pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> boo *encoding.transmute_ref() != Encoding::default() } -/// Returns a :c:type:`z_encoding_t` loaned from `encoding`. +/// Returns a :c:type:`z_loaned_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> &z_encoding_t { +pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> &z_loaned_encoding_t { encoding.transmute_ref().transmute_handle() } pub use crate::opaque_types::z_owned_value_t; decl_transmute_owned!(Value, z_owned_value_t); -pub use crate::opaque_types::z_value_t; -decl_transmute_handle!(Value, z_value_t); +pub use crate::opaque_types::z_loaned_value_t; +decl_transmute_handle!(Value, z_loaned_value_t); #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -350,37 +355,37 @@ pub extern "C" fn zcu_reply_keyexpr_default() -> zcu_reply_keyexpr_t { #[allow(non_camel_case_types)] #[repr(C)] #[derive(Clone, Copy)] -pub enum z_query_target_t { +pub enum z_loaned_query_target_t { BEST_MATCHING, ALL, ALL_COMPLETE, } -impl From for z_query_target_t { +impl From for z_loaned_query_target_t { #[inline] fn from(t: QueryTarget) -> Self { match t { - QueryTarget::BestMatching => z_query_target_t::BEST_MATCHING, - QueryTarget::All => z_query_target_t::ALL, - QueryTarget::AllComplete => z_query_target_t::ALL_COMPLETE, + QueryTarget::BestMatching => z_loaned_query_target_t::BEST_MATCHING, + QueryTarget::All => z_loaned_query_target_t::ALL, + QueryTarget::AllComplete => z_loaned_query_target_t::ALL_COMPLETE, } } } -impl From for QueryTarget { +impl From for QueryTarget { #[inline] - fn from(val: z_query_target_t) -> Self { + fn from(val: z_loaned_query_target_t) -> Self { match val { - z_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, - z_query_target_t::ALL => QueryTarget::All, - z_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, + z_loaned_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, + z_loaned_query_target_t::ALL => QueryTarget::All, + z_loaned_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, } } } -/// Create a default :c:type:`z_query_target_t`. +/// Create a default :c:type:`z_loaned_query_target_t`. #[no_mangle] -pub extern "C" fn z_query_target_default() -> z_query_target_t { +pub extern "C" fn z_loaned_query_target_default() -> z_loaned_query_target_t { QueryTarget::default().into() } diff --git a/src/config.rs b/src/config.rs index 9e207bbbe..2514d7f3d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -63,23 +63,23 @@ pub static Z_CONFIG_SCOUTING_DELAY_KEY: &c_char = pub static Z_CONFIG_ADD_TIMESTAMP_KEY: &c_char = unsafe { &*(b"timestamping/enabled\0".as_ptr() as *const c_char) }; -pub use crate::opaque_types::z_config_t; -decl_transmute_handle!(Config, z_config_t); +pub use crate::opaque_types::z_loaned_config_t; +decl_transmute_handle!(Config, z_loaned_config_t); pub use crate::opaque_types::z_owned_config_t; decl_transmute_owned!(Option, z_owned_config_t); -/// Returns a :c:type:`z_config_t` loaned from `s`. +/// Returns a :c:type:`z_loaned_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_config_t { +pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_loaned_config_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } -/// Returns a :c:type:`z_config_t` loaned from `s`. +/// Returns a :c:type:`z_loaned_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan_mut(this: &mut z_owned_config_t) -> &mut z_config_t { +pub extern "C" fn z_config_loan_mut(this: &mut z_owned_config_t) -> &mut z_loaned_config_t { let this = this.transmute_mut(); let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() @@ -111,7 +111,7 @@ pub extern "C" fn z_config_null(this: *mut MaybeUninit) { /// Clones the config. #[no_mangle] -pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_config_clone(src: &z_loaned_config_t, dst: *mut MaybeUninit) { let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); @@ -123,7 +123,7 @@ pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit, ) -> errors::z_error_t { @@ -154,7 +154,7 @@ pub unsafe extern "C" fn zc_config_get( #[no_mangle] #[allow(clippy::missing_safety_doc, unused_must_use)] pub unsafe extern "C" fn zc_config_insert_json( - config: &mut z_config_t, + config: &mut z_loaned_config_t, key: *const c_char, value: *const c_char, ) -> errors::z_error_t { @@ -210,7 +210,7 @@ pub unsafe extern "C" fn zc_config_from_str( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_config_to_string( - config: &z_config_t, + config: &z_loaned_config_t, config_string: *mut MaybeUninit, ) -> errors::z_error_t { let config: &Config = config.transmute_ref(); diff --git a/src/get.rs b/src/get.rs index 3586e50a2..d627a9075 100644 --- a/src/get.rs +++ b/src/get.rs @@ -30,25 +30,27 @@ use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; use crate::z_consolidation_mode_t; +use crate::z_loaned_query_target_t; +use crate::z_loaned_sample_t; +use crate::z_loaned_value_t; use crate::z_owned_bytes_t; use crate::z_owned_encoding_t; -use crate::z_query_target_t; -use crate::z_sample_t; -use crate::z_value_t; -use crate::{z_closure_reply_call, z_keyexpr_t, z_owned_closure_reply_t, z_session_t}; +use crate::{ + z_closure_reply_call, z_loaned_keyexpr_t, z_loaned_session_t, z_owned_closure_reply_t, +}; use zenoh::prelude::SyncResolve; pub use crate::opaque_types::z_owned_reply_t; decl_transmute_owned!(Option, z_owned_reply_t); -pub use crate::opaque_types::z_reply_t; -decl_transmute_handle!(Reply, z_reply_t); +pub use crate::opaque_types::z_loaned_reply_t; +decl_transmute_handle!(Reply, z_loaned_reply_t); /// Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. /// /// If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_is_ok(reply: &z_reply_t) -> bool { +pub unsafe extern "C" fn z_reply_is_ok(reply: &z_loaned_reply_t) -> bool { let reply = reply.transmute_ref(); reply.result().is_ok() } @@ -58,7 +60,7 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: &z_reply_t) -> bool { /// Returns null if reply does not contains a sample (i. e. if :c:func:`z_reply_is_ok` returns ``false``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_ok(reply: &z_reply_t) -> *const z_sample_t { +pub unsafe extern "C" fn z_reply_ok(reply: &z_loaned_reply_t) -> *const z_loaned_sample_t { let reply = reply.transmute_ref(); match reply.result() { Ok(sample) => sample.transmute_handle(), @@ -71,7 +73,7 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_reply_t) -> *const z_sample_t { /// Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_err(reply: &z_reply_t) -> *const z_value_t { +pub unsafe extern "C" fn z_reply_err(reply: &z_loaned_reply_t) -> *const z_loaned_value_t { let reply = reply.transmute_ref(); match reply.result() { Ok(_) => null(), @@ -92,7 +94,7 @@ pub extern "C" fn z_reply_null(this: *mut MaybeUninit) { } #[no_mangle] -pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: &z_reply_t) { +pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: &z_loaned_reply_t) { Inplace::init( this.transmute_uninit_ptr(), Some(reply.transmute_ref().clone()), @@ -102,14 +104,14 @@ pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: /// Options passed to the :c:func:`z_get` function. /// /// Members: -/// z_query_target_t target: The Queryables that should be target of the query. +/// z_loaned_query_target_t target: The Queryables that should be target of the query. /// z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. -/// z_value_t value: An optional value to attach to the query. -/// z_bytes_t attachment: The attachment to attach to the query. +/// z_loaned_value_t value: An optional value to attach to the query. +/// z_loaned_bytes_t attachment: The attachment to attach to the query. /// uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. #[repr(C)] pub struct z_get_options_t { - pub target: z_query_target_t, + pub target: z_loaned_query_target_t, pub consolidation: z_query_consolidation_t, pub payload: *mut z_owned_bytes_t, pub encoding: *mut z_owned_encoding_t, @@ -145,8 +147,8 @@ pub extern "C" fn z_get_options_default(this: &mut z_get_options_t) { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_get( - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, options: Option<&mut z_get_options_t>, @@ -206,7 +208,7 @@ pub extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { } #[no_mangle] -pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> &z_reply_t { +pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> &z_loaned_reply_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/info.rs b/src/info.rs index 90afc28ca..a7a23131e 100644 --- a/src/info.rs +++ b/src/info.rs @@ -12,7 +12,7 @@ use crate::transmute::{TransmuteCopy, TransmuteFromHandle}; // Contributors: // ZettaScale Zenoh team, // -use crate::{errors, z_closure_zid_call, z_owned_closure_zid_t, z_session_t}; +use crate::{errors, z_closure_zid_call, z_loaned_session_t, z_owned_closure_zid_t}; use std::mem::MaybeUninit; use zenoh::config::ZenohId; use zenoh::prelude::sync::SyncResolve; @@ -34,7 +34,7 @@ impl From<[u8; 16]> for z_id_t { /// to pass it a valid session. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { +pub unsafe extern "C" fn z_info_zid(session: z_loaned_session_t) -> z_id_t { let session = session.transmute_ref(); session.info().zid().res_sync().transmute_copy() } @@ -48,7 +48,7 @@ pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_peers_zid( - session: z_session_t, + session: z_loaned_session_t, callback: &mut z_owned_closure_zid_t, ) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); @@ -69,7 +69,7 @@ pub unsafe extern "C" fn z_info_peers_zid( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_routers_zid( - session: z_session_t, + session: z_loaned_session_t, callback: &mut z_owned_closure_zid_t, ) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 61fefacd5..4c2e75494 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -23,8 +23,8 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; +use crate::z_loaned_session_t; use crate::z_owned_str_t; -use crate::z_session_t; use crate::z_str_from_substring; use crate::z_view_slice_t; use crate::z_view_slice_wrap; @@ -143,15 +143,15 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize( } } -/// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. +/// Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. #[no_mangle] -pub extern "C" fn z_keyexpr_loan(key_expr: &z_owned_keyexpr_t) -> &z_keyexpr_t { +pub extern "C" fn z_keyexpr_loan(key_expr: &z_owned_keyexpr_t) -> &z_loaned_keyexpr_t { unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } -/// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. +/// Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. #[no_mangle] -pub extern "C" fn z_view_keyexpr_loan(key_expr: &z_view_keyexpr_t) -> &z_keyexpr_t { +pub extern "C" fn z_view_keyexpr_loan(key_expr: &z_view_keyexpr_t) -> &z_loaned_keyexpr_t { unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } @@ -183,8 +183,8 @@ pub extern "C" fn z_view_keyexpr_check(keyexpr: &z_view_keyexpr_t) -> bool { /// /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. -pub use crate::opaque_types::z_keyexpr_t; -decl_transmute_handle!(KeyExpr<'static>, z_keyexpr_t); +pub use crate::opaque_types::z_loaned_keyexpr_t; +decl_transmute_handle!(KeyExpr<'static>, z_loaned_keyexpr_t); /// Returns ``0`` if the passed string is a valid (and canon) key expression. /// Otherwise returns error value @@ -237,7 +237,7 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) } } -/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_view_keyexpr_from_slice( @@ -263,7 +263,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice( } } -/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. /// 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)] @@ -293,7 +293,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice_autocanonize( } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string. +/// Constructs a :c:type:`z_loaned_keyexpr_t` departing from a string. /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] @@ -310,7 +310,7 @@ pub unsafe extern "C" fn z_view_keyexpr( } } -/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. /// 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)] @@ -332,7 +332,7 @@ pub unsafe extern "C" fn z_view_keyexpr_autocanonize( } } -/// Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: /// - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -353,7 +353,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice_unchecked( Inplace::init(this.transmute_uninit_ptr(), Some(name)) } -/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: /// /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: @@ -372,11 +372,14 @@ pub unsafe extern "C" fn z_keyexpr_unchecked( z_view_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) } -/// Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. +/// Constructs a null-terminated string departing from a :c:type:`z_loaned_keyexpr_t`. /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { +pub unsafe extern "C" fn z_loaned_keyexpr_to_string( + ke: &z_loaned_keyexpr_t, + s: *mut MaybeUninit, +) { let ke = ke.transmute_ref(); unsafe { z_str_from_substring(s, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) }; } @@ -386,7 +389,10 @@ pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUnin /// Currently exclusive to zenoh-c #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUninit) { +pub unsafe extern "C" fn z_keyexpr_as_bytes( + ke: &z_loaned_keyexpr_t, + b: *mut MaybeUninit, +) { let ke = ke.transmute_ref(); unsafe { z_view_slice_wrap(b, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) }; } @@ -394,7 +400,7 @@ pub unsafe extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUnini /**************************************/ /* DECLARATION */ /**************************************/ -/// Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. +/// Declare a key expression. The id is returned as a :c:type:`z_loaned_keyexpr_t` with a nullptr suffix. /// /// This numerical id will be used on the network to save bandwidth and /// ease the retrieval of the concerned resource in the routing tables. @@ -402,8 +408,8 @@ pub unsafe extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUnini #[no_mangle] pub extern "C" fn z_declare_keyexpr( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, ) -> z_error_t { let this = this.transmute_uninit_ptr(); let key_expr = key_expr.transmute_ref(); @@ -426,7 +432,7 @@ pub extern "C" fn z_declare_keyexpr( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_keyexpr( - session: &z_session_t, + session: &z_loaned_session_t, kexpr: &mut z_owned_keyexpr_t, ) -> errors::z_error_t { let Some(kexpr) = kexpr.transmute_mut().take() else { @@ -446,7 +452,7 @@ pub extern "C" fn z_undeclare_keyexpr( #[allow(clippy::missing_safety_doc)] #[no_mangle] /// Returns ``0`` if both ``left`` and ``right`` are equal. -pub extern "C" fn z_keyexpr_equals(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_equals(left: &z_loaned_keyexpr_t, right: &z_loaned_keyexpr_t) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); *l == *r @@ -456,7 +462,10 @@ pub extern "C" fn z_keyexpr_equals(left: &z_keyexpr_t, right: &z_keyexpr_t) -> b #[no_mangle] /// Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the /// sets defined by ``left`` and ``right``. -pub extern "C" fn z_keyexpr_intersects(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_intersects( + left: &z_loaned_keyexpr_t, + right: &z_loaned_keyexpr_t, +) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); l.intersects(r) @@ -466,7 +475,10 @@ pub extern "C" fn z_keyexpr_intersects(left: &z_keyexpr_t, right: &z_keyexpr_t) #[no_mangle] /// Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set /// defined by ``right``. -pub extern "C" fn z_keyexpr_includes(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_includes( + left: &z_loaned_keyexpr_t, + right: &z_loaned_keyexpr_t, +) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); l.includes(r) @@ -483,7 +495,7 @@ pub extern "C" fn z_keyexpr_includes(left: &z_keyexpr_t, right: &z_keyexpr_t) -> /// as this would extremely likely cause bugs. pub unsafe extern "C" fn z_keyexpr_concat( this: *mut MaybeUninit, - left: &z_keyexpr_t, + left: &z_loaned_keyexpr_t, right_start: *const c_char, right_len: usize, ) -> errors::z_error_t { @@ -522,8 +534,8 @@ pub unsafe extern "C" fn z_keyexpr_concat( /// In case of error, the return value will be set to its invalidated state. pub extern "C" fn z_keyexpr_join( this: *mut MaybeUninit, - left: &z_keyexpr_t, - right: &z_keyexpr_t, + left: &z_loaned_keyexpr_t, + right: &z_loaned_keyexpr_t, ) -> errors::z_error_t { let left = left.transmute_ref(); let right = right.transmute_ref(); @@ -572,8 +584,8 @@ impl From for z_keyexpr_intersection_level_t { /// /// Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. pub extern "C" fn z_keyexpr_relation_to( - left: &z_keyexpr_t, - right: &z_keyexpr_t, + left: &z_loaned_keyexpr_t, + right: &z_loaned_keyexpr_t, ) -> z_keyexpr_intersection_level_t { let l = left.transmute_ref(); let r = right.transmute_ref(); diff --git a/src/liveliness.rs b/src/liveliness.rs index 8fefb253d..ae48097e7 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -23,17 +23,17 @@ use crate::transmute::TransmuteIntoHandle; use crate::{ errors, transmute::{Inplace, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, - z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, - z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, + z_closure_reply_call, z_closure_sample_call, z_loaned_keyexpr_t, z_loaned_session_t, + z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, }; -use crate::opaque_types::zc_liveliness_token_t; +use crate::opaque_types::zc_loaned_liveliness_token_t; use crate::opaque_types::zc_owned_liveliness_token_t; decl_transmute_owned!( Option>, zc_owned_liveliness_token_t ); -decl_transmute_handle!(LivelinessToken<'static>, zc_liveliness_token_t); +decl_transmute_handle!(LivelinessToken<'static>, zc_loaned_liveliness_token_t); /// The gravestone value for liveliness tokens. #[no_mangle] @@ -69,8 +69,8 @@ pub extern "C" fn zc_liveliness_declaration_options_default( #[no_mangle] pub extern "C" fn zc_liveliness_declare_token( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, _options: Option<&mut zc_liveliness_declaration_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); @@ -120,8 +120,8 @@ pub extern "C" fn zc_liveliness_subscriber_options_default( /// Declares a subscriber on liveliness tokens that intersect `key`. /// /// Parameters: -/// z_session_t session: The zenoh session. -/// z_keyexpr_t key_expr: The key expression to subscribe. +/// z_loaned_session_t session: The zenoh session. +/// z_loaned_keyexpr_t key_expr: The key expression to subscribe. /// z_owned_closure_sample_t callback: The callback function that will be called each time a /// liveliness token status changed. /// zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. @@ -134,8 +134,8 @@ pub extern "C" fn zc_liveliness_subscriber_options_default( #[no_mangle] pub extern "C" fn zc_liveliness_declare_subscriber( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_sample_t, _options: Option<&mut zc_liveliness_declare_subscriber_options_t>, ) -> errors::z_error_t { @@ -183,8 +183,8 @@ pub extern "C" fn zc_liveliness_get_options_default(this: &mut zc_liveliness_get /// Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. #[no_mangle] pub extern "C" fn zc_liveliness_get( - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_reply_t, options: Option<&mut zc_liveliness_get_options_t>, ) -> errors::z_error_t { diff --git a/src/payload.rs b/src/payload.rs index 665ae0d24..1283f28a6 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -4,8 +4,8 @@ use crate::transmute::{ TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{ - z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, - ZHashMap, + z_loaned_slice_map_t, z_loaned_slice_t, z_loaned_str_t, z_owned_slice_map_t, z_owned_slice_t, + z_owned_str_t, ZHashMap, }; use core::fmt; use std::any::Any; @@ -42,18 +42,18 @@ extern "C" fn z_bytes_check(payload: &z_owned_bytes_t) -> bool { /// Loans the payload, allowing you to call functions that only need a loan of it. #[no_mangle] -extern "C" fn z_bytes_loan(payload: &z_owned_bytes_t) -> &z_bytes_t { +extern "C" fn z_bytes_loan(payload: &z_owned_bytes_t) -> &z_loaned_bytes_t { let payload = payload.transmute_ref(); let payload = unwrap_ref_unchecked(payload); payload.transmute_handle() } -pub use crate::opaque_types::z_bytes_t; -decl_transmute_handle!(ZBytes, z_bytes_t); +pub use crate::opaque_types::z_loaned_bytes_t; +decl_transmute_handle!(ZBytes, z_loaned_bytes_t); /// Increments the payload's reference count, returning an owned version of it. #[no_mangle] -extern "C" fn z_bytes_clone(src: &z_bytes_t, dst: *mut MaybeUninit) { +extern "C" fn z_bytes_clone(src: &z_loaned_bytes_t, dst: *mut MaybeUninit) { let dst = dst.transmute_uninit_ptr(); let src = src.transmute_ref(); let src = Some(src.clone()); @@ -62,7 +62,7 @@ extern "C" fn z_bytes_clone(src: &z_bytes_t, dst: *mut MaybeUninit usize { +extern "C" fn z_bytes_len(payload: &z_loaned_bytes_t) -> usize { payload.transmute_ref().len() } @@ -70,7 +70,7 @@ extern "C" fn z_bytes_len(payload: &z_bytes_t) -> usize { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_string( - payload: &z_bytes_t, + payload: &z_loaned_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let len = z_bytes_len(payload); @@ -95,7 +95,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( - payload: z_bytes_t, + payload: z_loaned_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let dst = dst.transmute_uninit_ptr(); @@ -113,7 +113,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_bytes( - payload: &z_bytes_t, + payload: &z_loaned_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let payload = payload.transmute_ref(); @@ -131,17 +131,17 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes( } } -unsafe impl Send for z_slice_t {} -unsafe impl Sync for z_slice_t {} +unsafe impl Send for z_loaned_slice_t {} +unsafe impl Sync for z_loaned_slice_t {} -impl fmt::Debug for z_slice_t { +impl fmt::Debug for z_loaned_slice_t { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = self.transmute_ref(); - f.debug_struct("z_slice_t").field("_0", s).finish() + f.debug_struct("z_loaned_slice_t").field("_0", s).finish() } } -impl ZSliceBuffer for z_slice_t { +impl ZSliceBuffer for z_loaned_slice_t { fn as_slice(&self) -> &[u8] { self.transmute_ref() } @@ -159,7 +159,7 @@ impl ZSliceBuffer for z_slice_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_bytes( this: *mut MaybeUninit, - bytes: &z_slice_t, + bytes: &z_loaned_slice_t, ) { let this = this.transmute_uninit_ptr(); let payload = ZBytes::from(ZSlice::from(*bytes)); @@ -171,7 +171,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( this: *mut MaybeUninit, - bytes_map: &z_slice_map_t, + bytes_map: &z_loaned_slice_map_t, ) { let dst = this.transmute_uninit_ptr(); let hm = bytes_map.transmute_ref(); @@ -184,7 +184,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_string( this: *mut MaybeUninit, - s: &z_str_t, + s: &z_loaned_str_t, ) { let s = s.transmute_ref(); let ss = &s[0..s.len() - 1]; @@ -195,8 +195,8 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( pub use crate::opaque_types::z_owned_bytes_reader_t; decl_transmute_owned!(Option>, z_owned_bytes_reader_t); -pub use crate::opaque_types::z_bytes_reader_t; -decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); +pub use crate::opaque_types::z_loaned_bytes_reader_t; +decl_transmute_handle!(ZBytesReader<'static>, z_loaned_bytes_reader_t); /// Creates a reader for the specified `payload`. /// @@ -204,7 +204,7 @@ decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_new( - payload: z_bytes_t, + payload: z_loaned_bytes_t, this: *mut MaybeUninit, ) { let this = this.transmute_uninit_ptr(); @@ -233,7 +233,7 @@ extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_reader_t) { } #[no_mangle] -extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_reader_t { +extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_loaned_bytes_reader_t { let reader = reader.transmute_ref(); let reader = unwrap_ref_unchecked(reader); reader.transmute_handle() @@ -242,7 +242,7 @@ extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_r #[no_mangle] extern "C" fn z_bytes_reader_loan_mut( reader: &mut z_owned_bytes_reader_t, -) -> &mut z_bytes_reader_t { +) -> &mut z_loaned_bytes_reader_t { let reader = reader.transmute_mut(); let reader = unwrap_ref_unchecked_mut(reader); reader.transmute_handle_mut() @@ -255,7 +255,7 @@ extern "C" fn z_bytes_reader_loan_mut( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_read( - this: &mut z_bytes_reader_t, + this: &mut z_loaned_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { @@ -271,7 +271,7 @@ pub unsafe extern "C" fn z_bytes_reader_read( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_seek( - this: &mut z_bytes_reader_t, + this: &mut z_loaned_bytes_reader_t, offset: i64, origin: libc::c_int, ) -> z_error_t { @@ -294,7 +294,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( /// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_tell(this: &mut z_bytes_reader_t) -> i64 { +pub unsafe extern "C" fn z_loaned_bytes_reader_tell(this: &mut z_loaned_bytes_reader_t) -> i64 { let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index 9c2adf78f..52032c8aa 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -6,7 +6,7 @@ use std::{ use libc::c_void; -pub use crate::opaque_types::z_mutex_t; +pub use crate::opaque_types::z_loaned_mutex_t; pub use crate::opaque_types::z_owned_mutex_t; use crate::{ errors, @@ -20,7 +20,10 @@ decl_transmute_owned!( Option<(Mutex<()>, Option>)>, z_owned_mutex_t ); -decl_transmute_handle!((Mutex<()>, Option>), z_mutex_t); +decl_transmute_handle!( + (Mutex<()>, Option>), + z_loaned_mutex_t +); #[no_mangle] pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::z_error_t { @@ -46,14 +49,14 @@ pub extern "C" fn z_mutex_null(this: *mut MaybeUninit) { } #[no_mangle] -pub extern "C" fn z_mutex_loan_mut(this: &mut z_owned_mutex_t) -> &mut z_mutex_t { +pub extern "C" fn z_mutex_loan_mut(this: &mut z_owned_mutex_t) -> &mut z_loaned_mutex_t { let this = this.transmute_mut(); let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() } #[no_mangle] -pub extern "C" fn z_mutex_lock(this: &mut z_mutex_t) -> errors::z_error_t { +pub extern "C" fn z_mutex_lock(this: &mut z_loaned_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.lock() { @@ -69,7 +72,7 @@ pub extern "C" fn z_mutex_lock(this: &mut z_mutex_t) -> errors::z_error_t { } #[no_mangle] -pub extern "C" fn z_mutex_unlock(this: &mut z_mutex_t) -> errors::z_error_t { +pub extern "C" fn z_mutex_unlock(this: &mut z_loaned_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); if this.1.is_none() { return errors::Z_EINVAL_MUTEX; @@ -81,7 +84,7 @@ pub extern "C" fn z_mutex_unlock(this: &mut z_mutex_t) -> errors::z_error_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_try_lock(this: &mut z_mutex_t) -> errors::z_error_t { +pub unsafe extern "C" fn z_loaned_mutex_try_lock(this: &mut z_loaned_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.try_lock() { Ok(new_lock) => { @@ -95,11 +98,11 @@ pub unsafe extern "C" fn z_mutex_try_lock(this: &mut z_mutex_t) -> errors::z_err errors::Z_OK } -pub use crate::opaque_types::z_condvar_t; +pub use crate::opaque_types::z_loaned_condvar_t; pub use crate::opaque_types::z_owned_condvar_t; decl_transmute_owned!(Option, z_owned_condvar_t); -decl_transmute_handle!(Condvar, z_condvar_t); +decl_transmute_handle!(Condvar, z_loaned_condvar_t); #[no_mangle] pub extern "C" fn z_condvar_init(this: *mut MaybeUninit) { @@ -124,21 +127,21 @@ pub extern "C" fn z_condvar_check(this: &z_owned_condvar_t) -> bool { } #[no_mangle] -pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> &z_condvar_t { +pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> &z_loaned_condvar_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } #[no_mangle] -pub extern "C" fn z_condvar_loan_mut(this: &mut z_owned_condvar_t) -> &mut z_condvar_t { +pub extern "C" fn z_condvar_loan_mut(this: &mut z_owned_condvar_t) -> &mut z_loaned_condvar_t { let this = this.transmute_mut(); let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() } #[no_mangle] -pub extern "C" fn z_condvar_signal(this: &z_condvar_t) -> errors::z_error_t { +pub extern "C" fn z_condvar_signal(this: &z_loaned_condvar_t) -> errors::z_error_t { let this = this.transmute_ref(); this.notify_one(); errors::Z_OK @@ -147,8 +150,8 @@ pub extern "C" fn z_condvar_signal(this: &z_condvar_t) -> errors::z_error_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_condvar_wait( - this: &z_condvar_t, - m: &mut z_mutex_t, + this: &z_loaned_condvar_t, + m: &mut z_loaned_mutex_t, ) -> errors::z_error_t { let this = this.transmute_ref(); let m = m.transmute_mut(); diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 84278e3d8..49cc9f1f1 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -19,12 +19,12 @@ use zenoh::prelude::SyncResolve; use zenoh_ext::SessionExt; use crate::transmute::{Inplace, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; -use crate::{errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t}; +use crate::{errors, z_loaned_keyexpr_t, z_loaned_session_t, zcu_locality_default, zcu_locality_t}; /// Options passed to the :c:func:`ze_declare_publication_cache` function. /// /// Members: -/// z_keyexpr_t queryable_prefix: The prefix used for queryable +/// z_loaned_keyexpr_t queryable_prefix: The prefix used for queryable /// zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this /// publication cache /// bool queryable_complete: the `complete` option for the queryable @@ -32,7 +32,7 @@ use crate::{errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality /// size_t resources_limit: The limit number of cached resources #[repr(C)] pub struct ze_publication_cache_options_t { - pub queryable_prefix: *const z_keyexpr_t, + pub queryable_prefix: *const z_loaned_keyexpr_t, pub queryable_origin: zcu_locality_t, pub queryable_complete: bool, pub history: usize, @@ -51,19 +51,22 @@ pub extern "C" fn ze_publication_cache_options_default(this: &mut ze_publication }; } +pub use crate::opaque_types::ze_loaned_publication_cache_t; pub use crate::opaque_types::ze_owned_publication_cache_t; -pub use crate::opaque_types::ze_publication_cache_t; decl_transmute_owned!( Option>, ze_owned_publication_cache_t ); -decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); +decl_transmute_handle!( + zenoh_ext::PublicationCache<'static>, + ze_loaned_publication_cache_t +); /// Declares a Publication Cache. /// /// Parameters: -/// z_session_t session: The zenoh session. -/// z_keyexpr_t key_expr: The key expression to publish. +/// z_loaned_session_t session: The zenoh session. +/// z_loaned_keyexpr_t key_expr: The key expression to publish. /// ze_publication_cache_options_t options: Additional options for the publication_cache. /// /// Returns: @@ -87,8 +90,8 @@ decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cach #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_declare_publication_cache( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, options: Option<&mut ze_publication_cache_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); diff --git a/src/publisher.rs b/src/publisher.rs index 8b647dfd4..f4d6b8cbf 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -34,7 +34,9 @@ use zenoh::{prelude::Priority, publication::MatchingListener, publication::Publi use zenoh::prelude::SyncResolve; -use crate::{z_congestion_control_t, z_keyexpr_t, z_owned_bytes_t, z_priority_t, z_session_t}; +use crate::{ + z_congestion_control_t, z_loaned_keyexpr_t, z_loaned_session_t, z_owned_bytes_t, z_priority_t, +}; /// Options passed to the :c:func:`z_declare_publisher` function. /// @@ -58,8 +60,8 @@ pub extern "C" fn z_publisher_options_default(this: &mut z_publisher_options_t) pub use crate::opaque_types::z_owned_publisher_t; decl_transmute_owned!(Option>, z_owned_publisher_t); -pub use crate::opaque_types::z_publisher_t; -decl_transmute_handle!(Publisher<'static>, z_publisher_t); +pub use crate::opaque_types::z_loaned_publisher_t; +decl_transmute_handle!(Publisher<'static>, z_loaned_publisher_t); /// Declares a publisher for the given key expression. /// @@ -98,8 +100,8 @@ decl_transmute_handle!(Publisher<'static>, z_publisher_t); #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_publisher( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, options: Option<&z_publisher_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); @@ -139,9 +141,9 @@ pub extern "C" fn z_publisher_check(this: &z_owned_publisher_t) -> bool { this.transmute_ref().is_some() } -/// Returns a :c:type:`z_publisher_t` loaned from `p`. +/// Returns a :c:type:`z_loaned_publisher_t` loaned from `p`. #[no_mangle] -pub extern "C" fn z_publisher_loan(this: &z_owned_publisher_t) -> &z_publisher_t { +pub extern "C" fn z_publisher_loan(this: &z_owned_publisher_t) -> &z_loaned_publisher_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -185,7 +187,7 @@ pub extern "C" fn z_publisher_put_options_default(this: &mut z_publisher_put_opt #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_publisher_put( - publisher: &z_publisher_t, + publisher: &z_loaned_publisher_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_publisher_put_options_t>, ) -> errors::z_error_t { @@ -241,7 +243,7 @@ pub extern "C" fn z_publisher_delete_options_default(this: &mut z_publisher_dele #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_delete( - publisher: &z_publisher_t, + publisher: &z_loaned_publisher_t, _options: z_publisher_delete_options_t, ) -> errors::z_error_t { let publisher = publisher.transmute_ref(); @@ -256,7 +258,7 @@ pub extern "C" fn z_publisher_delete( /// Returns the key expression of the publisher #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_keyexpr(publisher: &z_publisher_t) -> &z_keyexpr_t { +pub extern "C" fn z_publisher_keyexpr(publisher: &z_loaned_publisher_t) -> &z_loaned_keyexpr_t { let publisher = publisher.transmute_ref(); publisher.key_expr().transmute_handle() } @@ -282,7 +284,7 @@ pub struct zcu_matching_status_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn zcu_publisher_matching_listener_callback( this: *mut MaybeUninit, - publisher: &z_publisher_t, + publisher: &z_loaned_publisher_t, callback: &mut zcu_owned_closure_matching_status_t, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index 624be46cb..79ba96eb3 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -136,8 +136,8 @@ pub extern "C" fn z_pull_subscriber_options_default() -> z_pull_subscriber_optio #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_pull_subscriber( - session: z_session_t, - keyexpr: z_keyexpr_t, + session: z_loaned_session_t, + keyexpr: z_loaned_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&z_pull_subscriber_options_t>, ) -> z_owned_pull_subscriber_t { @@ -149,7 +149,7 @@ pub extern "C" fn z_declare_pull_subscriber( let mut res = s .declare_subscriber(keyexpr) .callback(move |sample| { - let sample = z_sample_t::new(&sample); + let sample = z_loaned_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) .pull_mode(); diff --git a/src/put.rs b/src/put.rs index 74b63b4b8..ef5f99801 100644 --- a/src/put.rs +++ b/src/put.rs @@ -19,8 +19,8 @@ use crate::keyexpr::*; use crate::transmute::Inplace; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteRef; +use crate::z_loaned_session_t; use crate::z_owned_bytes_t; -use crate::z_session_t; use zenoh::prelude::{sync::SyncResolve, Priority}; use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; @@ -30,10 +30,10 @@ use zenoh::sample::ValueBuilderTrait; /// Options passed to the :c:func:`z_put` function. /// /// Members: -/// z_encoding_t encoding: The encoding of the payload. +/// z_loaned_encoding_t encoding: The encoding of the payload. /// z_congestion_control_t congestion_control: The congestion control to apply when routing this message. /// z_priority_t priority: The priority of this message. -/// z_bytes_t attachment: The attachment to this message. +/// z_loaned_bytes_t attachment: The attachment to this message. #[repr(C)] #[allow(non_camel_case_types)] pub struct z_put_options_t { @@ -71,8 +71,8 @@ pub extern "C" fn z_put_options_default(this: &mut z_put_options_t) { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_put( - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_put_options_t>, ) -> errors::z_error_t { @@ -135,8 +135,8 @@ pub unsafe extern "C" fn z_delete_options_default(this: *mut z_delete_options_t) #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_delete( - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, options: Option<&mut z_delete_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); diff --git a/src/queryable.rs b/src/queryable.rs index 0f2de51ce..03da4edbe 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -16,8 +16,9 @@ use crate::transmute::{ TransmuteUninitPtr, }; use crate::{ - errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, - z_owned_encoding_t, z_session_t, z_value_t, z_view_slice_t, z_view_slice_wrap, + errors, z_closure_query_call, z_loaned_bytes_t, z_loaned_keyexpr_t, z_loaned_session_t, + z_loaned_value_t, z_owned_bytes_t, z_owned_closure_query_t, z_owned_encoding_t, z_view_slice_t, + z_view_slice_wrap, }; use std::mem::MaybeUninit; use std::ptr::{null, null_mut}; @@ -36,8 +37,8 @@ pub extern "C" fn z_queryable_null(this: *mut MaybeUninit) Inplace::empty(this.transmute_uninit_ptr()); } -pub use crate::opaque_types::z_query_t; -decl_transmute_handle!(Query, z_query_t); +pub use crate::opaque_types::z_loaned_query_t; +decl_transmute_handle!(Query, z_loaned_query_t); /// Owned variant of a Query received by a Queryable. /// @@ -66,7 +67,7 @@ pub extern "C" fn z_query_check(query: &z_owned_query_t) -> bool { /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] -pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> &z_query_t { +pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> &z_loaned_query_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -82,7 +83,7 @@ pub extern "C" fn z_query_drop(this: &mut z_owned_query_t) { /// /// This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). #[no_mangle] -pub extern "C" fn z_query_clone(this: &z_query_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_query_clone(this: &z_loaned_query_t, dst: *mut MaybeUninit) { let this = this.transmute_ref(); let this = this.clone(); let dst = dst.transmute_uninit_ptr(); @@ -142,8 +143,8 @@ pub extern "C" fn z_query_reply_options_default(this: &mut z_query_reply_options #[no_mangle] pub extern "C" fn z_declare_queryable( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_query_t, options: Option<&mut z_queryable_options_t>, ) -> errors::z_error_t { @@ -210,8 +211,8 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_reply( - query: z_query_t, - key_expr: z_keyexpr_t, + query: z_loaned_query_t, + key_expr: z_loaned_keyexpr_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_query_reply_options_t>, ) -> errors::z_error_t { @@ -248,7 +249,7 @@ pub unsafe extern "C" fn z_query_reply( /// Get a query's key by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { +pub extern "C" fn z_query_keyexpr(query: &z_loaned_query_t) -> &z_loaned_keyexpr_t { query.transmute_ref().key_expr().transmute_handle() } @@ -256,7 +257,7 @@ pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_parameters( - query: &z_query_t, + query: &z_loaned_query_t, parameters: *mut MaybeUninit, ) { let query = query.transmute_ref(); @@ -266,7 +267,7 @@ pub unsafe extern "C" fn z_query_parameters( /// Checks if query contains a payload value. #[no_mangle] -pub extern "C" fn z_query_has_value(query: &z_query_t) -> bool { +pub extern "C" fn z_query_has_value(query: &z_loaned_query_t) -> bool { query.transmute_ref().value().is_some() } @@ -275,7 +276,7 @@ pub extern "C" fn z_query_has_value(query: &z_query_t) -> bool { /// **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** /// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] -pub extern "C" fn z_query_value(query: &z_query_t) -> &z_value_t { +pub extern "C" fn z_query_value(query: &z_loaned_query_t) -> &z_loaned_value_t { query .transmute_ref() .value() @@ -287,7 +288,7 @@ pub extern "C" fn z_query_value(query: &z_query_t) -> &z_value_t { /// /// Returns NULL if query does not contain an attachment. #[no_mangle] -pub extern "C" fn z_query_attachment(query: &z_query_t) -> *const z_bytes_t { +pub extern "C" fn z_query_attachment(query: &z_loaned_query_t) -> *const z_loaned_bytes_t { match query.transmute_ref().attachment() { Some(attachment) => attachment.transmute_handle() as *const _, None => null(), diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 0166314f1..c1d180ecc 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -22,13 +22,13 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_keyexpr_t; +use crate::z_loaned_keyexpr_t; use crate::z_owned_closure_sample_t; use crate::z_reliability_t; use crate::{ - z_closure_sample_call, z_get_options_t, z_query_consolidation_none, z_query_consolidation_t, - z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, - zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, + z_closure_sample_call, z_get_options_t, z_loaned_query_target_default, z_loaned_query_target_t, + z_loaned_session_t, z_query_consolidation_none, z_query_consolidation_t, zcu_locality_default, + zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, }; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; @@ -36,15 +36,15 @@ use zenoh::session::Session; use zenoh::subscriber::Reliability; use zenoh_ext::*; +use crate::opaque_types::ze_loaned_querying_subscriber_t; use crate::opaque_types::ze_owned_querying_subscriber_t; -use crate::opaque_types::ze_querying_subscriber_t; decl_transmute_owned!( Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t ); decl_transmute_handle!( (zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), - ze_querying_subscriber_t + ze_loaned_querying_subscriber_t ); /// Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type @@ -64,8 +64,8 @@ pub extern "C" fn ze_querying_subscriber_null( /// z_reliability_t reliability: The subscription reliability. /// zcu_locality_t allowed_origin: The restriction for the matching publications that will be /// receive by this subscriber. -/// z_keyexpr_t query_selector: The selector to be used for queries. -/// z_query_target_t query_target: The target to be used for queries. +/// z_loaned_keyexpr_t query_selector: The selector to be used for queries. +/// z_loaned_query_target_t query_target: The target to be used for queries. /// z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. /// zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. /// uint64_t query_timeout_ms: The timeout to be used for queries. @@ -74,8 +74,8 @@ pub extern "C" fn ze_querying_subscriber_null( pub struct ze_querying_subscriber_options_t { reliability: z_reliability_t, allowed_origin: zcu_locality_t, - query_selector: *const z_keyexpr_t, - query_target: z_query_target_t, + query_selector: *const z_loaned_keyexpr_t, + query_target: z_loaned_query_target_t, query_consolidation: z_query_consolidation_t, query_accept_replies: zcu_reply_keyexpr_t, query_timeout_ms: u64, @@ -90,7 +90,7 @@ pub extern "C" fn ze_querying_subscriber_options_default( reliability: Reliability::DEFAULT.into(), allowed_origin: zcu_locality_default(), query_selector: null(), - query_target: z_query_target_default(), + query_target: z_loaned_query_target_default(), query_consolidation: z_query_consolidation_none(), query_accept_replies: zcu_reply_keyexpr_default(), query_timeout_ms: 0, @@ -100,8 +100,8 @@ pub extern "C" fn ze_querying_subscriber_options_default( /// Declares a Querying Subscriber for a given key expression. /// /// Parameters: -/// z_session_t session: The zenoh session. -/// z_keyexpr_t keyexpr: The key expression to subscribe. +/// z_loaned_session_t session: The zenoh session. +/// z_loaned_keyexpr_t keyexpr: The key expression to subscribe. /// z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. /// ze_querying_subscriber_options_t options: Additional options for the querying subscriber. /// @@ -132,8 +132,8 @@ pub extern "C" fn ze_querying_subscriber_options_default( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn ze_declare_querying_subscriber( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&mut ze_querying_subscriber_options_t>, ) -> errors::z_error_t { @@ -181,8 +181,8 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn ze_querying_subscriber_get( - sub: &ze_querying_subscriber_t, - selector: &z_keyexpr_t, + sub: &ze_loaned_querying_subscriber_t, + selector: &z_loaned_keyexpr_t, options: Option<&z_get_options_t>, ) -> errors::z_error_t { unsafe impl Sync for z_get_options_t {} @@ -237,7 +237,7 @@ pub extern "C" fn ze_querying_subscriber_check(this: &ze_owned_querying_subscrib #[no_mangle] pub extern "C" fn ze_querying_subscriber_loan( this: &ze_owned_querying_subscriber_t, -) -> &ze_querying_subscriber_t { +) -> &ze_loaned_querying_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/scouting.rs b/src/scouting.rs index 7609c3a38..7a7931301 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -15,8 +15,8 @@ use crate::{ errors::{self, Z_OK}, transmute::{Inplace, TransmuteRef}, z_closure_hello_call, z_config_check, z_config_clone, z_config_default, z_config_drop, - z_config_null, z_config_t, z_id_t, z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, - CopyableToCArray, + z_config_null, z_id_t, z_loaned_config_t, 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}; @@ -219,7 +219,7 @@ pub unsafe extern "C" fn z_scouting_config_default( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_scouting_config_from( this: *mut MaybeUninit, - config: &z_config_t, + config: &z_loaned_config_t, ) { let mut dst = MaybeUninit::uninit(); z_config_clone(config, &mut dst as *mut _); diff --git a/src/session.rs b/src/session.rs index 049fd7ca3..768bdf720 100644 --- a/src/session.rs +++ b/src/session.rs @@ -26,19 +26,19 @@ use crate::opaque_types::z_owned_session_t; decl_transmute_owned!(Option>, z_owned_session_t); /// A loaned zenoh session. -use crate::opaque_types::z_session_t; -decl_transmute_handle!(Session, z_session_t); +use crate::opaque_types::z_loaned_session_t; +decl_transmute_handle!(Session, z_loaned_session_t); -/// Returns a :c:type:`z_session_t` loaned from `s`. +/// Returns a :c:type:`z_loaned_session_t` loaned from `s`. /// /// This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. /// /// # Safety -/// The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, +/// The returned `z_loaned_session_t` aliases `z_owned_session_t`'s internal allocation, /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(this: &z_owned_session_t) -> &z_session_t { +pub extern "C" fn z_session_loan(this: &z_owned_session_t) -> &z_loaned_session_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); let this = this.as_ref(); diff --git a/src/shm.rs b/src/shm.rs index 52f9d51cd..cb90ed65f 100644 --- a/src/shm.rs +++ b/src/shm.rs @@ -23,7 +23,7 @@ use zenoh::{ shm::{SharedMemoryBuf, SharedMemoryManager}, }; -use crate::{z_session_t, z_owned_bytes_t, z_bytes_null}; +use crate::{z_loaned_session_t, z_owned_bytes_t, z_bytes_null}; #[repr(C)] pub struct zc_owned_shm_manager_t(usize); @@ -51,7 +51,7 @@ impl zc_owned_shm_manager_t { #[no_mangle] pub extern "C" fn zc_shm_manager_new( - session: z_session_t, + session: z_loaned_session_t, id: *const c_char, size: usize, ) -> zc_owned_shm_manager_t { diff --git a/src/subscriber.rs b/src/subscriber.rs index ad5d73e4d..f1cb26beb 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -23,8 +23,8 @@ use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; use crate::z_closure_sample_call; +use crate::z_loaned_session_t; use crate::z_owned_closure_sample_t; -use crate::z_session_t; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; use zenoh::subscriber::Reliability; @@ -62,11 +62,11 @@ impl From for Reliability { } } +pub use crate::opaque_types::z_loaned_subscriber_t; pub use crate::opaque_types::z_owned_subscriber_t; -pub use crate::opaque_types::z_subscriber_t; decl_transmute_owned!(Option>, z_owned_subscriber_t); -decl_transmute_handle!(Subscriber<'static, ()>, z_subscriber_t); +decl_transmute_handle!(Subscriber<'static, ()>, z_loaned_subscriber_t); /// Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type #[no_mangle] @@ -75,9 +75,9 @@ pub extern "C" fn z_subscriber_null(this: *mut MaybeUninit Inplace::empty(this); } -/// Returns a :c:type:`z_subscriber_t` loaned from `this`. +/// Returns a :c:type:`z_loaned_subscriber_t` loaned from `this`. #[no_mangle] -pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> &z_subscriber_t { +pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> &z_loaned_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -136,8 +136,8 @@ pub extern "C" fn z_subscriber_options_default(this: &mut z_subscriber_options_t #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_subscriber( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&mut z_subscriber_options_t>, ) -> errors::z_error_t { @@ -171,7 +171,7 @@ pub extern "C" fn z_declare_subscriber( /// Returns the key expression of the subscriber. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_subscriber_keyexpr(subscriber: &z_subscriber_t) -> &z_keyexpr_t { +pub extern "C" fn z_subscriber_keyexpr(subscriber: &z_loaned_subscriber_t) -> &z_loaned_keyexpr_t { let subscriber = subscriber.transmute_ref(); subscriber.key_expr().transmute_handle() } diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 062c7c7ad..57bb31fd9 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -41,19 +41,19 @@ void hello_handler(z_owned_hello_t *hello, void *arg) { } volatile unsigned int queries = 0; -void query_handler(const z_query_t *query, void *arg) { +void query_handler(const z_loaned_query_t *query, void *arg) { queries++; - z_owned_str_t k_str = z_keyexpr_to_string(z_query_keyexpr(query)); + z_owned_str_t k_str = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); #ifdef ZENOH_PICO if (k_str == NULL) { - k_str = zp_keyexpr_resolve(*(z_session_t *)arg, z_query_keyexpr(query)); + k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, z_query_keyexpr(query)); } #endif - z_slice_t pred = z_query_parameters(query); + z_loaned_slice_t pred = z_query_parameters(query); (void)(pred); - z_value_t payload_value = z_query_value(query); + z_loaned_value_t payload_value = z_query_value(query); (void)(payload_value); z_query_reply_options_t _ret_qreply_opt = z_query_reply_options_default(); z_owned_bytes_t payload = z_bytes_encode_from_string(value); @@ -67,17 +67,17 @@ void reply_handler(z_owned_reply_t *reply, void *arg) { replies++; if (z_reply_is_ok(reply)) { - z_sample_t sample = z_reply_ok(reply); + z_loaned_sample_t sample = z_reply_ok(reply); - z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_owned_str_t k_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); #ifdef ZENOH_PICO if (k_str == NULL) { - k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample.keyexpr); + k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, sample.keyexpr); } #endif z_drop(z_move(k_str)); } else { - z_value_t _ret_zvalue = z_reply_err(reply); + z_loaned_value_t _ret_zvalue = z_reply_err(reply); (void)(_ret_zvalue); } @@ -85,13 +85,13 @@ void reply_handler(z_owned_reply_t *reply, void *arg) { } volatile unsigned int datas = 0; -void data_handler(const z_sample_t *sample, void *arg) { +void data_handler(const z_loaned_sample_t *sample, void *arg) { datas++; - z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t k_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); #ifdef ZENOH_PICO if (k_str == NULL) { - k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample->keyexpr); + k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, sample->keyexpr); } #endif z_drop(z_move(k_str)); @@ -104,7 +104,7 @@ int main(int argc, char **argv) { zc_init_logger(); #endif - z_keyexpr_t key = z_keyexpr("demo/example"); + z_loaned_keyexpr_t key = z_keyexpr("demo/example"); _Bool _ret_bool = z_keyexpr_is_initialized(&key); assert(_ret_bool == true); @@ -243,7 +243,7 @@ int main(int argc, char **argv) { z_sleep_s(SLEEP); - z_session_t ls1 = z_loan(s1); + z_loaned_session_t ls1 = z_loan(s1); z_owned_closure_sample_t _ret_closure_sample = z_closure(data_handler, NULL, &ls1); z_subscriber_options_t _ret_sub_opt = z_subscriber_options_default(); z_owned_subscriber_t _ret_sub = @@ -258,7 +258,7 @@ int main(int argc, char **argv) { assert(z_check(_ret_expr)); z_put_options_t _ret_put_opt = z_put_options_default(); _ret_put_opt.congestion_control = Z_CONGESTION_CONTROL_BLOCK; - z_encoding_t _ret_encoding = z_encoding_default(); + z_loaned_encoding_t _ret_encoding = z_encoding_default(); _ret_encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); _ret_put_opt.encoding = _ret_encoding; z_owned_bytes_t payload = z_bytes_encode_from_string(value); @@ -333,10 +333,10 @@ int main(int argc, char **argv) { z_sleep_s(SLEEP); - z_session_t ls2 = z_loan(s2); + z_loaned_session_t ls2 = z_loan(s2); z_owned_closure_reply_t _ret_closure_reply = z_closure(reply_handler, NULL, &ls2); z_get_options_t _ret_get_opt = z_get_options_default(); - _ret_get_opt.target = z_query_target_default(); + _ret_get_opt.target = z_loaned_query_target_default(); _ret_get_opt.consolidation = z_query_consolidation_auto(); _ret_get_opt.consolidation = z_query_consolidation_default(); _ret_get_opt.consolidation = z_query_consolidation_latest(); diff --git a/tests/z_api_attachment_test.c b/tests/z_api_attachment_test.c index 7669a3605..ebcdc6993 100644 --- a/tests/z_api_attachment_test.c +++ b/tests/z_api_attachment_test.c @@ -26,7 +26,7 @@ void writting_through_map_by_alias_read_by_get() { z_owned_bytes_map_t map = z_slice_map_new(); z_slice_map_insert_by_alias(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); z_slice_map_insert_by_alias(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); - z_bytes_t attachment = z_slice_map_as_attachment(&map); + z_loaned_bytes_t attachment = z_slice_map_as_attachment(&map); // Elements check @@ -34,20 +34,20 @@ void writting_through_map_by_alias_read_by_get() { assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); - z_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); + z_loaned_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); - z_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); + z_loaned_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); ASSERT_STR_BYTES_EQUAL("v2", a2); - z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); + z_loaned_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); z_drop(z_move(map)); } -int8_t _attachment_reader(z_slice_t key, z_slice_t value, void* ctx) { +int8_t _attachment_reader(z_loaned_slice_t key, z_loaned_slice_t value, void* ctx) { assert((size_t)ctx == 42); if (!strncmp(key.start, "k1", key.len)) { assert(!strncmp(value.start, "v1", value.len)); @@ -63,7 +63,7 @@ void writting_through_map_by_copy_read_by_iter() { z_owned_bytes_map_t map = z_slice_map_new(); z_slice_map_insert_by_copy(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); z_slice_map_insert_by_copy(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); - z_bytes_t attachment = z_slice_map_as_attachment(&map); + z_loaned_bytes_t attachment = z_slice_map_as_attachment(&map); // Elements check assert(z_slice_map_len(&map) == 2); @@ -87,29 +87,29 @@ int8_t _iteration_driver(const void* data, z_attachment_iter_body_t body, void* } void writting_no_map_read_by_get() { - z_bytes_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; + z_loaned_bytes_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; // Elements check assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); - z_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); + z_loaned_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); - z_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); + z_loaned_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); ASSERT_STR_BYTES_EQUAL("v2", a2); - z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); + z_loaned_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); } void invalid_attachment_safety() { - z_bytes_t attachment = z_attachment_null(); + z_loaned_bytes_t attachment = z_attachment_null(); assert(z_attachment_is_empty(attachment)); assert(z_attachment_len(attachment) == 0); - z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); + z_loaned_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); diff --git a/tests/z_api_double_drop_test.c b/tests/z_api_double_drop_test.c index 3fd158f12..48b5927f6 100644 --- a/tests/z_api_double_drop_test.c +++ b/tests/z_api_double_drop_test.c @@ -71,7 +71,7 @@ void test_scouting_config() { assert(!z_check(config)); } -void data_handler(const z_sample_t *sample, void *arg) {} +void data_handler(const z_loaned_sample_t *sample, void *arg) {} void test_pull_subscriber() { z_owned_config_t config = z_config_default(); @@ -99,7 +99,7 @@ void test_subscriber() { z_drop(z_move(s)); } -void query_handler(const z_query_t *query, void *context) {} +void query_handler(const z_loaned_query_t *query, void *context) {} void test_queryable() { z_owned_config_t config = z_config_default(); diff --git a/tests/z_api_keyexpr_drop_test.c b/tests/z_api_keyexpr_drop_test.c index ac81be4cd..08b77038d 100644 --- a/tests/z_api_keyexpr_drop_test.c +++ b/tests/z_api_keyexpr_drop_test.c @@ -29,14 +29,14 @@ void test_publisher() { z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); strncpy(keyexpr, "baz/quax", 256); // Update source string to ensure that the correct keyexpr z_owned_keyexpr_t pub_keyexpr = z_publisher_keyexpr(z_loan(pub)); - z_owned_str_t pub_keyexpr_str = z_keyexpr_to_string(z_loan(pub_keyexpr)); + z_owned_str_t pub_keyexpr_str = z_loaned_keyexpr_to_string(z_loan(pub_keyexpr)); assert(strcmp(z_loan(pub_keyexpr_str), "foo/bar") == 0); // Check that publisher keeps the correct keyexpr z_drop(z_move(pub_keyexpr_str)); z_drop(z_move(pub)); z_drop(z_move(s)); } -void data_handler(const z_sample_t *sample, void *arg) {} +void data_handler(const z_loaned_sample_t *sample, void *arg) {} // void test_pull_subscriber() { // z_owned_config_t config = z_config_default(); @@ -59,14 +59,14 @@ void test_subscriber() { z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); strncpy(keyexpr, "baz/quax", 256); // Update source string to ensure that the keyexpr is copied into the subscriber z_owned_keyexpr_t sub_keyexpr = z_subscriber_keyexpr(z_loan(sub)); - z_owned_str_t sub_keyexpr_str = z_keyexpr_to_string(z_loan(sub_keyexpr)); + z_owned_str_t sub_keyexpr_str = z_loaned_keyexpr_to_string(z_loan(sub_keyexpr)); assert(strcmp(z_loan(sub_keyexpr_str), "foo/bar") == 0); // Check that subscriber keeps the correct keyexpr z_drop(z_move(sub_keyexpr_str)); z_drop(z_move(sub)); z_drop(z_move(s)); } -// void query_handler(const z_query_t *query, void *context) {} +// void query_handler(const z_loaned_query_t *query, void *context) {} // void test_queryable() { // z_owned_config_t config = z_config_default(); diff --git a/tests/z_api_keyexpr_test.c b/tests/z_api_keyexpr_test.c index cb3c234b3..e62e27d09 100644 --- a/tests/z_api_keyexpr_test.c +++ b/tests/z_api_keyexpr_test.c @@ -43,7 +43,7 @@ void canonize() { assert(strcmp(keyexpr, "a/**/c") == 0); strcpy(keyexpr, "a/**/**/c"); - z_keyexpr_t key_expr_canonized = z_keyexpr_autocanonize(keyexpr); + z_loaned_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); @@ -60,9 +60,9 @@ void canonize() { } void includes() { - z_keyexpr_t nul = z_keyexpr(NULL); - z_keyexpr_t foobar = z_keyexpr("foo/bar"); - z_keyexpr_t foostar = z_keyexpr("foo/*"); + z_loaned_keyexpr_t nul = z_keyexpr(NULL); + z_loaned_keyexpr_t foobar = z_keyexpr("foo/bar"); + z_loaned_keyexpr_t foostar = z_keyexpr("foo/*"); assert(z_keyexpr_includes(foostar, foobar) == 0); assert(z_keyexpr_includes(foobar, foostar) == -1); assert(z_keyexpr_includes(nul, foobar) < -1); @@ -70,10 +70,10 @@ void includes() { } void intersects() { - z_keyexpr_t nul = z_keyexpr(NULL); - z_keyexpr_t foobar = z_keyexpr("foo/bar"); - z_keyexpr_t foostar = z_keyexpr("foo/*"); - z_keyexpr_t barstar = z_keyexpr("bar/*"); + z_loaned_keyexpr_t nul = z_keyexpr(NULL); + z_loaned_keyexpr_t foobar = z_keyexpr("foo/bar"); + z_loaned_keyexpr_t foostar = z_keyexpr("foo/*"); + z_loaned_keyexpr_t barstar = z_keyexpr("bar/*"); assert(z_keyexpr_intersects(foostar, foobar) == 0); assert(z_keyexpr_intersects(barstar, foobar) == -1); assert(z_keyexpr_intersects(nul, foobar) < -1); @@ -90,10 +90,10 @@ void undeclare() { } void relation_to() { - z_keyexpr_t nul = z_keyexpr(NULL); - z_keyexpr_t foobar = z_keyexpr("foo/bar"); - z_keyexpr_t foostar = z_keyexpr("foo/*"); - z_keyexpr_t barstar = z_keyexpr("bar/*"); + z_loaned_keyexpr_t nul = z_keyexpr(NULL); + z_loaned_keyexpr_t foobar = z_keyexpr("foo/bar"); + z_loaned_keyexpr_t foostar = z_keyexpr("foo/*"); + z_loaned_keyexpr_t barstar = z_keyexpr("bar/*"); assert(z_keyexpr_relation_to(foostar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES); assert(z_keyexpr_relation_to(foobar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS); assert(z_keyexpr_relation_to(foostar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS); diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c index 9d8df0076..3e2fed1b2 100644 --- a/tests/z_api_payload_test.c +++ b/tests/z_api_payload_test.c @@ -24,7 +24,7 @@ void test_reader() { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; uint8_t data_out[10] = {0}; - z_slice_t bytes = {.start = data, .len = 10 }; + z_loaned_slice_t bytes = {.start = data, .len = 10 }; z_owned_bytes_t payload = z_bytes_encode_from_bytes(bytes); z_bytes_reader reader; diff --git a/tests/z_api_unitinialized_check.c b/tests/z_api_unitinialized_check.c index 5a4df764e..3b6f95da0 100644 --- a/tests/z_api_unitinialized_check.c +++ b/tests/z_api_unitinialized_check.c @@ -25,6 +25,6 @@ int main(int argc, char **argv) { z_owned_keyexpr_t owned_keyexpr = z_keyexpr_new(NULL); assert(!z_check(owned_keyexpr)); - z_keyexpr_t keyexpr = z_keyexpr(NULL); + z_loaned_keyexpr_t keyexpr = z_keyexpr(NULL); assert(!z_check(keyexpr)); } diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index e0246ad01..742f2d656 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -85,9 +85,9 @@ int run_publisher() { return 0; } -void data_handler(const z_sample_t *sample, void *arg) { +void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index 63bb54f4a..a2dba9b6b 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -65,9 +65,9 @@ int run_publisher() { return 0; } -void data_handler(const z_sample_t *sample, void *arg) { +void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); @@ -83,10 +83,10 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(payload_value)); - z_slice_t v_const = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_CONST)); + z_loaned_slice_t v_const = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_slice_t v_var = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_VAR)); + z_loaned_slice_t v_var = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[val_num], v_var); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index 6d681bb49..4907af56e 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -58,9 +58,9 @@ int run_publisher() { return 0; } -void data_handler(const z_sample_t *sample, void *arg) { +void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 9ea97fe8f..7582a9e92 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -29,19 +29,19 @@ const char *const K_VAR = "k_var"; const char *const K_CONST = "k_const"; const char *const V_CONST = "v const"; -void query_handler(const z_query_t *query, void *context) { +void query_handler(const z_loaned_query_t *query, void *context) { static int value_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_slice_t pred = z_query_parameters(query); - z_value_t payload_value = z_query_value(query); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); + z_loaned_slice_t pred = z_query_parameters(query); + z_loaned_value_t payload_value = z_query_value(query); - z_bytes_t attachment = z_query_attachment(query); + z_loaned_bytes_t attachment = z_query_attachment(query); - z_slice_t v_const = z_attachment_get(attachment, z_slice_from_str(K_CONST)); + z_loaned_slice_t v_const = z_attachment_get(attachment, z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_slice_t v_var = z_attachment_get(attachment, z_slice_from_str(K_VAR)); + z_loaned_slice_t v_var = z_attachment_get(attachment, z_slice_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[value_num], v_var); z_owned_bytes_map_t map = z_slice_map_new(); @@ -108,8 +108,8 @@ int run_get() { for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { assert(z_reply_is_ok(&reply)); - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(&reply); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { @@ -118,7 +118,7 @@ int run_get() { exit(-1); } - z_slice_t v_const = z_attachment_get(z_sample_attachment(&sample), z_slice_from_str(K_CONST)); + z_loaned_slice_t v_const = z_attachment_get(z_sample_attachment(&sample), z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index b63686ecb..d22d5b6ab 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -25,12 +25,12 @@ const char *const keyexpr = "test/key"; const char *const values[] = {"test_value_1", "test_value_2", "test_value_3"}; const size_t values_count = sizeof(values) / sizeof(values[0]); -void query_handler(const z_query_t *query, void *context) { +void query_handler(const z_loaned_query_t *query, void *context) { static int value_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_slice_t pred = z_query_parameters(query); - z_value_t payload_value = z_query_value(query); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); + z_loaned_slice_t pred = z_query_parameters(query); + z_loaned_value_t payload_value = z_query_value(query); z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); @@ -84,8 +84,8 @@ int run_get() { for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { assert(z_reply_is_ok(&reply)); - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(&reply); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { From 044757ad66773390247f90c045f500e54f850fc8 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 26 Apr 2024 16:50:08 +0200 Subject: [PATCH 063/377] automated macro-function generation --- build-resources/opaque-types/src/lib.rs | 4 +- build.rs | 456 +++++++++++++++++ include/zenoh_commons.h | 36 +- include/zenoh_macros.h | 646 +++++++++++++----------- src/commons.rs | 19 +- src/publisher.rs | 2 +- 6 files changed, 843 insertions(+), 320 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 512ea8b00..0d870a510 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -70,8 +70,8 @@ get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_loaned_ /// An owned sample. /// /// This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. -/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -get_opaque_type_data!(Option, zc_owned_sample_t); +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `z_sample_drop`. +get_opaque_type_data!(Option, z_owned_sample_t); get_opaque_type_data!(Sample, z_loaned_sample_t); /// A reader for payload data. diff --git a/build.rs b/build.rs index 72fd1ab4c..4d06c44e3 100644 --- a/build.rs +++ b/build.rs @@ -37,6 +37,7 @@ fn main() { .expect("Unable to generate bindings") .write_to_file(GENERATION_PATH); + create_generics_header(GENERATION_PATH, "include/zenoh_macros.h"); configure(); let split_guide = SplitGuide::from_yaml(SPLITGUIDE_PATH); split_bindings(&split_guide).unwrap(); @@ -732,3 +733,458 @@ impl<'a> Iterator for Tokenizer<'a> { } } } + +#[derive(Clone, Debug)] +pub struct FuncArg { + typename: String, + cv: String, + name: String, +} + +impl FuncArg { + pub fn new(typename: &str, cv: &str, name: &str) -> Self { + FuncArg { + typename: typename.to_owned(), + cv: cv.to_owned(), + name: name.to_owned(), + } + } +} +#[derive(Clone, Debug)] +pub struct FunctionSignature { + return_type: String, + func_name: String, + arg_type_and_name: Vec, +} + +pub fn create_generics_header(path_in: &str, path_out: &str) { + let mut file_out = std::fs::File::options() + .read(false) + .create(false) + .write(true) + .truncate(true) + .open(path_out) + .unwrap(); + + let header = "#pragma once +// clang-format off +#ifndef __cplusplus + +"; + file_out.write(header.as_bytes()).unwrap(); + + let type_name_to_loan_func = find_loan_functions(path_in); + let out = generate_generic_loan_c(&type_name_to_loan_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_loan_mut_func = find_loan_mut_functions(path_in); + let out = generate_generic_loan_mut_c(&type_name_to_loan_mut_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_drop_func = find_drop_functions(path_in); + let out = generate_generic_drop_c(&type_name_to_drop_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_null_func = find_null_functions(path_in); + let out = generate_generic_null_c(&type_name_to_null_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_check_func = find_check_functions(path_in); + let out = generate_generic_check_c(&type_name_to_check_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_call_func = find_call_functions(path_in); + let out = generate_generic_call_c(&type_name_to_call_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_closure_c(&type_name_to_call_func); + file_out.write(out.as_bytes()).unwrap(); + + file_out + .write("\n#else // #ifndef __cplusplus\n".as_bytes()) + .unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_loan_cpp(&type_name_to_loan_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_loan_mut_cpp(&type_name_to_loan_mut_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_drop_cpp(&type_name_to_drop_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_null_cpp(&type_name_to_null_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_check_cpp(&type_name_to_check_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_call_cpp(&type_name_to_call_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_closure_cpp(&type_name_to_call_func); + file_out.write(out.as_bytes()).unwrap(); + + file_out + .write("\n#endif // #ifndef __cplusplus".as_bytes()) + .unwrap(); +} + +pub fn find_loan_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"const struct (\w+) \*(\w+)_loan\(const struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [return_type, func_name, arg_type, arg_name]) in + re.captures_iter(&bindings).map(|c| c.extract()) + { + let f = FunctionSignature { + return_type: return_type.to_string(), + func_name: func_name.to_string() + "_loan", + arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_loan_mut_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"struct (\w+) \*(\w+)_loan_mut\(struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [return_type, func_name, arg_type, arg_name]) in + re.captures_iter(&bindings).map(|c| c.extract()) + { + let f = FunctionSignature { + return_type: return_type.to_string(), + func_name: func_name.to_string() + "_loan_mut", + arg_type_and_name: [FuncArg::new(arg_type, "", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_drop_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"(\w+)_drop\(struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { + let f = FunctionSignature { + return_type: "void".to_string(), + func_name: func_name.to_string() + "_drop", + arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_null_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"(\w+)_null\(struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { + let f = FunctionSignature { + return_type: "void".to_string(), + func_name: func_name.to_string() + "_null", + arg_type_and_name: [FuncArg::new(arg_type, "", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_check_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"bool (\w+)_check\(const struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { + let f = FunctionSignature { + return_type: "bool".to_string(), + func_name: func_name.to_string() + "_check", + arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_call_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new( + r"(\w+) (\w+)_call\(const struct (\w+) \*(\w+),\s+(\w*)\s*struct (\w+) \*(\w+)\);", + ) + .unwrap(); + let mut res = HashMap::::new(); + + for (_, [return_type, func_name, closure_type, closure_name, arg_cv, arg_type, arg_name]) in + re.captures_iter(&bindings).map(|c| c.extract()) + { + let f = FunctionSignature { + return_type: return_type.to_string(), + func_name: func_name.to_string() + "_call", + arg_type_and_name: [ + FuncArg::new(closure_type, "const", closure_name), + FuncArg::new(arg_type, arg_cv, arg_name), + ] + .to_vec(), + }; + res.insert(closure_type.to_string(), f); + } + res +} + +pub fn generate_generic_loan_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_loan(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} : {func_name}"); + } + out += " \\\n"; + out += " )(&x)"; + out +} + +pub fn generate_generic_loan_mut_c( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "#define z_loan_mut(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} : {func_name}"); + } + out += " \\\n"; + out += " )(&x)"; + out +} + +pub fn generate_generic_drop_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_drop(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ",\\\n"; + out += &format!(" {owned_type} * : {func_name}"); + } + out += " \\\n"; + out += " )(x)"; + out +} + +pub fn generate_generic_null_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_null(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} * : {func_name}"); + } + out += " \\\n"; + out += " )(x)"; + out +} + +pub fn generate_generic_check_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_check(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} : {func_name}"); + } + out += " \\\n"; + out += " )(&x)"; + out +} + +pub fn generate_generic_call_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_call(x, ...) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} : {func_name}"); + } + out += " \\\n"; + out += " )(&x, __VA_ARGS__)"; + + out +} + +pub fn generate_generic_closure_c( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "#define z_closure(x, callback, dropper, ctx) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, _func) in owned_type_to_fun { + out += ", \\\n"; + out += &format!( +" {owned_type} * : {{ x->context = (void*)ctx; x->call = callback; x->drop = droper; }}"); + } + out += " \\\n"; + out += " )"; + + out +} + +pub fn generate_generic_loan_cpp(owned_type_to_fun: &HashMap) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline const {return_type}* z_loan({cv} {arg_type}* {arg_name}) {{ return {func_name}({arg_name}); }};"); + } + out +} + +pub fn generate_generic_loan_mut_cpp( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline {return_type}* z_loan_mut({cv} {arg_type}& {arg_name}) {{ return {func_name}(&{arg_name}); }};"); + } + out +} + +pub fn generate_generic_drop_cpp(owned_type_to_fun: &HashMap) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline {return_type} z_drop({cv} {arg_type}* {arg_name}) {{ return {func_name}({arg_name}); }};"); + } + out +} + +pub fn generate_generic_null_cpp(owned_type_to_fun: &HashMap) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline {return_type} z_null({cv} {arg_type}* {arg_name}) {{ return {func_name}({arg_name}); }};"); + } + out +} + +pub fn generate_generic_check_cpp( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline {return_type} z_check({cv} {arg_type}& {arg_name}) {{ return {func_name}(&{arg_name}); }};"); + } + out +} + +pub fn generate_generic_call_cpp(owned_type_to_fun: &HashMap) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let closure_cv = &func.arg_type_and_name[0].cv; + let closure_name = &func.arg_type_and_name[0].name; + let closure_type = &func.arg_type_and_name[0].typename; + let arg_cv = &func.arg_type_and_name[1].cv; + let arg_name = &func.arg_type_and_name[1].name; + let arg_type = &func.arg_type_and_name[1].typename; + out += "\n"; + out += &format!("inline {return_type} z_call({closure_cv} {closure_type}& {closure_name}, {arg_cv} {arg_type}* {arg_name}) {{ + return {func_name}(&{closure_name}, {arg_name}); +}};"); + } + out +} + +pub fn generate_generic_closure_cpp( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let return_type = &func.return_type; + let closure_name = &func.arg_type_and_name[0].name; + let closure_type = &func.arg_type_and_name[0].typename; + let arg_cv = &func.arg_type_and_name[1].cv; + let arg_type = &func.arg_type_and_name[1].typename; + out += "\n"; + out += &format!( + "inline void z_closure( + {closure_type}* {closure_name}, + {return_type} (*call)({arg_cv} {arg_type}*, void*), + void (*drop)(void*), + void *context) {{ + {closure_name}->context = context; + {closure_name}->drop = drop; + {closure_name}->call = call; +}};" + ); + } + out +} diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 35429b0d6..463f37575 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -675,11 +675,11 @@ typedef struct z_owned_reply_channel_t { * An owned sample. * * This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `z_sample_drop`. */ -typedef struct ALIGN(8) zc_owned_sample_t { +typedef struct ALIGN(8) z_owned_sample_t { uint8_t _0[240]; -} zc_owned_sample_t; +} z_owned_sample_t; typedef struct z_owned_scouting_config_t { struct z_owned_config_t _config; unsigned long zc_timeout_ms; @@ -1558,7 +1558,7 @@ ZENOHC_API void z_publisher_options_default(struct z_publisher_options_t *this_) * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. * * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - `z_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher * - constructed from a `zc_owned_shmbuf_t` * * The payload and all owned options fields are consumed upon function return. @@ -1823,17 +1823,21 @@ const struct z_loaned_bytes_t *z_sample_attachment(const struct z_loaned_sample_ /** * Returns `true` if `sample` is valid. * - * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * Note that there exist no fallinle constructors for `z_owned_sample_t`, so validity is always guaranteed * unless the value has been dropped already. */ ZENOHC_API -bool z_sample_check(const struct zc_owned_sample_t *sample); +bool z_sample_check(const struct z_owned_sample_t *sample); /** * Clone a sample in the cheapest way available. */ -ZENOHC_API void z_sample_clone(const struct z_loaned_sample_t *src, struct zc_owned_sample_t *dst); +ZENOHC_API void z_sample_clone(const struct z_loaned_sample_t *src, struct z_owned_sample_t *dst); ZENOHC_API enum z_congestion_control_t z_sample_congestion_control(const struct z_loaned_sample_t *sample); +/** + * Destroy the sample. + */ +ZENOHC_API void z_sample_drop(struct z_owned_sample_t *sample); /** * The encoding of the payload. */ @@ -1851,6 +1855,13 @@ const struct z_loaned_keyexpr_t *z_sample_keyexpr(const struct z_loaned_sample_t * The sample's kind (put or delete). */ ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_loaned_sample_t *sample); +/** + * Borrow the sample, allowing calling its accessor methods. + * + * Calling this function using a dropped sample is undefined behaviour. + */ +ZENOHC_API const struct z_loaned_sample_t *z_sample_loan(const struct z_owned_sample_t *sample); +ZENOHC_API void z_sample_null(struct z_owned_sample_t *sample); /** * The sample's data, the return value aliases the sample. * @@ -2363,17 +2374,6 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); */ ZENOHC_API struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); -/** - * Destroy the sample. - */ -ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); -/** - * Borrow the sample, allowing calling its accessor methods. - * - * Calling this function using a dropped sample is undefined behaviour. - */ -ZENOHC_API const struct z_loaned_sample_t *zc_sample_loan(const struct zc_owned_sample_t *sample); -ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 7b6bbe214..c4229023b 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -1,312 +1,382 @@ #pragma once - +// clang-format off #ifndef __cplusplus -// clang-format off #define z_loan(x) \ - _Generic((x), z_owned_session_t : z_session_loan, \ - z_owned_keyexpr_t : z_keyexpr_loan, \ - z_owned_config_t : z_config_loan, \ - z_owned_publisher_t : z_publisher_loan, \ - z_owned_subscriber_t : z_subscriber_loan, \ - z_owned_encoding_t : z_encoding_loan, \ - z_owned_hello_t : z_hello_loan, \ - z_owned_str_t : z_str_loan, \ - z_owned_query_t : z_query_loan, \ - z_owned_slice_map_t : z_slice_map_loan, \ - z_owned_slice_t : z_slice_loan, \ - z_owned_bytes_t : z_bytes_loan, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ - z_owned_reply_t : z_reply_loan, \ - z_owned_mutex_t : z_mutex_loan, \ - z_loaned_condvar_t : z_condvar_loan, \ - z_owned_bytes_reader_t : z_bytes_reader_loan \ - )(&x) + _Generic((x), \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_loan, \ + z_owned_sample_t : z_sample_loan, \ + z_view_slice_t : z_view_slice_loan, \ + z_owned_bytes_t : z_bytes_loan, \ + z_owned_publisher_t : z_publisher_loan, \ + z_owned_slice_t : z_slice_loan, \ + z_owned_slice_map_t : z_slice_map_loan, \ + z_owned_keyexpr_t : z_keyexpr_loan, \ + z_owned_encoding_t : z_encoding_loan, \ + z_owned_str_t : z_str_loan, \ + z_owned_session_t : z_session_loan, \ + z_owned_hello_t : z_hello_loan, \ + z_view_str_t : z_view_str_loan, \ + z_owned_query_t : z_query_loan, \ + z_owned_subscriber_t : z_subscriber_loan, \ + z_view_keyexpr_t : z_view_keyexpr_loan, \ + z_owned_str_array_t : z_str_array_loan, \ + z_owned_condvar_t : z_condvar_loan, \ + z_owned_config_t : z_config_loan, \ + z_owned_bytes_reader_t : z_bytes_reader_loan \ + )(&x) + +#define z_loan_mut(x) \ + _Generic((x), \ + z_owned_condvar_t : z_condvar_loan_mut, \ + z_owned_bytes_reader_t : z_bytes_reader_loan_mut, \ + z_owned_config_t : z_config_loan_mut, \ + z_owned_slice_map_t : z_slice_map_loan_mut, \ + z_owned_mutex_t : z_mutex_loan_mut \ + )(&x) #define z_drop(x) \ - _Generic((x), z_owned_session_t * : z_close, \ - z_owned_publisher_t * : z_undeclare_publisher, \ - z_owned_keyexpr_t * : z_keyexpr_drop, \ - z_owned_config_t * : z_config_drop, \ - z_owned_scouting_config_t * : z_scouting_config_drop, \ - z_owned_subscriber_t * : z_undeclare_subscriber, \ - z_owned_queryable_t * : z_undeclare_queryable, \ - z_owned_encoding_t * : z_encoding_drop, \ - z_owned_reply_t * : z_reply_drop, \ - z_owned_hello_t * : z_hello_drop, \ - z_owned_str_t * : z_str_drop, \ - z_owned_query_t * : z_query_drop, \ - z_owned_closure_sample_t * : z_closure_sample_drop, \ - z_owned_closure_query_t * : z_closure_query_drop, \ - z_owned_closure_reply_t * : z_closure_reply_drop, \ - z_owned_closure_hello_t * : z_closure_hello_drop, \ - z_owned_closure_zid_t * : z_closure_zid_drop, \ - zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop, \ - z_owned_reply_channel_closure_t * : z_reply_channel_closure_drop, \ - z_owned_query_channel_closure_t * : z_query_channel_closure_drop, \ - z_owned_reply_channel_t * : z_reply_channel_drop, \ - z_owned_query_channel_t * : z_query_channel_drop, \ - z_owned_slice_map_t * : z_slice_map_drop, \ - z_owned_slice_t * : z_slice_drop, \ - zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ - ze_owned_publication_cache_t * : ze_undeclare_publication_cache, \ - ze_owned_querying_subscriber_t * : ze_undeclare_querying_subscriber, \ - z_owned_bytes_t * : z_bytes_drop, \ - z_owned_bytes_reader_t * : z_bytes_reader_drop, \ - z_owned_mutex_t * : z_mutex_drop, \ - z_owned_condvar_t * : z_condvar_drop \ - )(x) + _Generic((x),\ + z_owned_closure_query_t * : z_closure_query_drop,\ + z_owned_closure_zid_t * : z_closure_zid_drop,\ + z_owned_slice_map_t * : z_slice_map_drop,\ + zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop,\ + z_owned_reply_t * : z_reply_drop,\ + z_owned_slice_t * : z_slice_drop,\ + z_owned_closure_sample_t * : z_closure_sample_drop,\ + z_owned_bytes_t * : z_bytes_drop,\ + z_owned_condvar_t * : z_condvar_drop,\ + z_owned_sample_t * : z_sample_drop,\ + z_owned_query_channel_t * : z_query_channel_drop,\ + z_owned_query_channel_closure_t * : z_query_channel_closure_drop,\ + z_owned_closure_reply_t * : z_closure_reply_drop,\ + z_owned_reply_channel_t * : z_reply_channel_drop,\ + z_owned_str_t * : z_str_drop,\ + z_owned_closure_owned_query_t * : z_closure_owned_query_drop,\ + z_owned_config_t * : z_config_drop,\ + z_owned_mutex_t * : z_mutex_drop,\ + z_owned_bytes_reader_t * : z_bytes_reader_drop,\ + z_owned_str_array_t * : z_str_array_drop,\ + z_owned_keyexpr_t * : z_keyexpr_drop,\ + z_owned_scouting_config_t * : z_scouting_config_drop,\ + z_owned_closure_hello_t * : z_closure_hello_drop,\ + z_owned_encoding_t * : z_encoding_drop,\ + z_owned_hello_t * : z_hello_drop,\ + z_owned_query_t * : z_query_drop,\ + z_owned_reply_channel_closure_t * : z_reply_channel_closure_drop \ + )(x) -#define z_null(x) (*x = \ - _Generic((x), z_owned_session_t * : z_session_null, \ - z_owned_publisher_t * : z_publisher_null, \ - z_owned_keyexpr_t * : z_keyexpr_null, \ - z_owned_config_t * : z_config_null, \ - z_owned_scouting_config_t * : z_scouting_config_null, \ - z_owned_subscriber_t * : z_subscriber_null, \ - z_owned_queryable_t * : z_queryable_null, \ - z_owned_encoding_t * : z_encoding_null, \ - z_owned_reply_t * : z_reply_null, \ - z_owned_hello_t * : z_hello_null, \ - z_owned_str_t * : z_str_null, \ - z_owned_query_t * : z_query_null, \ - z_owned_closure_sample_t * : z_closure_sample_null, \ - z_owned_closure_query_t * : z_closure_query_null, \ - z_owned_closure_reply_t * : z_closure_reply_null, \ - z_owned_closure_hello_t * : z_closure_hello_null, \ - z_owned_closure_zid_t * : z_closure_zid_null, \ - zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ - z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ - z_owned_reply_channel_t * : z_reply_channel_null, \ - z_owned_slice_map_t * : z_slice_map_null, \ - z_owned_bytes_t * : z_bytes_null, \ - z_owned_slice_t * : z_slice_null, \ - ze_owned_publication_cache_t * : ze_publication_cache_null, \ - zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ - z_owned_bytes_reader_t * : z_bytes_reader_null, \ - z_owned_mutex_t * : z_mutex_null, \ - z_owned_condvar_t * : z_condvar_null, \ - z_owned_task_t * : z_task_null \ - )()) +#define z_null(x) \ + _Generic((x), \ + z_owned_slice_map_t * : z_slice_map_null, \ + z_owned_query_t * : z_query_null, \ + z_owned_keyexpr_t * : z_keyexpr_null, \ + z_view_str_t * : z_view_str_null, \ + z_view_slice_t * : z_view_slice_null, \ + z_owned_str_t * : z_str_null, \ + z_owned_scouting_config_t * : z_scouting_config_null, \ + z_owned_condvar_t * : z_condvar_null, \ + z_owned_encoding_t * : z_encoding_null, \ + z_owned_queryable_t * : z_queryable_null, \ + z_owned_reply_t * : z_reply_null, \ + z_owned_mutex_t * : z_mutex_null, \ + z_owned_config_t * : z_config_null, \ + z_owned_bytes_reader_t * : z_bytes_reader_null, \ + z_owned_hello_t * : z_hello_null, \ + z_owned_sample_t * : z_sample_null, \ + z_owned_subscriber_t * : z_subscriber_null, \ + z_owned_bytes_t * : z_bytes_null, \ + z_owned_publisher_t * : z_publisher_null, \ + z_owned_session_t * : z_session_null, \ + z_owned_task_t * : z_task_null, \ + z_owned_slice_t * : z_slice_null, \ + z_view_keyexpr_t * : z_view_keyexpr_null, \ + zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ + ze_owned_querying_subscriber_t * : ze_querying_subscriber_null, \ + ze_owned_publication_cache_t * : ze_publication_cache_null \ + )(x) #define z_check(x) \ - _Generic((x), z_owned_session_t : z_session_check, \ - z_owned_publisher_t : z_publisher_check, \ - z_owned_keyexpr_t : z_keyexpr_check, \ - z_owned_config_t : z_config_check, \ - z_owned_scouting_config_t : z_scouting_config_check, \ - z_owned_subscriber_t : z_subscriber_check, \ - z_owned_queryable_t : z_queryable_check, \ - z_owned_encoding_t : z_encoding_check, \ - z_owned_reply_t : z_reply_check, \ - z_owned_hello_t : z_hello_check, \ - z_owned_query_t : z_query_check, \ - z_owned_str_t : z_str_check, \ - z_owned_slice_map_t : z_slice_map_check, \ - z_owned_slice_t: z_slice_check, \ - z_owned_bytes_t : z_bytes_check, \ - zc_owned_liveliness_token_t : zc_liveliness_token_check, \ - ze_owned_publication_cache_t : ze_publication_cache_check, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_check,\ - z_owned_mutex_t : z_mutex_check, \ - z_owned_condvar_t : z_condvar_check, \ - z_owned_task_t : z_task_check \ - )(&x) + _Generic((x), \ + z_view_keyexpr_t : z_view_keyexpr_check, \ + z_owned_bytes_t : z_bytes_check, \ + z_owned_query_t : z_query_check, \ + z_owned_scouting_config_t : z_scouting_config_check, \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_check, \ + z_owned_sample_t : z_sample_check, \ + z_owned_keyexpr_t : z_keyexpr_check, \ + z_owned_str_array_t : z_str_array_check, \ + z_owned_hello_t : z_hello_check, \ + z_owned_task_t : z_task_check, \ + z_owned_reply_t : z_reply_check, \ + z_view_slice_t : z_view_slice_check, \ + ze_owned_publication_cache_t : ze_publication_cache_check, \ + zc_owned_liveliness_token_t : zc_liveliness_token_check, \ + z_owned_queryable_t : z_queryable_check, \ + z_owned_condvar_t : z_condvar_check, \ + z_owned_str_t : z_str_check, \ + z_owned_config_t : z_config_check, \ + z_owned_bytes_reader_t : z_bytes_reader_check, \ + z_owned_mutex_t : z_mutex_check, \ + z_owned_publisher_t : z_publisher_check, \ + z_owned_slice_t : z_owned_slice_check, \ + z_owned_session_t : z_session_check, \ + z_owned_encoding_t : z_encoding_check, \ + z_owned_slice_map_t : z_slice_map_check, \ + z_owned_subscriber_t : z_subscriber_check \ + )(&x) #define z_call(x, ...) \ - _Generic((x), z_owned_closure_sample_t : z_closure_sample_call, \ - z_owned_closure_query_t : z_closure_query_call, \ - z_owned_closure_owned_query_t : z_closure_owned_query_call, \ - z_owned_closure_reply_t : z_closure_reply_call, \ - z_owned_closure_hello_t : z_closure_hello_call, \ - z_owned_closure_zid_t : z_closure_zid_call, \ - zcu_owned_closure_matching_status_t : zcu_closure_matching_status_call, \ - z_owned_reply_channel_closure_t : z_reply_channel_closure_call, \ - z_owned_query_channel_closure_t : z_query_channel_closure_call \ - ) (&x, __VA_ARGS__) -// clang-format on - -#define _z_closure_overloader(callback, droper, ctx, ...) \ - { .context = (void*)ctx, .call = callback, .drop = droper } -#define z_closure(...) _z_closure_overloader(__VA_ARGS__, NULL, NULL) -#define z_move(x) (&x) + _Generic((x), \ + z_owned_closure_query_t : z_closure_query_call, \ + z_owned_closure_hello_t : z_closure_hello_call, \ + z_owned_closure_reply_t : z_closure_reply_call, \ + z_owned_closure_sample_t : z_closure_sample_call, \ + z_owned_closure_owned_query_t : z_closure_owned_query_call, \ + z_owned_closure_zid_t : z_closure_zid_call, \ + zcu_owned_closure_matching_status_t : zcu_closure_matching_status_call, \ + z_owned_query_channel_closure_t : z_query_channel_closure_call, \ + z_owned_reply_channel_closure_t : z_reply_channel_closure_call \ + )(&x, __VA_ARGS__) +#define z_closure(x, callback, dropper, ctx) \ + _Generic((x), \ + z_owned_closure_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_hello_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_reply_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_sample_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_owned_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_zid_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + zcu_owned_closure_matching_status_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_query_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_reply_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; } \ + ) #else // #ifndef __cplusplus -// clang-format off -template struct zenoh_loan_type { typedef T type; }; -template inline typename zenoh_loan_type::type z_loan(const T&); -template<> struct zenoh_loan_type{ typedef z_loaned_session_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_keyexpr_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_config_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_publisher_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_subscriber_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_query_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_encoding_t type; }; -template<> struct zenoh_loan_type{ typedef z_hello_t type; }; -template<> struct zenoh_loan_type{ typedef const char* type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_bytes_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_bytes_reader_t type; }; -template<> struct zenoh_loan_type{ typedef ze_loaned_querying_subscriber_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_slice_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_slice_map_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_mutex_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_condvar_t type; }; -template<> inline z_loaned_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } -template<> inline z_loaned_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keyexpr_loan(&x); } -template<> inline z_loaned_config_t z_loan(const z_owned_config_t& x) { return z_config_loan(&x); } -template<> inline z_loaned_publisher_t z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } -template<> inline z_loaned_subscriber_t z_loan(const z_owned_subscriber_t& x) { return z_subscriber_loan(&x); } -template<> inline z_loaned_encoding_t z_loan(const z_owned_encoding_t& x) { return z_encoding_loan(&x); } -template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } -template<> inline z_loaned_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } -template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } -template<> inline z_loaned_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } -template<> inline z_loaned_bytes_reader_t z_loan(const z_owned_bytes_reader_t& x) { return z_bytes_reader_loan(&x); } -template<> inline ze_loaned_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } -template<> inline z_loaned_slice_t z_loan(const z_owned_slice_t& x) { return z_slice_loan(&x); } -template<> inline z_loaned_slice_map_t z_loan(const z_owned_slice_map_t& x) { return z_slice_map_loan(&x); } -template<> inline z_loaned_mutex_t z_loan(const z_owned_mutex_t& x) { return z_mutex_loan(&x); } -template<> inline z_loaned_condvar_t z_loan(const z_owned_condvar_t& x) { return z_condvar_loan(&x); } +inline const ze_loaned_querying_subscriber_t* z_loan(const ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_loan(this_); }; +inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* sample) { return z_sample_loan(sample); }; +inline const z_loaned_slice_t* z_loan(const z_view_slice_t* this_) { return z_view_slice_loan(this_); }; +inline const z_loaned_bytes_t* z_loan(const z_owned_bytes_t* payload) { return z_bytes_loan(payload); }; +inline const z_loaned_publisher_t* z_loan(const z_owned_publisher_t* this_) { return z_publisher_loan(this_); }; +inline const z_loaned_slice_t* z_loan(const z_owned_slice_t* this_) { return z_slice_loan(this_); }; +inline const z_loaned_slice_map_t* z_loan(const z_owned_slice_map_t* this_) { return z_slice_map_loan(this_); }; +inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t* key_expr) { return z_keyexpr_loan(key_expr); }; +inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* encoding) { return z_encoding_loan(encoding); }; +inline const z_loaned_str_t* z_loan(const z_owned_str_t* this_) { return z_str_loan(this_); }; +inline const z_loaned_session_t* z_loan(const z_owned_session_t* this_) { return z_session_loan(this_); }; +inline const z_hello_t* z_loan(const z_owned_hello_t* hello) { return z_hello_loan(hello); }; +inline const z_loaned_str_t* z_loan(const z_view_str_t* this_) { return z_view_str_loan(this_); }; +inline const z_loaned_query_t* z_loan(const z_owned_query_t* this_) { return z_query_loan(this_); }; +inline const z_loaned_subscriber_t* z_loan(const z_owned_subscriber_t* this_) { return z_subscriber_loan(this_); }; +inline const z_loaned_keyexpr_t* z_loan(const z_view_keyexpr_t* key_expr) { return z_view_keyexpr_loan(key_expr); }; +inline const z_str_array_t* z_loan(const z_owned_str_array_t* strs) { return z_str_array_loan(strs); }; +inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t* this_) { return z_condvar_loan(this_); }; +inline const z_loaned_config_t* z_loan(const z_owned_config_t* this_) { return z_config_loan(this_); }; +inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t* reader) { return z_bytes_reader_loan(reader); }; + + +inline z_loaned_condvar_t* z_loan_mut( z_owned_condvar_t& this_) { return z_condvar_loan_mut(&this_); }; +inline z_loaned_bytes_reader_t* z_loan_mut( z_owned_bytes_reader_t& reader) { return z_bytes_reader_loan_mut(&reader); }; +inline z_loaned_config_t* z_loan_mut( z_owned_config_t& this_) { return z_config_loan_mut(&this_); }; +inline z_loaned_slice_map_t* z_loan_mut( z_owned_slice_map_t& this_) { return z_slice_map_loan_mut(&this_); }; +inline z_loaned_mutex_t* z_loan_mut( z_owned_mutex_t& this_) { return z_mutex_loan_mut(&this_); }; + + +inline void z_drop(const z_owned_closure_query_t* closure) { return z_closure_query_drop(closure); }; +inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; +inline void z_drop(const z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; +inline void z_drop(const zcu_owned_closure_matching_status_t* closure) { return zcu_closure_matching_status_drop(closure); }; +inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; +inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; +inline void z_drop(const z_owned_closure_sample_t* closure) { return z_closure_sample_drop(closure); }; +inline void z_drop(const z_owned_bytes_t* this_) { return z_bytes_drop(this_); }; +inline void z_drop(const z_owned_condvar_t* this_) { return z_condvar_drop(this_); }; +inline void z_drop(const z_owned_sample_t* sample) { return z_sample_drop(sample); }; +inline void z_drop(const z_owned_query_channel_t* channel) { return z_query_channel_drop(channel); }; +inline void z_drop(const z_owned_query_channel_closure_t* closure) { return z_query_channel_closure_drop(closure); }; +inline void z_drop(const z_owned_closure_reply_t* closure) { return z_closure_reply_drop(closure); }; +inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_channel_drop(channel); }; +inline void z_drop(const z_owned_str_t* this_) { return z_str_drop(this_); }; +inline void z_drop(const z_owned_closure_owned_query_t* closure) { return z_closure_owned_query_drop(closure); }; +inline void z_drop(const z_owned_config_t* config) { return z_config_drop(config); }; +inline void z_drop(const z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; +inline void z_drop(const z_owned_bytes_reader_t* this_) { return z_bytes_reader_drop(this_); }; +inline void z_drop(const z_owned_str_array_t* strs) { return z_str_array_drop(strs); }; +inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; +inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; +inline void z_drop(const z_owned_closure_hello_t* closure) { return z_closure_hello_drop(closure); }; +inline void z_drop(const z_owned_encoding_t* encoding) { return z_encoding_drop(encoding); }; +inline void z_drop(const z_owned_hello_t* hello) { return z_hello_drop(hello); }; +inline void z_drop(const z_owned_query_t* this_) { return z_query_drop(this_); }; +inline void z_drop(const z_owned_reply_channel_closure_t* closure) { return z_reply_channel_closure_drop(closure); }; -template struct zenoh_drop_type { typedef T type; }; -template inline typename zenoh_drop_type::type z_drop(T*); -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; +inline void z_null( z_owned_query_t* this_) { return z_query_null(this_); }; +inline void z_null( z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; +inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; +inline void z_null( z_view_slice_t* this_) { return z_view_slice_null(this_); }; +inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; +inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; +inline void z_null( z_owned_condvar_t* this_) { return z_condvar_null(this_); }; +inline void z_null( z_owned_encoding_t* encoding) { return z_encoding_null(encoding); }; +inline void z_null( z_owned_queryable_t* this_) { return z_queryable_null(this_); }; +inline void z_null( z_owned_reply_t* this_) { return z_reply_null(this_); }; +inline void z_null( z_owned_mutex_t* this_) { return z_mutex_null(this_); }; +inline void z_null( z_owned_config_t* this_) { return z_config_null(this_); }; +inline void z_null( z_owned_bytes_reader_t* this_) { return z_bytes_reader_null(this_); }; +inline void z_null( z_owned_hello_t* this_) { return z_hello_null(this_); }; +inline void z_null( z_owned_sample_t* sample) { return z_sample_null(sample); }; +inline void z_null( z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; +inline void z_null( z_owned_bytes_t* this_) { return z_bytes_null(this_); }; +inline void z_null( z_owned_publisher_t* this_) { return z_publisher_null(this_); }; +inline void z_null( z_owned_session_t* this_) { return z_session_null(this_); }; +inline void z_null( z_owned_task_t* this_) { return z_task_null(this_); }; +inline void z_null( z_owned_slice_t* this_) { return z_slice_null(this_); }; +inline void z_null( z_view_keyexpr_t* this_) { return z_view_keyexpr_null(this_); }; +inline void z_null( zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_null(this_); }; +inline void z_null( ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_null(this_); }; +inline void z_null( ze_owned_publication_cache_t* this_) { return ze_publication_cache_null(this_); }; -template<> inline int8_t z_drop(z_owned_session_t* v) { return z_close(v); } -template<> inline int8_t z_drop(z_owned_publisher_t* v) { return z_undeclare_publisher(v); } -template<> inline void z_drop(z_owned_keyexpr_t* v) { z_keyexpr_drop(v); } -template<> inline void z_drop(z_owned_config_t* v) { z_config_drop(v); } -template<> inline void z_drop(z_owned_scouting_config_t* v) { z_scouting_config_drop(v); } -template<> inline int8_t z_drop(z_owned_subscriber_t* v) { return z_undeclare_subscriber(v); } -template<> inline int8_t z_drop(z_owned_queryable_t* v) { return z_undeclare_queryable(v); } -template<> inline void z_drop(z_owned_encoding_t* v) { z_encoding_drop(v); } -template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } -template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } -template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } -template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } -template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } -template<> inline void z_drop(z_owned_bytes_reader_t* v) { z_bytes_reader_drop(v); } -template<> inline void z_drop(z_owned_closure_sample_t* v) { z_closure_sample_drop(v); } -template<> inline void z_drop(z_owned_closure_query_t* v) { z_closure_query_drop(v); } -template<> inline void z_drop(z_owned_closure_reply_t* v) { z_closure_reply_drop(v); } -template<> inline void z_drop(z_owned_closure_hello_t* v) { z_closure_hello_drop(v); } -template<> inline void z_drop(z_owned_closure_zid_t* v) { z_closure_zid_drop(v); } -template<> inline void z_drop(zcu_owned_closure_matching_status_t* v) { zcu_closure_matching_status_drop(v); } -template<> inline void z_drop(z_owned_reply_channel_closure_t* v) { z_reply_channel_closure_drop(v); } -template<> inline void z_drop(z_owned_reply_channel_t* v) { z_reply_channel_drop(v); } -template<> inline void z_drop(z_owned_slice_t* v) { z_slice_drop(v); } -template<> inline void z_drop(z_owned_slice_map_t* v) { z_slice_map_drop(v); } -template<> inline void z_drop(zc_owned_liveliness_token_t* v) { zc_liveliness_undeclare_token(v); } -template<> inline int8_t z_drop(ze_owned_publication_cache_t* v) { return ze_undeclare_publication_cache(v); } -template<> inline int8_t z_drop(ze_owned_querying_subscriber_t* v) { return ze_undeclare_querying_subscriber(v); } -template<> inline void z_drop(z_owned_mutex_t* v) { z_mutex_drop(v); } -template<> inline void z_drop(z_owned_condvar_t* v) { z_condvar_drop(v); } -inline void z_null(z_owned_session_t& v) { v = z_session_null(); } -inline void z_null(z_owned_publisher_t& v) { v = z_publisher_null(); } -inline void z_null(z_owned_keyexpr_t& v) { v = z_keyexpr_null(); } -inline void z_null(z_owned_config_t& v) { v = z_config_null(); } -inline void z_null(z_owned_scouting_config_t& v) { v = z_scouting_config_null(); } -inline void z_null(z_owned_subscriber_t& v) { v = z_subscriber_null(); } -inline void z_null(z_owned_queryable_t& v) { v = z_queryable_null(); } -inline void z_null(z_owned_encoding_t& v) { v = z_encoding_null(); } -inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } -inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } -inline void z_null(z_owned_query_t& v) { v = z_query_null(); } -inline void z_null(z_owned_str_t& v) { v = z_str_null(); } -inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } -inline void z_null(z_owned_bytes_reader_t& v) { v = z_bytes_reader_null(); } -inline void z_null(z_owned_closure_sample_t& v) { v = z_closure_sample_null(); } -inline void z_null(z_owned_closure_query_t& v) { v = z_closure_query_null(); } -inline void z_null(z_owned_closure_reply_t& v) { v = z_closure_reply_null(); } -inline void z_null(z_owned_closure_hello_t& v) { v = z_closure_hello_null(); } -inline void z_null(z_owned_closure_zid_t& v) { v = z_closure_zid_null(); } -inline void z_null(zcu_owned_closure_matching_status_t& v) { v = zcu_closure_matching_status_null(); } -inline void z_null(z_owned_reply_channel_closure_t& v) { v = z_reply_channel_closure_null(); } -inline void z_null(z_owned_reply_channel_t& v) { v = z_reply_channel_null(); } -inline void z_null(z_owned_slice_t& v) { v = z_slice_null(); } -inline void z_null(z_owned_slice_map_t& v) { v = z_slice_map_null(); } -inline void z_null(zc_owned_liveliness_token_t& v) { v = zc_liveliness_token_null(); } -inline void z_null(ze_owned_publication_cache_t& v) { v = ze_publication_cache_null(); } -inline void z_null(ze_owned_querying_subscriber_t& v) { v = ze_querying_subscriber_null(); } -inline void z_null(z_owned_mutex_t& v) { v = z_mutex_null(); } -inline void z_null(z_owned_condvar_t& v) { v = z_condvar_null(); } -inline void z_null(z_owned_task_t& v) { v = z_task_null(); } +inline bool z_check(const z_view_keyexpr_t& keyexpr) { return z_view_keyexpr_check(&keyexpr); }; +inline bool z_check(const z_owned_bytes_t& payload) { return z_bytes_check(&payload); }; +inline bool z_check(const z_owned_query_t& query) { return z_query_check(&query); }; +inline bool z_check(const z_owned_scouting_config_t& config) { return z_scouting_config_check(&config); }; +inline bool z_check(const ze_owned_querying_subscriber_t& this_) { return ze_querying_subscriber_check(&this_); }; +inline bool z_check(const z_owned_sample_t& sample) { return z_sample_check(&sample); }; +inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; +inline bool z_check(const z_owned_str_array_t& strs) { return z_str_array_check(&strs); }; +inline bool z_check(const z_owned_hello_t& hello) { return z_hello_check(&hello); }; +inline bool z_check(const z_owned_task_t& this_) { return z_task_check(&this_); }; +inline bool z_check(const z_owned_reply_t& this_) { return z_reply_check(&this_); }; +inline bool z_check(const z_view_slice_t& this_) { return z_view_slice_check(&this_); }; +inline bool z_check(const ze_owned_publication_cache_t& this_) { return ze_publication_cache_check(&this_); }; +inline bool z_check(const zc_owned_liveliness_token_t& this_) { return zc_liveliness_token_check(&this_); }; +inline bool z_check(const z_owned_queryable_t& qable) { return z_queryable_check(&qable); }; +inline bool z_check(const z_owned_condvar_t& this_) { return z_condvar_check(&this_); }; +inline bool z_check(const z_owned_str_t& this_) { return z_str_check(&this_); }; +inline bool z_check(const z_owned_config_t& config) { return z_config_check(&config); }; +inline bool z_check(const z_owned_bytes_reader_t& this_) { return z_bytes_reader_check(&this_); }; +inline bool z_check(const z_owned_mutex_t& this_) { return z_mutex_check(&this_); }; +inline bool z_check(const z_owned_publisher_t& this_) { return z_publisher_check(&this_); }; +inline bool z_check(const z_owned_slice_t& this_) { return z_owned_slice_check(&this_); }; +inline bool z_check(const z_owned_session_t& this_) { return z_session_check(&this_); }; +inline bool z_check(const z_owned_encoding_t& encoding) { return z_encoding_check(&encoding); }; +inline bool z_check(const z_owned_slice_map_t& map) { return z_slice_map_check(&map); }; +inline bool z_check(const z_owned_subscriber_t& subscriber) { return z_subscriber_check(&subscriber); }; -inline bool z_check(const z_owned_session_t& v) { return z_session_check(&v); } -inline bool z_check(const z_owned_publisher_t& v) { return z_publisher_check(&v); } -inline bool z_check(const z_owned_keyexpr_t& v) { return z_keyexpr_check(&v); } -inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } -inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } -inline bool z_check(const z_owned_bytes_t& v) { return z_slice_check(&v); } -inline bool z_check(const z_owned_bytes_reader_t& v) { return z_bytes_reader_check(&v); } -inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } -inline bool z_check(const z_owned_queryable_t& v) { return z_queryable_check(&v); } -inline bool z_check(const z_owned_encoding_t& v) { return z_encoding_check(&v); } -inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } -inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } -inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } -inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } -inline bool z_check(const z_owned_slice_t& v) { return z_slice_check(&v); } -inline bool z_check(const z_owned_slice_map_t& v) { return z_slice_map_check(&v); } -inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } -inline bool z_check(const ze_owned_publication_cache_t& v) { return ze_publication_cache_check(&v); } -inline bool z_check(const ze_owned_querying_subscriber_t& v) { return ze_querying_subscriber_check(&v); } -inline bool z_check(const z_owned_mutex_t& v) { return z_mutex_check(&v); } -inline bool z_check(const z_owned_condvar_t& v) { return z_condvar_check(&v); } -inline bool z_check(const z_owned_task_t& v) { return z_task_check(&v); } -inline void z_call(const struct z_owned_closure_sample_t &closure, const struct z_loaned_sample_t *sample) - { z_closure_sample_call(&closure, sample); } -inline void z_call(const struct z_owned_closure_query_t &closure, const struct z_loaned_query_t *query) - { z_closure_query_call(&closure, query); } -inline void z_call(const struct z_owned_closure_reply_t &closure, struct z_owned_reply_t *sample) - { z_closure_reply_call(&closure, sample); } -inline void z_call(const struct z_owned_closure_hello_t &closure, struct z_owned_hello_t *hello) - { z_closure_hello_call(&closure, hello); } -inline void z_call(const struct z_owned_closure_zid_t &closure, const struct z_id_t *zid) - { z_closure_zid_call(&closure, zid); } -inline void z_call(const struct zcu_owned_closure_matching_status_t &closure, const struct zcu_matching_status_t *matching_status) - { zcu_closure_matching_status_call(&closure, matching_status); } -inline bool z_call(const struct z_owned_reply_channel_closure_t &closure, struct z_owned_reply_t *sample) - { return z_reply_channel_closure_call(&closure, sample); } -// clang-format on +inline void z_call(const z_owned_closure_query_t& closure, const z_loaned_query_t* query) { + return z_closure_query_call(&closure, query); +}; +inline void z_call(const z_owned_closure_hello_t& closure, z_owned_hello_t* hello) { + return z_closure_hello_call(&closure, hello); +}; +inline void z_call(const z_owned_closure_reply_t& closure, const z_loaned_reply_t* reply) { + return z_closure_reply_call(&closure, reply); +}; +inline void z_call(const z_owned_closure_sample_t& closure, const z_loaned_sample_t* sample) { + return z_closure_sample_call(&closure, sample); +}; +inline void z_call(const z_owned_closure_owned_query_t& closure, z_owned_query_t* query) { + return z_closure_owned_query_call(&closure, query); +}; +inline void z_call(const z_owned_closure_zid_t& closure, const z_id_t* sample) { + return z_closure_zid_call(&closure, sample); +}; +inline void z_call(const zcu_owned_closure_matching_status_t& closure, const zcu_matching_status_t* sample) { + return zcu_closure_matching_status_call(&closure, sample); +}; +inline bool z_call(const z_owned_query_channel_closure_t& closure, z_owned_query_t* query) { + return z_query_channel_closure_call(&closure, query); +}; +inline bool z_call(const z_owned_reply_channel_closure_t& closure, z_owned_reply_t* reply) { + return z_reply_channel_closure_call(&closure, reply); +}; -#define _z_closure_overloader(callback, droper, ctx, ...) \ - { .context = const_cast(static_cast(ctx)), .call = callback, .drop = droper } -#define z_closure(...) _z_closure_overloader(__VA_ARGS__, NULL, NULL) -#define z_move(x) (&x) -#endif // #ifndef __cplusplus +inline void z_closure( + z_owned_closure_query_t* closure, + void (*call)(const z_loaned_query_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_hello_t* closure, + void (*call)( z_owned_hello_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_reply_t* closure, + void (*call)(const z_loaned_reply_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_sample_t* closure, + void (*call)(const z_loaned_sample_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_owned_query_t* closure, + void (*call)( z_owned_query_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_zid_t* closure, + void (*call)(const z_id_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + zcu_owned_closure_matching_status_t* closure, + void (*call)(const zcu_matching_status_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_query_channel_closure_t* closure, + bool (*call)( z_owned_query_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_reply_channel_closure_t* closure, + bool (*call)( z_owned_reply_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +#endif // #ifndef __cplusplus \ No newline at end of file diff --git a/src/commons.rs b/src/commons.rs index efc9fc9f0..11a6a28b3 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -149,15 +149,12 @@ pub extern "C" fn z_sample_attachment(sample: &z_loaned_sample_t) -> *const z_lo } } -pub use crate::opaque_types::zc_owned_sample_t; -decl_transmute_owned!(Option, zc_owned_sample_t); +pub use crate::opaque_types::z_owned_sample_t; +decl_transmute_owned!(Option, z_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] -pub extern "C" fn z_sample_clone( - src: &z_loaned_sample_t, - dst: *mut MaybeUninit, -) { +pub extern "C" fn z_sample_clone(src: &z_loaned_sample_t, dst: *mut MaybeUninit) { let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); @@ -186,10 +183,10 @@ pub extern "C" fn z_sample_congestion_control( /// Returns `true` if `sample` is valid. /// -/// Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed +/// Note that there exist no fallinle constructors for `z_owned_sample_t`, so validity is always guaranteed /// unless the value has been dropped already. #[no_mangle] -pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { +pub extern "C" fn z_sample_check(sample: &z_owned_sample_t) -> bool { let sample = sample.transmute_ref(); sample.is_some() } @@ -198,18 +195,18 @@ pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> &z_loaned_sample_t { +pub extern "C" fn z_sample_loan(sample: &z_owned_sample_t) -> &z_loaned_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } /// Destroy the sample. #[no_mangle] -pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { +pub extern "C" fn z_sample_drop(sample: &mut z_owned_sample_t) { Inplace::drop(sample.transmute_mut()); } #[no_mangle] -pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { +pub extern "C" fn z_sample_null(sample: *mut MaybeUninit) { Inplace::empty(sample.transmute_uninit_ptr()); } diff --git a/src/publisher.rs b/src/publisher.rs index f4d6b8cbf..acc473008 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -173,7 +173,7 @@ pub extern "C" fn z_publisher_put_options_default(this: &mut z_publisher_put_opt /// Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. /// /// This is avoids copies when transfering data that was either: -/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher +/// - `z_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher /// - constructed from a `zc_owned_shmbuf_t` /// /// The payload and all owned options fields are consumed upon function return. From cff75b0ec9994d6543740bab6b116c7fba451749 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 26 Apr 2024 16:50:33 +0200 Subject: [PATCH 064/377] automated macro-function generation --- build.rs | 159 ++++++++++--------- include/zenoh_macros.h | 346 ++++++++++++++++++++--------------------- 2 files changed, 256 insertions(+), 249 deletions(-) diff --git a/build.rs b/build.rs index 4d06c44e3..2a1c263bf 100644 --- a/build.rs +++ b/build.rs @@ -771,82 +771,82 @@ pub fn create_generics_header(path_in: &str, path_out: &str) { #ifndef __cplusplus "; - file_out.write(header.as_bytes()).unwrap(); + file_out.write_all(header.as_bytes()).unwrap(); let type_name_to_loan_func = find_loan_functions(path_in); let out = generate_generic_loan_c(&type_name_to_loan_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_loan_mut_func = find_loan_mut_functions(path_in); let out = generate_generic_loan_mut_c(&type_name_to_loan_mut_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_drop_func = find_drop_functions(path_in); let out = generate_generic_drop_c(&type_name_to_drop_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_null_func = find_null_functions(path_in); let out = generate_generic_null_c(&type_name_to_null_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_check_func = find_check_functions(path_in); let out = generate_generic_check_c(&type_name_to_check_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_call_func = find_call_functions(path_in); let out = generate_generic_call_c(&type_name_to_call_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_closure_c(&type_name_to_call_func); - file_out.write(out.as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); file_out - .write("\n#else // #ifndef __cplusplus\n".as_bytes()) + .write_all("\n#else // #ifndef __cplusplus\n".as_bytes()) .unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_loan_cpp(&type_name_to_loan_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_loan_mut_cpp(&type_name_to_loan_mut_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_drop_cpp(&type_name_to_drop_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_null_cpp(&type_name_to_null_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_check_cpp(&type_name_to_check_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_call_cpp(&type_name_to_call_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_closure_cpp(&type_name_to_call_func); - file_out.write(out.as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); file_out - .write("\n#endif // #ifndef __cplusplus".as_bytes()) + .write_all("\n#endif // #ifndef __cplusplus".as_bytes()) .unwrap(); } -pub fn find_loan_functions(path_in: &str) -> HashMap { +pub fn find_loan_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"const struct (\w+) \*(\w+)_loan\(const struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [return_type, func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) @@ -856,15 +856,15 @@ pub fn find_loan_functions(path_in: &str) -> HashMap func_name: func_name.to_string() + "_loan", arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), }; - res.insert(arg_type.to_string(), f); + res.push(f); } res } -pub fn find_loan_mut_functions(path_in: &str) -> HashMap { +pub fn find_loan_mut_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"struct (\w+) \*(\w+)_loan_mut\(struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [return_type, func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) @@ -874,15 +874,15 @@ pub fn find_loan_mut_functions(path_in: &str) -> HashMap HashMap { +pub fn find_drop_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"(\w+)_drop\(struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { let f = FunctionSignature { @@ -890,15 +890,15 @@ pub fn find_drop_functions(path_in: &str) -> HashMap func_name: func_name.to_string() + "_drop", arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), }; - res.insert(arg_type.to_string(), f); + res.push(f); } res } -pub fn find_null_functions(path_in: &str) -> HashMap { +pub fn find_null_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"(\w+)_null\(struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { let f = FunctionSignature { @@ -906,15 +906,15 @@ pub fn find_null_functions(path_in: &str) -> HashMap func_name: func_name.to_string() + "_null", arg_type_and_name: [FuncArg::new(arg_type, "", arg_name)].to_vec(), }; - res.insert(arg_type.to_string(), f); + res.push(f); } res } -pub fn find_check_functions(path_in: &str) -> HashMap { +pub fn find_check_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"bool (\w+)_check\(const struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { let f = FunctionSignature { @@ -922,18 +922,18 @@ pub fn find_check_functions(path_in: &str) -> HashMap func_name: func_name.to_string() + "_check", arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), }; - res.insert(arg_type.to_string(), f); + res.push(f); } res } -pub fn find_call_functions(path_in: &str) -> HashMap { +pub fn find_call_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new( r"(\w+) (\w+)_call\(const struct (\w+) \*(\w+),\s+(\w*)\s*struct (\w+) \*(\w+)\);", ) .unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [return_type, func_name, closure_type, closure_name, arg_cv, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) @@ -947,17 +947,18 @@ pub fn find_call_functions(path_in: &str) -> HashMap ] .to_vec(), }; - res.insert(closure_type.to_string(), f); + res.push(f); } res } -pub fn generate_generic_loan_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_loan_c(macro_func: &Vec) -> String { let mut out = "#define z_loan(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ", \\\n"; out += &format!(" {owned_type} : {func_name}"); @@ -968,13 +969,14 @@ pub fn generate_generic_loan_c(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "#define z_loan_mut(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ", \\\n"; out += &format!(" {owned_type} : {func_name}"); @@ -984,12 +986,13 @@ pub fn generate_generic_loan_mut_c( out } -pub fn generate_generic_drop_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_drop_c(macro_func: &Vec) -> String { let mut out = "#define z_drop(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ",\\\n"; out += &format!(" {owned_type} * : {func_name}"); @@ -999,12 +1002,13 @@ pub fn generate_generic_drop_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_null_c(macro_func: &Vec) -> String { let mut out = "#define z_null(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ", \\\n"; out += &format!(" {owned_type} * : {func_name}"); @@ -1014,12 +1018,13 @@ pub fn generate_generic_null_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_check_c(macro_func: &Vec) -> String { let mut out = "#define z_check(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ", \\\n"; out += &format!(" {owned_type} : {func_name}"); @@ -1029,13 +1034,14 @@ pub fn generate_generic_check_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_call_c(macro_func: &Vec) -> String { let mut out = "#define z_call(x, ...) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; + let owned_type = &func.arg_type_and_name[0].typename; out += ", \\\n"; out += &format!(" {owned_type} : {func_name}"); } @@ -1046,13 +1052,14 @@ pub fn generate_generic_call_c(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "#define z_closure(x, callback, dropper, ctx) \\ _Generic((x)" .to_owned(); - for (owned_type, _func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; out += ", \\\n"; out += &format!( " {owned_type} * : {{ x->context = (void*)ctx; x->call = callback; x->drop = droper; }}"); @@ -1063,10 +1070,10 @@ pub fn generate_generic_closure_c( out } -pub fn generate_generic_loan_cpp(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_loan_cpp(macro_func: &Vec) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1079,11 +1086,11 @@ pub fn generate_generic_loan_cpp(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1095,10 +1102,10 @@ pub fn generate_generic_loan_mut_cpp( out } -pub fn generate_generic_drop_cpp(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_drop_cpp(macro_func: &Vec) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1110,10 +1117,10 @@ pub fn generate_generic_drop_cpp(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_null_cpp(macro_func: &Vec) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1126,11 +1133,11 @@ pub fn generate_generic_null_cpp(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1142,10 +1149,10 @@ pub fn generate_generic_check_cpp( out } -pub fn generate_generic_call_cpp(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_call_cpp(macro_func: &Vec) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let closure_cv = &func.arg_type_and_name[0].cv; @@ -1163,11 +1170,11 @@ pub fn generate_generic_call_cpp(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let return_type = &func.return_type; let closure_name = &func.arg_type_and_name[0].name; let closure_type = &func.arg_type_and_name[0].typename; diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index c4229023b..d432f0650 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -4,303 +4,303 @@ #define z_loan(x) \ _Generic((x), \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_loan, \ - z_owned_sample_t : z_sample_loan, \ - z_view_slice_t : z_view_slice_loan, \ z_owned_bytes_t : z_bytes_loan, \ + z_owned_bytes_reader_t : z_bytes_reader_loan, \ + z_owned_condvar_t : z_condvar_loan, \ + z_owned_config_t : z_config_loan, \ + z_owned_encoding_t : z_encoding_loan, \ + z_owned_hello_t : z_hello_loan, \ + z_owned_keyexpr_t : z_keyexpr_loan, \ z_owned_publisher_t : z_publisher_loan, \ + z_owned_query_t : z_query_loan, \ + z_owned_sample_t : z_sample_loan, \ + z_owned_session_t : z_session_loan, \ z_owned_slice_t : z_slice_loan, \ z_owned_slice_map_t : z_slice_map_loan, \ - z_owned_keyexpr_t : z_keyexpr_loan, \ - z_owned_encoding_t : z_encoding_loan, \ + z_owned_str_array_t : z_str_array_loan, \ z_owned_str_t : z_str_loan, \ - z_owned_session_t : z_session_loan, \ - z_owned_hello_t : z_hello_loan, \ - z_view_str_t : z_view_str_loan, \ - z_owned_query_t : z_query_loan, \ z_owned_subscriber_t : z_subscriber_loan, \ z_view_keyexpr_t : z_view_keyexpr_loan, \ - z_owned_str_array_t : z_str_array_loan, \ - z_owned_condvar_t : z_condvar_loan, \ - z_owned_config_t : z_config_loan, \ - z_owned_bytes_reader_t : z_bytes_reader_loan \ + z_view_slice_t : z_view_slice_loan, \ + z_view_str_t : z_view_str_loan, \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ )(&x) #define z_loan_mut(x) \ _Generic((x), \ - z_owned_condvar_t : z_condvar_loan_mut, \ z_owned_bytes_reader_t : z_bytes_reader_loan_mut, \ + z_owned_condvar_t : z_condvar_loan_mut, \ z_owned_config_t : z_config_loan_mut, \ - z_owned_slice_map_t : z_slice_map_loan_mut, \ - z_owned_mutex_t : z_mutex_loan_mut \ + z_owned_mutex_t : z_mutex_loan_mut, \ + z_owned_slice_map_t : z_slice_map_loan_mut \ )(&x) #define z_drop(x) \ _Generic((x),\ + z_owned_bytes_t * : z_bytes_drop,\ + z_owned_bytes_reader_t * : z_bytes_reader_drop,\ + z_owned_closure_hello_t * : z_closure_hello_drop,\ + z_owned_closure_owned_query_t * : z_closure_owned_query_drop,\ z_owned_closure_query_t * : z_closure_query_drop,\ - z_owned_closure_zid_t * : z_closure_zid_drop,\ - z_owned_slice_map_t * : z_slice_map_drop,\ - zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop,\ - z_owned_reply_t * : z_reply_drop,\ - z_owned_slice_t * : z_slice_drop,\ + z_owned_closure_reply_t * : z_closure_reply_drop,\ z_owned_closure_sample_t * : z_closure_sample_drop,\ - z_owned_bytes_t * : z_bytes_drop,\ + z_owned_closure_zid_t * : z_closure_zid_drop,\ z_owned_condvar_t * : z_condvar_drop,\ - z_owned_sample_t * : z_sample_drop,\ - z_owned_query_channel_t * : z_query_channel_drop,\ - z_owned_query_channel_closure_t * : z_query_channel_closure_drop,\ - z_owned_closure_reply_t * : z_closure_reply_drop,\ - z_owned_reply_channel_t * : z_reply_channel_drop,\ - z_owned_str_t * : z_str_drop,\ - z_owned_closure_owned_query_t * : z_closure_owned_query_drop,\ z_owned_config_t * : z_config_drop,\ - z_owned_mutex_t * : z_mutex_drop,\ - z_owned_bytes_reader_t * : z_bytes_reader_drop,\ - z_owned_str_array_t * : z_str_array_drop,\ - z_owned_keyexpr_t * : z_keyexpr_drop,\ - z_owned_scouting_config_t * : z_scouting_config_drop,\ - z_owned_closure_hello_t * : z_closure_hello_drop,\ z_owned_encoding_t * : z_encoding_drop,\ z_owned_hello_t * : z_hello_drop,\ + z_owned_keyexpr_t * : z_keyexpr_drop,\ + z_owned_mutex_t * : z_mutex_drop,\ + z_owned_query_channel_closure_t * : z_query_channel_closure_drop,\ + z_owned_query_channel_t * : z_query_channel_drop,\ z_owned_query_t * : z_query_drop,\ - z_owned_reply_channel_closure_t * : z_reply_channel_closure_drop \ + z_owned_reply_channel_closure_t * : z_reply_channel_closure_drop,\ + z_owned_reply_channel_t * : z_reply_channel_drop,\ + z_owned_reply_t * : z_reply_drop,\ + z_owned_sample_t * : z_sample_drop,\ + z_owned_scouting_config_t * : z_scouting_config_drop,\ + z_owned_slice_t * : z_slice_drop,\ + z_owned_slice_map_t * : z_slice_map_drop,\ + z_owned_str_array_t * : z_str_array_drop,\ + z_owned_str_t * : z_str_drop,\ + zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop \ )(x) #define z_null(x) \ _Generic((x), \ - z_owned_slice_map_t * : z_slice_map_null, \ - z_owned_query_t * : z_query_null, \ - z_owned_keyexpr_t * : z_keyexpr_null, \ - z_view_str_t * : z_view_str_null, \ - z_view_slice_t * : z_view_slice_null, \ - z_owned_str_t * : z_str_null, \ - z_owned_scouting_config_t * : z_scouting_config_null, \ + z_owned_bytes_t * : z_bytes_null, \ + z_owned_bytes_reader_t * : z_bytes_reader_null, \ z_owned_condvar_t * : z_condvar_null, \ + z_owned_config_t * : z_config_null, \ z_owned_encoding_t * : z_encoding_null, \ + z_owned_hello_t * : z_hello_null, \ + z_owned_keyexpr_t * : z_keyexpr_null, \ + z_owned_mutex_t * : z_mutex_null, \ + z_owned_publisher_t * : z_publisher_null, \ + z_owned_query_t * : z_query_null, \ z_owned_queryable_t * : z_queryable_null, \ z_owned_reply_t * : z_reply_null, \ - z_owned_mutex_t * : z_mutex_null, \ - z_owned_config_t * : z_config_null, \ - z_owned_bytes_reader_t * : z_bytes_reader_null, \ - z_owned_hello_t * : z_hello_null, \ z_owned_sample_t * : z_sample_null, \ - z_owned_subscriber_t * : z_subscriber_null, \ - z_owned_bytes_t * : z_bytes_null, \ - z_owned_publisher_t * : z_publisher_null, \ + z_owned_scouting_config_t * : z_scouting_config_null, \ z_owned_session_t * : z_session_null, \ - z_owned_task_t * : z_task_null, \ + z_owned_slice_map_t * : z_slice_map_null, \ z_owned_slice_t * : z_slice_null, \ + z_owned_str_t * : z_str_null, \ + z_owned_subscriber_t * : z_subscriber_null, \ + z_owned_task_t * : z_task_null, \ z_view_keyexpr_t * : z_view_keyexpr_null, \ + z_view_slice_t * : z_view_slice_null, \ + z_view_str_t * : z_view_str_null, \ zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ - ze_owned_querying_subscriber_t * : ze_querying_subscriber_null, \ - ze_owned_publication_cache_t * : ze_publication_cache_null \ + ze_owned_publication_cache_t * : ze_publication_cache_null, \ + ze_owned_querying_subscriber_t * : ze_querying_subscriber_null \ )(x) #define z_check(x) \ _Generic((x), \ - z_view_keyexpr_t : z_view_keyexpr_check, \ z_owned_bytes_t : z_bytes_check, \ - z_owned_query_t : z_query_check, \ - z_owned_scouting_config_t : z_scouting_config_check, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_check, \ - z_owned_sample_t : z_sample_check, \ - z_owned_keyexpr_t : z_keyexpr_check, \ - z_owned_str_array_t : z_str_array_check, \ - z_owned_hello_t : z_hello_check, \ - z_owned_task_t : z_task_check, \ - z_owned_reply_t : z_reply_check, \ - z_view_slice_t : z_view_slice_check, \ - ze_owned_publication_cache_t : ze_publication_cache_check, \ - zc_owned_liveliness_token_t : zc_liveliness_token_check, \ - z_owned_queryable_t : z_queryable_check, \ + z_owned_bytes_reader_t : z_bytes_reader_check, \ z_owned_condvar_t : z_condvar_check, \ - z_owned_str_t : z_str_check, \ z_owned_config_t : z_config_check, \ - z_owned_bytes_reader_t : z_bytes_reader_check, \ + z_owned_encoding_t : z_encoding_check, \ + z_owned_hello_t : z_hello_check, \ + z_owned_keyexpr_t : z_keyexpr_check, \ z_owned_mutex_t : z_mutex_check, \ - z_owned_publisher_t : z_publisher_check, \ z_owned_slice_t : z_owned_slice_check, \ + z_owned_publisher_t : z_publisher_check, \ + z_owned_query_t : z_query_check, \ + z_owned_queryable_t : z_queryable_check, \ + z_owned_reply_t : z_reply_check, \ + z_owned_sample_t : z_sample_check, \ + z_owned_scouting_config_t : z_scouting_config_check, \ z_owned_session_t : z_session_check, \ - z_owned_encoding_t : z_encoding_check, \ z_owned_slice_map_t : z_slice_map_check, \ - z_owned_subscriber_t : z_subscriber_check \ + z_owned_str_array_t : z_str_array_check, \ + z_owned_str_t : z_str_check, \ + z_owned_subscriber_t : z_subscriber_check, \ + z_owned_task_t : z_task_check, \ + z_view_keyexpr_t : z_view_keyexpr_check, \ + z_view_slice_t : z_view_slice_check, \ + zc_owned_liveliness_token_t : zc_liveliness_token_check, \ + ze_owned_publication_cache_t : ze_publication_cache_check, \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_check \ )(&x) #define z_call(x, ...) \ _Generic((x), \ - z_owned_closure_query_t : z_closure_query_call, \ z_owned_closure_hello_t : z_closure_hello_call, \ + z_owned_closure_owned_query_t : z_closure_owned_query_call, \ + z_owned_closure_query_t : z_closure_query_call, \ z_owned_closure_reply_t : z_closure_reply_call, \ z_owned_closure_sample_t : z_closure_sample_call, \ - z_owned_closure_owned_query_t : z_closure_owned_query_call, \ z_owned_closure_zid_t : z_closure_zid_call, \ - zcu_owned_closure_matching_status_t : zcu_closure_matching_status_call, \ z_owned_query_channel_closure_t : z_query_channel_closure_call, \ - z_owned_reply_channel_closure_t : z_reply_channel_closure_call \ + z_owned_reply_channel_closure_t : z_reply_channel_closure_call, \ + zcu_owned_closure_matching_status_t : zcu_closure_matching_status_call \ )(&x, __VA_ARGS__) #define z_closure(x, callback, dropper, ctx) \ _Generic((x), \ - z_owned_closure_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_closure_hello_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_owned_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_closure_reply_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_closure_sample_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_closure_owned_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_closure_zid_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - zcu_owned_closure_matching_status_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_query_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_reply_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; } \ + z_owned_reply_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + zcu_owned_closure_matching_status_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; } \ ) #else // #ifndef __cplusplus -inline const ze_loaned_querying_subscriber_t* z_loan(const ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_loan(this_); }; -inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* sample) { return z_sample_loan(sample); }; -inline const z_loaned_slice_t* z_loan(const z_view_slice_t* this_) { return z_view_slice_loan(this_); }; inline const z_loaned_bytes_t* z_loan(const z_owned_bytes_t* payload) { return z_bytes_loan(payload); }; +inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t* reader) { return z_bytes_reader_loan(reader); }; +inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t* this_) { return z_condvar_loan(this_); }; +inline const z_loaned_config_t* z_loan(const z_owned_config_t* this_) { return z_config_loan(this_); }; +inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* encoding) { return z_encoding_loan(encoding); }; +inline const z_hello_t* z_loan(const z_owned_hello_t* hello) { return z_hello_loan(hello); }; +inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t* key_expr) { return z_keyexpr_loan(key_expr); }; inline const z_loaned_publisher_t* z_loan(const z_owned_publisher_t* this_) { return z_publisher_loan(this_); }; +inline const z_loaned_query_t* z_loan(const z_owned_query_t* this_) { return z_query_loan(this_); }; +inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* sample) { return z_sample_loan(sample); }; +inline const z_loaned_session_t* z_loan(const z_owned_session_t* this_) { return z_session_loan(this_); }; inline const z_loaned_slice_t* z_loan(const z_owned_slice_t* this_) { return z_slice_loan(this_); }; inline const z_loaned_slice_map_t* z_loan(const z_owned_slice_map_t* this_) { return z_slice_map_loan(this_); }; -inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t* key_expr) { return z_keyexpr_loan(key_expr); }; -inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* encoding) { return z_encoding_loan(encoding); }; +inline const z_str_array_t* z_loan(const z_owned_str_array_t* strs) { return z_str_array_loan(strs); }; inline const z_loaned_str_t* z_loan(const z_owned_str_t* this_) { return z_str_loan(this_); }; -inline const z_loaned_session_t* z_loan(const z_owned_session_t* this_) { return z_session_loan(this_); }; -inline const z_hello_t* z_loan(const z_owned_hello_t* hello) { return z_hello_loan(hello); }; -inline const z_loaned_str_t* z_loan(const z_view_str_t* this_) { return z_view_str_loan(this_); }; -inline const z_loaned_query_t* z_loan(const z_owned_query_t* this_) { return z_query_loan(this_); }; inline const z_loaned_subscriber_t* z_loan(const z_owned_subscriber_t* this_) { return z_subscriber_loan(this_); }; inline const z_loaned_keyexpr_t* z_loan(const z_view_keyexpr_t* key_expr) { return z_view_keyexpr_loan(key_expr); }; -inline const z_str_array_t* z_loan(const z_owned_str_array_t* strs) { return z_str_array_loan(strs); }; -inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t* this_) { return z_condvar_loan(this_); }; -inline const z_loaned_config_t* z_loan(const z_owned_config_t* this_) { return z_config_loan(this_); }; -inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t* reader) { return z_bytes_reader_loan(reader); }; +inline const z_loaned_slice_t* z_loan(const z_view_slice_t* this_) { return z_view_slice_loan(this_); }; +inline const z_loaned_str_t* z_loan(const z_view_str_t* this_) { return z_view_str_loan(this_); }; +inline const ze_loaned_querying_subscriber_t* z_loan(const ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_loan(this_); }; -inline z_loaned_condvar_t* z_loan_mut( z_owned_condvar_t& this_) { return z_condvar_loan_mut(&this_); }; inline z_loaned_bytes_reader_t* z_loan_mut( z_owned_bytes_reader_t& reader) { return z_bytes_reader_loan_mut(&reader); }; +inline z_loaned_condvar_t* z_loan_mut( z_owned_condvar_t& this_) { return z_condvar_loan_mut(&this_); }; inline z_loaned_config_t* z_loan_mut( z_owned_config_t& this_) { return z_config_loan_mut(&this_); }; -inline z_loaned_slice_map_t* z_loan_mut( z_owned_slice_map_t& this_) { return z_slice_map_loan_mut(&this_); }; inline z_loaned_mutex_t* z_loan_mut( z_owned_mutex_t& this_) { return z_mutex_loan_mut(&this_); }; +inline z_loaned_slice_map_t* z_loan_mut( z_owned_slice_map_t& this_) { return z_slice_map_loan_mut(&this_); }; +inline void z_drop(const z_owned_bytes_t* this_) { return z_bytes_drop(this_); }; +inline void z_drop(const z_owned_bytes_reader_t* this_) { return z_bytes_reader_drop(this_); }; +inline void z_drop(const z_owned_closure_hello_t* closure) { return z_closure_hello_drop(closure); }; +inline void z_drop(const z_owned_closure_owned_query_t* closure) { return z_closure_owned_query_drop(closure); }; inline void z_drop(const z_owned_closure_query_t* closure) { return z_closure_query_drop(closure); }; -inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; -inline void z_drop(const z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; -inline void z_drop(const zcu_owned_closure_matching_status_t* closure) { return zcu_closure_matching_status_drop(closure); }; -inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; -inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; +inline void z_drop(const z_owned_closure_reply_t* closure) { return z_closure_reply_drop(closure); }; inline void z_drop(const z_owned_closure_sample_t* closure) { return z_closure_sample_drop(closure); }; -inline void z_drop(const z_owned_bytes_t* this_) { return z_bytes_drop(this_); }; +inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; inline void z_drop(const z_owned_condvar_t* this_) { return z_condvar_drop(this_); }; -inline void z_drop(const z_owned_sample_t* sample) { return z_sample_drop(sample); }; -inline void z_drop(const z_owned_query_channel_t* channel) { return z_query_channel_drop(channel); }; -inline void z_drop(const z_owned_query_channel_closure_t* closure) { return z_query_channel_closure_drop(closure); }; -inline void z_drop(const z_owned_closure_reply_t* closure) { return z_closure_reply_drop(closure); }; -inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_channel_drop(channel); }; -inline void z_drop(const z_owned_str_t* this_) { return z_str_drop(this_); }; -inline void z_drop(const z_owned_closure_owned_query_t* closure) { return z_closure_owned_query_drop(closure); }; inline void z_drop(const z_owned_config_t* config) { return z_config_drop(config); }; -inline void z_drop(const z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; -inline void z_drop(const z_owned_bytes_reader_t* this_) { return z_bytes_reader_drop(this_); }; -inline void z_drop(const z_owned_str_array_t* strs) { return z_str_array_drop(strs); }; -inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; -inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; -inline void z_drop(const z_owned_closure_hello_t* closure) { return z_closure_hello_drop(closure); }; inline void z_drop(const z_owned_encoding_t* encoding) { return z_encoding_drop(encoding); }; inline void z_drop(const z_owned_hello_t* hello) { return z_hello_drop(hello); }; +inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; +inline void z_drop(const z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; +inline void z_drop(const z_owned_query_channel_closure_t* closure) { return z_query_channel_closure_drop(closure); }; +inline void z_drop(const z_owned_query_channel_t* channel) { return z_query_channel_drop(channel); }; inline void z_drop(const z_owned_query_t* this_) { return z_query_drop(this_); }; inline void z_drop(const z_owned_reply_channel_closure_t* closure) { return z_reply_channel_closure_drop(closure); }; +inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_channel_drop(channel); }; +inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; +inline void z_drop(const z_owned_sample_t* sample) { return z_sample_drop(sample); }; +inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; +inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; +inline void z_drop(const z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; +inline void z_drop(const z_owned_str_array_t* strs) { return z_str_array_drop(strs); }; +inline void z_drop(const z_owned_str_t* this_) { return z_str_drop(this_); }; +inline void z_drop(const zcu_owned_closure_matching_status_t* closure) { return zcu_closure_matching_status_drop(closure); }; -inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; -inline void z_null( z_owned_query_t* this_) { return z_query_null(this_); }; -inline void z_null( z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; -inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; -inline void z_null( z_view_slice_t* this_) { return z_view_slice_null(this_); }; -inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; -inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; +inline void z_null( z_owned_bytes_t* this_) { return z_bytes_null(this_); }; +inline void z_null( z_owned_bytes_reader_t* this_) { return z_bytes_reader_null(this_); }; inline void z_null( z_owned_condvar_t* this_) { return z_condvar_null(this_); }; +inline void z_null( z_owned_config_t* this_) { return z_config_null(this_); }; inline void z_null( z_owned_encoding_t* encoding) { return z_encoding_null(encoding); }; +inline void z_null( z_owned_hello_t* this_) { return z_hello_null(this_); }; +inline void z_null( z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; +inline void z_null( z_owned_mutex_t* this_) { return z_mutex_null(this_); }; +inline void z_null( z_owned_publisher_t* this_) { return z_publisher_null(this_); }; +inline void z_null( z_owned_query_t* this_) { return z_query_null(this_); }; inline void z_null( z_owned_queryable_t* this_) { return z_queryable_null(this_); }; inline void z_null( z_owned_reply_t* this_) { return z_reply_null(this_); }; -inline void z_null( z_owned_mutex_t* this_) { return z_mutex_null(this_); }; -inline void z_null( z_owned_config_t* this_) { return z_config_null(this_); }; -inline void z_null( z_owned_bytes_reader_t* this_) { return z_bytes_reader_null(this_); }; -inline void z_null( z_owned_hello_t* this_) { return z_hello_null(this_); }; inline void z_null( z_owned_sample_t* sample) { return z_sample_null(sample); }; -inline void z_null( z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; -inline void z_null( z_owned_bytes_t* this_) { return z_bytes_null(this_); }; -inline void z_null( z_owned_publisher_t* this_) { return z_publisher_null(this_); }; +inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; inline void z_null( z_owned_session_t* this_) { return z_session_null(this_); }; -inline void z_null( z_owned_task_t* this_) { return z_task_null(this_); }; +inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; inline void z_null( z_owned_slice_t* this_) { return z_slice_null(this_); }; +inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; +inline void z_null( z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; +inline void z_null( z_owned_task_t* this_) { return z_task_null(this_); }; inline void z_null( z_view_keyexpr_t* this_) { return z_view_keyexpr_null(this_); }; +inline void z_null( z_view_slice_t* this_) { return z_view_slice_null(this_); }; +inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; inline void z_null( zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_null(this_); }; -inline void z_null( ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_null(this_); }; inline void z_null( ze_owned_publication_cache_t* this_) { return ze_publication_cache_null(this_); }; +inline void z_null( ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_null(this_); }; -inline bool z_check(const z_view_keyexpr_t& keyexpr) { return z_view_keyexpr_check(&keyexpr); }; inline bool z_check(const z_owned_bytes_t& payload) { return z_bytes_check(&payload); }; -inline bool z_check(const z_owned_query_t& query) { return z_query_check(&query); }; -inline bool z_check(const z_owned_scouting_config_t& config) { return z_scouting_config_check(&config); }; -inline bool z_check(const ze_owned_querying_subscriber_t& this_) { return ze_querying_subscriber_check(&this_); }; -inline bool z_check(const z_owned_sample_t& sample) { return z_sample_check(&sample); }; -inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; -inline bool z_check(const z_owned_str_array_t& strs) { return z_str_array_check(&strs); }; -inline bool z_check(const z_owned_hello_t& hello) { return z_hello_check(&hello); }; -inline bool z_check(const z_owned_task_t& this_) { return z_task_check(&this_); }; -inline bool z_check(const z_owned_reply_t& this_) { return z_reply_check(&this_); }; -inline bool z_check(const z_view_slice_t& this_) { return z_view_slice_check(&this_); }; -inline bool z_check(const ze_owned_publication_cache_t& this_) { return ze_publication_cache_check(&this_); }; -inline bool z_check(const zc_owned_liveliness_token_t& this_) { return zc_liveliness_token_check(&this_); }; -inline bool z_check(const z_owned_queryable_t& qable) { return z_queryable_check(&qable); }; +inline bool z_check(const z_owned_bytes_reader_t& this_) { return z_bytes_reader_check(&this_); }; inline bool z_check(const z_owned_condvar_t& this_) { return z_condvar_check(&this_); }; -inline bool z_check(const z_owned_str_t& this_) { return z_str_check(&this_); }; inline bool z_check(const z_owned_config_t& config) { return z_config_check(&config); }; -inline bool z_check(const z_owned_bytes_reader_t& this_) { return z_bytes_reader_check(&this_); }; +inline bool z_check(const z_owned_encoding_t& encoding) { return z_encoding_check(&encoding); }; +inline bool z_check(const z_owned_hello_t& hello) { return z_hello_check(&hello); }; +inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; inline bool z_check(const z_owned_mutex_t& this_) { return z_mutex_check(&this_); }; -inline bool z_check(const z_owned_publisher_t& this_) { return z_publisher_check(&this_); }; inline bool z_check(const z_owned_slice_t& this_) { return z_owned_slice_check(&this_); }; +inline bool z_check(const z_owned_publisher_t& this_) { return z_publisher_check(&this_); }; +inline bool z_check(const z_owned_query_t& query) { return z_query_check(&query); }; +inline bool z_check(const z_owned_queryable_t& qable) { return z_queryable_check(&qable); }; +inline bool z_check(const z_owned_reply_t& this_) { return z_reply_check(&this_); }; +inline bool z_check(const z_owned_sample_t& sample) { return z_sample_check(&sample); }; +inline bool z_check(const z_owned_scouting_config_t& config) { return z_scouting_config_check(&config); }; inline bool z_check(const z_owned_session_t& this_) { return z_session_check(&this_); }; -inline bool z_check(const z_owned_encoding_t& encoding) { return z_encoding_check(&encoding); }; inline bool z_check(const z_owned_slice_map_t& map) { return z_slice_map_check(&map); }; +inline bool z_check(const z_owned_str_array_t& strs) { return z_str_array_check(&strs); }; +inline bool z_check(const z_owned_str_t& this_) { return z_str_check(&this_); }; inline bool z_check(const z_owned_subscriber_t& subscriber) { return z_subscriber_check(&subscriber); }; +inline bool z_check(const z_owned_task_t& this_) { return z_task_check(&this_); }; +inline bool z_check(const z_view_keyexpr_t& keyexpr) { return z_view_keyexpr_check(&keyexpr); }; +inline bool z_check(const z_view_slice_t& this_) { return z_view_slice_check(&this_); }; +inline bool z_check(const zc_owned_liveliness_token_t& this_) { return zc_liveliness_token_check(&this_); }; +inline bool z_check(const ze_owned_publication_cache_t& this_) { return ze_publication_cache_check(&this_); }; +inline bool z_check(const ze_owned_querying_subscriber_t& this_) { return ze_querying_subscriber_check(&this_); }; -inline void z_call(const z_owned_closure_query_t& closure, const z_loaned_query_t* query) { - return z_closure_query_call(&closure, query); -}; inline void z_call(const z_owned_closure_hello_t& closure, z_owned_hello_t* hello) { return z_closure_hello_call(&closure, hello); }; +inline void z_call(const z_owned_closure_owned_query_t& closure, z_owned_query_t* query) { + return z_closure_owned_query_call(&closure, query); +}; +inline void z_call(const z_owned_closure_query_t& closure, const z_loaned_query_t* query) { + return z_closure_query_call(&closure, query); +}; inline void z_call(const z_owned_closure_reply_t& closure, const z_loaned_reply_t* reply) { return z_closure_reply_call(&closure, reply); }; inline void z_call(const z_owned_closure_sample_t& closure, const z_loaned_sample_t* sample) { return z_closure_sample_call(&closure, sample); }; -inline void z_call(const z_owned_closure_owned_query_t& closure, z_owned_query_t* query) { - return z_closure_owned_query_call(&closure, query); -}; inline void z_call(const z_owned_closure_zid_t& closure, const z_id_t* sample) { return z_closure_zid_call(&closure, sample); }; -inline void z_call(const zcu_owned_closure_matching_status_t& closure, const zcu_matching_status_t* sample) { - return zcu_closure_matching_status_call(&closure, sample); -}; inline bool z_call(const z_owned_query_channel_closure_t& closure, z_owned_query_t* query) { return z_query_channel_closure_call(&closure, query); }; inline bool z_call(const z_owned_reply_channel_closure_t& closure, z_owned_reply_t* reply) { return z_reply_channel_closure_call(&closure, reply); }; +inline void z_call(const zcu_owned_closure_matching_status_t& closure, const zcu_matching_status_t* sample) { + return zcu_closure_matching_status_call(&closure, sample); +}; inline void z_closure( - z_owned_closure_query_t* closure, - void (*call)(const z_loaned_query_t*, void*), + z_owned_closure_hello_t* closure, + void (*call)( z_owned_hello_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -308,8 +308,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_closure_hello_t* closure, - void (*call)( z_owned_hello_t*, void*), + z_owned_closure_owned_query_t* closure, + void (*call)( z_owned_query_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -317,8 +317,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_closure_reply_t* closure, - void (*call)(const z_loaned_reply_t*, void*), + z_owned_closure_query_t* closure, + void (*call)(const z_loaned_query_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -326,8 +326,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_closure_sample_t* closure, - void (*call)(const z_loaned_sample_t*, void*), + z_owned_closure_reply_t* closure, + void (*call)(const z_loaned_reply_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -335,8 +335,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_closure_owned_query_t* closure, - void (*call)( z_owned_query_t*, void*), + z_owned_closure_sample_t* closure, + void (*call)(const z_loaned_sample_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -353,8 +353,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - zcu_owned_closure_matching_status_t* closure, - void (*call)(const zcu_matching_status_t*, void*), + z_owned_query_channel_closure_t* closure, + bool (*call)( z_owned_query_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -362,8 +362,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_query_channel_closure_t* closure, - bool (*call)( z_owned_query_t*, void*), + z_owned_reply_channel_closure_t* closure, + bool (*call)( z_owned_reply_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -371,8 +371,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_reply_channel_closure_t* closure, - bool (*call)( z_owned_reply_t*, void*), + zcu_owned_closure_matching_status_t* closure, + void (*call)(const zcu_matching_status_t*, void*), void (*drop)(void*), void *context) { closure->context = context; From b8dc2a94bc3207a5f4ed0c541698a950e7be8826 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 29 Apr 2024 18:46:32 +0200 Subject: [PATCH 065/377] point zenoh branch to protocol_changes; examples build --- Cargo.lock | 60 ++--- Cargo.toml | 8 +- Cargo.toml.in | 8 +- build-resources/opaque-types/Cargo.lock | 44 ++-- build-resources/opaque-types/Cargo.toml | 4 +- build-resources/opaque-types/src/lib.rs | 20 +- build.rs | 19 +- docs/api.rst | 2 +- docs/examples.rst | 4 +- examples/z_delete.c | 10 +- examples/z_get.c | 35 ++- examples/z_get_liveliness.c | 17 +- examples/z_info.c | 15 +- examples/z_liveliness.c | 17 +- examples/z_non_blocking_get.c | 40 +-- examples/z_ping.c | 52 ++-- examples/z_pong.c | 34 ++- examples/z_pub.c | 35 ++- examples/z_pub_attachment.c | 46 ++-- examples/z_pub_cache.c | 30 ++- examples/z_pub_thr.c | 23 +- examples/z_put.c | 43 +++- examples/z_query_sub.c | 51 ++-- examples/z_queryable.c | 73 +++--- examples/z_queryable_with_channels.c | 86 ++++--- examples/z_scout.c | 34 ++- examples/z_sub.c | 45 ++-- examples/z_sub_attachment.c | 69 ++++-- examples/z_sub_liveliness.c | 37 +-- examples/z_sub_thr.c | 14 +- include/zenoh_commons.h | 307 +++++++++++++----------- include/zenoh_macros.h | 63 +++-- src/closures/hello_closure.rs | 22 +- src/closures/matching_status_closure.rs | 6 +- src/closures/query_channel.rs | 18 +- src/closures/query_closure.rs | 6 +- src/closures/reply_closure.rs | 6 +- src/closures/response_channel.rs | 25 +- src/closures/sample_closure.rs | 6 +- src/closures/zenohid_closure.rs | 6 +- src/collections.rs | 139 ++++++++++- src/commons.rs | 33 +-- src/get.rs | 16 +- src/info.rs | 6 +- src/keyexpr.rs | 24 +- src/liveliness.rs | 6 + src/payload.rs | 11 +- src/queryable.rs | 4 +- src/scouting.rs | 172 +++---------- tests/z_api_alignment_test.c | 6 +- tests/z_api_keyexpr_drop_test.c | 4 +- tests/z_int_pub_cache_query_sub_test.c | 2 +- tests/z_int_pub_sub_attachment_test.c | 2 +- tests/z_int_pub_sub_test.c | 2 +- tests/z_int_queryable_attachment_test.c | 4 +- tests/z_int_queryable_test.c | 4 +- 56 files changed, 1081 insertions(+), 794 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3120c2703..93eda3119 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3227,7 +3227,7 @@ dependencies = [ [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "ahash", "async-trait", @@ -3283,7 +3283,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "zenoh-collections", ] @@ -3319,7 +3319,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "serde", "tracing", @@ -3332,12 +3332,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "flume", "json5", @@ -3357,7 +3357,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-global-executor", "lazy_static", @@ -3369,7 +3369,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "aes", "hmac", @@ -3382,7 +3382,7 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "bincode", "flume", @@ -3401,7 +3401,7 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3415,7 +3415,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "zenoh-config", @@ -3433,7 +3433,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "flume", @@ -3446,6 +3446,7 @@ dependencies = [ "tracing", "zenoh-buffers", "zenoh-codec", + "zenoh-config", "zenoh-core", "zenoh-protocol", "zenoh-result", @@ -3456,7 +3457,7 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "base64", @@ -3464,13 +3465,15 @@ dependencies = [ "quinn", "rustls 0.21.7", "rustls-native-certs 0.7.0", - "rustls-pemfile 2.0.0", + "rustls-pemfile 1.0.3", + "rustls-pki-types", "rustls-webpki 0.102.2", "secrecy", "tokio", "tokio-rustls 0.24.1", "tokio-util", "tracing", + "webpki-roots", "zenoh-collections", "zenoh-config", "zenoh-core", @@ -3485,7 +3488,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "tokio", @@ -3503,7 +3506,7 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "base64", @@ -3532,7 +3535,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "socket2 0.5.6", @@ -3553,7 +3556,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "futures", @@ -3573,7 +3576,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "futures-util", @@ -3594,7 +3597,7 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "proc-macro2", "quote", @@ -3605,7 +3608,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "const_format", "libloading", @@ -3621,7 +3624,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "const_format", "rand", @@ -3636,7 +3639,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "anyhow", ] @@ -3644,7 +3647,7 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "futures", "lazy_static", @@ -3652,6 +3655,7 @@ dependencies = [ "ron", "serde", "tokio", + "tracing", "zenoh-collections", "zenoh-macros", "zenoh-protocol", @@ -3661,7 +3665,7 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "bincode", @@ -3685,7 +3689,7 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "event-listener 4.0.0", "futures", @@ -3699,7 +3703,7 @@ dependencies = [ [[package]] name = "zenoh-task" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "futures", "tokio", @@ -3712,7 +3716,7 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "flume", @@ -3745,7 +3749,7 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-std", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 1b5582b26..cdb229c21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,10 +53,10 @@ spin = "0.9.5" unwrap-infallible = "0.1.5" const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes", features = ["unstable"] } [build-dependencies] diff --git a/Cargo.toml.in b/Cargo.toml.in index 80c4f40ec..11f319f93 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -53,10 +53,10 @@ spin = "0.9.5" unwrap-infallible = "0.1.5" const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes", features = ["unstable"] } [build-dependencies] diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index ec5cafe8e..061e20b9a 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -2606,7 +2606,7 @@ dependencies = [ [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "ahash", "async-trait", @@ -2662,7 +2662,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "zenoh-collections", ] @@ -2670,7 +2670,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "serde", "tracing", @@ -2683,12 +2683,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "flume", "json5", @@ -2708,7 +2708,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-global-executor", "lazy_static", @@ -2720,7 +2720,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "aes", "hmac", @@ -2733,7 +2733,7 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "bincode", "flume", @@ -2752,7 +2752,7 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "hashbrown 0.14.3", "keyed-set", @@ -2766,7 +2766,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "zenoh-config", @@ -2778,7 +2778,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "flume", @@ -2791,6 +2791,7 @@ dependencies = [ "tracing", "zenoh-buffers", "zenoh-codec", + "zenoh-config", "zenoh-core", "zenoh-protocol", "zenoh-result", @@ -2801,7 +2802,7 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "proc-macro2", "quote", @@ -2812,7 +2813,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "const_format", "libloading", @@ -2828,7 +2829,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "const_format", "rand", @@ -2843,7 +2844,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "anyhow", ] @@ -2851,7 +2852,7 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "futures", "lazy_static", @@ -2859,6 +2860,7 @@ dependencies = [ "ron", "serde", "tokio", + "tracing", "zenoh-collections", "zenoh-macros", "zenoh-protocol", @@ -2868,7 +2870,7 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "bincode", @@ -2892,7 +2894,7 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "event-listener 4.0.3", "futures", @@ -2906,7 +2908,7 @@ dependencies = [ [[package]] name = "zenoh-task" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "futures", "tokio", @@ -2919,7 +2921,7 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-trait", "flume", @@ -2951,7 +2953,7 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=protocol_changes#10212610a7231d55e8e79b30f51165f1f2d05d49" dependencies = [ "async-std", "async-trait", diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml index 4d976ea98..2d95b5a5c 100644 --- a/build-resources/opaque-types/Cargo.toml +++ b/build-resources/opaque-types/Cargo.toml @@ -7,6 +7,6 @@ edition = "2021" [dependencies] # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes", features = ["shared-memory", "unstable"], default-features = false } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "protocol_changes", features = ["unstable"] } const_format = "0.2.32" diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 0d870a510..90e744dbf 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -18,6 +18,7 @@ use zenoh::query::Reply; use zenoh::queryable::Query; use zenoh::queryable::Queryable; use zenoh::sample::Sample; +use zenoh::scouting::Hello; use zenoh::session::Session; use zenoh::subscriber::Subscriber; use zenoh::time::Timestamp; @@ -61,12 +62,17 @@ get_opaque_type_data!(Option>, z_owned_str_t); get_opaque_type_data!(Option<&'static [u8]>, z_view_str_t); get_opaque_type_data!(&'static [u8], z_loaned_str_t); -/// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. +/// A map of maybe-owned slices to maybe-owned slices. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher get_opaque_type_data!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_loaned_slice_map_t); +/// An array of maybe-owned slices +/// +get_opaque_type_data!(Option>>, z_owned_slice_array_t); +get_opaque_type_data!(Vec>, z_loaned_slice_array_t); + /// An owned sample. /// /// This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. @@ -272,4 +278,14 @@ get_opaque_type_data!((Mutex<()>, Option>), z_loaned_mut get_opaque_type_data!(Option, z_owned_condvar_t); get_opaque_type_data!(Condvar, z_loaned_condvar_t); -get_opaque_type_data!(Option>, z_owned_task_t); \ No newline at end of file +get_opaque_type_data!(Option>, z_owned_task_t); + +/// A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +get_opaque_type_data!(Option, z_owned_hello_t); +get_opaque_type_data!(Hello, z_loaned_hello_t); \ No newline at end of file diff --git a/build.rs b/build.rs index 2a1c263bf..e059fabd6 100644 --- a/build.rs +++ b/build.rs @@ -767,6 +767,9 @@ pub fn create_generics_header(path_in: &str, path_out: &str) { .unwrap(); let header = "#pragma once + +#define z_move(x) (&x) + // clang-format off #ifndef __cplusplus @@ -1052,21 +1055,11 @@ pub fn generate_generic_call_c(macro_func: &Vec) -> String { } pub fn generate_generic_closure_c( - macro_func: &Vec + _macro_func: &Vec ) -> String { - let mut out = "#define z_closure(x, callback, dropper, ctx) \\ - _Generic((x)" + let out = "#define z_closure(x, callback, dropper, ctx) \\ + {{(x)->context = (void*)(ctx); (x)->call = (callback); (x)->drop = (dropper);}}" .to_owned(); - - for func in macro_func { - let owned_type = &func.arg_type_and_name[0].typename; - out += ", \\\n"; - out += &format!( -" {owned_type} * : {{ x->context = (void*)ctx; x->call = callback; x->drop = droper; }}"); - } - out += " \\\n"; - out += " )"; - out } diff --git a/docs/api.rst b/docs/api.rst index a5b0e1eea..f7af3cf82 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -110,7 +110,7 @@ Key expression .. 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_loaned_keyexpr_to_string +.. autocfunction:: zenoh_commons.h::z_keyexpr_to_string .. autocfunction:: zenoh_commons.h::z_keyexpr_as_bytes .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize_null_terminated diff --git a/docs/examples.rst b/docs/examples.rst index 1aab457a6..4bcf21d43 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -44,7 +44,7 @@ Subscribe #include "zenoh.h" void data_handler(const z_loaned_sample_t *sample, const void *arg) { - z_owned_str_t keystr = z_loaned_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); printf(">> Received (%s, %.*s)\n", keystr, (int)sample->payload.len, sample->payload.start); z_drop(z_move(keystr)); @@ -87,7 +87,7 @@ Query if (z_reply_is_ok(&reply)) { z_loaned_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_loaned_keyexpr_to_string(sample.keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); printf(">> Received ('%s': '%.*s')\n", keystr, (int)sample.payload.len, sample.payload.start); z_drop(z_move(keystr)); } diff --git a/examples/z_delete.c b/examples/z_delete.c index 6f364dc80..7ff5e3078 100644 --- a/examples/z_delete.c +++ b/examples/z_delete.c @@ -24,7 +24,7 @@ int main(int argc, char **argv) { z_owned_config_t config; z_config_default(&config); if (argc > 3) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -41,15 +41,13 @@ int main(int argc, char **argv) { } printf("Deleting resources matching '%s'...\n", keyexpr); - z_delete_options_t options = z_delete_options_default(); - z_owned_keyexpr_t ke; - z_keyexpr(&ke, keyexpr); - int res = z_delete(z_loan(s), z_loan(ke), &options); + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, keyexpr); + int res = z_delete(z_loan(s), z_loan(ke), NULL); if (res < 0) { printf("Delete failed...\n"); } - z_keyexpr_drop(z_move(ke)); z_close(z_move(s)); return 0; } diff --git a/examples/z_get.c b/examples/z_get.c index 00eb2a524..5973f43c5 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -30,15 +30,15 @@ int main(int argc, char **argv) { // Do nothing break; } - z_owned_keyexpr_t keyexpr; - if (z_keyexpr(&keyexpr, expr) < 0) { + z_view_keyexpr_t keyexpr; + if (z_view_keyexpr(&keyexpr, expr) < 0) { printf("%s is not a valid key expression", expr); exit(-1); } z_owned_config_t config; z_config_default(&config); if (argc > 3) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -55,30 +55,41 @@ int main(int argc, char **argv) { } printf("Sending Query '%s'...\n", expr); - z_owned_reply_channel_t channel = zc_reply_fifo_new(16); - z_get_options_t opts = z_get_options_default(); + z_owned_reply_channel_t channel; + zc_reply_fifo_new(&channel, 16); + + z_get_options_t opts; + z_get_options_default(&opts); + z_owned_bytes_t payload; + z_view_str_t value_str; if (value != NULL) { - z_bytes_encode_from_string(&payload, value); + z_view_str_wrap(&value_str, value); + z_bytes_encode_from_string(&payload, z_loan(value_str)); opts.payload = &payload; } z_get(z_loan(s), z_loan(keyexpr), "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply; - z_owned_str_t reply_str; + for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(z_loan(reply))) { - z_loaned_sample_t sample = z_reply_ok(z_loan(reply)); - z_owned_str_t key_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_bytes_decode_into_string(z_sample_payload(&sample), &reply_str); - printf(">> Received ('%s': '%s')\n", z_loan(key_str), z_loan(reply_str)); + const z_loaned_sample_t* sample = z_reply_ok(z_loan(reply)); + + z_owned_str_t key_str; + z_keyexpr_to_string(z_sample_keyexpr(sample), &key_str); + + z_owned_str_t reply_str; + z_bytes_decode_into_string(z_sample_payload(sample), &reply_str); + + printf(">> Received ('%s': '%s')\n", z_str_data(z_loan(key_str)), z_str_data(z_loan(reply_str))); z_drop(z_move(reply_str)); z_drop(z_move(key_str)); } else { printf("Received an error\n"); } } - z_drop(z_move(keyexpr)); + z_drop(z_move(reply)); z_drop(z_move(channel)); z_close(z_move(s)); diff --git a/examples/z_get_liveliness.c b/examples/z_get_liveliness.c index 025b09db3..ffcd58d9b 100644 --- a/examples/z_get_liveliness.c +++ b/examples/z_get_liveliness.c @@ -22,8 +22,8 @@ int main(int argc, char **argv) { expr = argv[1]; } - z_owned_keyexpr_t keyexpr; - if (z_keyexpr(&keyexpr, expr) < 0) { + z_view_keyexpr_t keyexpr; + if (z_view_keyexpr(&keyexpr, expr) < 0) { printf("%s is not a valid key expression\n", expr); exit(-1); } @@ -31,7 +31,7 @@ int main(int argc, char **argv) { z_owned_config_t config; z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -48,21 +48,22 @@ int main(int argc, char **argv) { } printf("Sending liveliness query '%s'...\n", expr); - z_owned_reply_channel_t channel = zc_reply_fifo_new(16); + z_owned_reply_channel_t channel; + zc_reply_fifo_new(&channel, 16); zc_liveliness_get(z_loan(s), z_loan(keyexpr), z_move(channel.send), NULL); z_owned_reply_t reply; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(z_loan(reply))) { - z_loaned_sample_t sample = z_reply_ok(z_loan(reply)); - z_owned_str_t key_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); - printf(">> Alive token ('%s')\n", z_loan(key_str)); + const z_loaned_sample_t* sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_str; + z_keyexpr_to_string(z_sample_keyexpr(sample), &key_str); + printf(">> Alive token ('%s')\n", z_str_data(z_loan(key_str))); z_drop(z_move(key_str)); } else { printf("Received an error\n"); } } - z_drop(z_move(keyexpr)); z_drop(z_move(reply)); z_drop(z_move(channel)); z_close(z_move(s)); diff --git a/examples/z_info.c b/examples/z_info.c index d9db2e6d9..49b900ce8 100644 --- a/examples/z_info.c +++ b/examples/z_info.c @@ -23,9 +23,10 @@ void print_zid(const z_id_t *id, void *ctx) { } int main(int argc, char **argv) { - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 1) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[1]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[1]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -35,8 +36,8 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } @@ -46,13 +47,15 @@ int main(int argc, char **argv) { print_zid(&self_id, NULL); printf("routers ids:\n"); - z_owned_closure_zid_t callback = z_closure(print_zid); + z_owned_closure_zid_t callback; + z_closure(&callback, print_zid, NULL, NULL); z_info_routers_zid(z_loan(s), z_move(callback)); // `callback` has been `z_move`d just above, so it's safe to reuse the variable, // we'll just have to make sure we `z_move` it again to avoid mem-leaks. printf("peers ids:\n"); - z_owned_closure_zid_t callback2 = z_closure(print_zid); + z_owned_closure_zid_t callback2; + z_closure(&callback, print_zid, NULL, NULL); z_info_peers_zid(z_loan(s), z_move(callback2)); z_close(z_move(s)); diff --git a/examples/z_liveliness.c b/examples/z_liveliness.c index bc71da8eb..5359fcde9 100644 --- a/examples/z_liveliness.c +++ b/examples/z_liveliness.c @@ -21,15 +21,16 @@ int main(int argc, char **argv) { expr = argv[1]; } - z_loaned_keyexpr_t keyexpr = z_keyexpr(expr); - if (!z_check(keyexpr)) { + z_view_keyexpr_t keyexpr; + if (z_view_keyexpr(&keyexpr, expr) < 0) { printf("%s is not a valid key expression\n", expr); exit(-1); } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -39,15 +40,15 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config))) { printf("Unable to open session!\n"); exit(-1); } printf("Declaring liveliness token '%s'...\n", expr); - zc_owned_liveliness_token_t token = zc_liveliness_declare_token(z_loan(s), keyexpr, NULL); - if (!z_check(token)) { + zc_owned_liveliness_token_t token; + if (zc_liveliness_declare_token(&token, z_loan(s), z_loan(keyexpr), NULL) < 0) { printf("Unable to create liveliness token!\n"); exit(-1); } diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index c84074e67..64929d0ca 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -21,14 +21,15 @@ int main(int argc, char **argv) { if (argc > 1) { expr = argv[1]; } - z_loaned_keyexpr_t keyexpr = z_keyexpr(expr); - if (!z_check(keyexpr)) { + z_view_keyexpr_t keyexpr; + if (z_view_keyexpr(&keyexpr, expr) < 0) { printf("%s is not a valid key expression", expr); exit(-1); } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -38,31 +39,34 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config))) { printf("Unable to open session!\n"); exit(-1); } printf("Sending Query '%s'...\n", expr); - z_get_options_t opts = z_get_options_default(); - opts.target = Z_QUERY_TARGET_ALL; - z_owned_reply_channel_t channel = zc_reply_non_blocking_fifo_new(16); - z_get(z_loan(s), keyexpr, "", z_move(channel.send), + z_get_options_t opts; + z_get_options_default(&opts); + opts.target = Z_LOANED_QUERY_TARGET_ALL; + z_owned_reply_channel_t channel; + zc_reply_non_blocking_fifo_new(&channel, 16); + z_get(z_loan(s), z_loan(keyexpr), "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate - z_owned_reply_t reply = z_reply_null(); - z_owned_str_t payload_value = z_str_null(); + z_owned_reply_t reply; for (bool call_success = z_call(channel.recv, &reply); !call_success || z_check(reply); call_success = z_call(channel.recv, &reply)) { if (!call_success) { continue; } - if (z_reply_is_ok(&reply)) { - z_loaned_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); - printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); - z_drop(z_move(payload_value)); + if (z_reply_is_ok(z_loan(reply))) { + const z_loaned_sample_t* sample = z_reply_ok(z_loan(reply)); + z_owned_str_t keystr; + z_owned_str_t payload_string; + z_keyexpr_to_string(z_sample_keyexpr(sample), &keystr); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_string); + printf(">> Received ('%s': '%s')\n", z_str_data(z_loan(keystr)), z_str_data(z_loan(payload_string))); + z_drop(z_move(payload_string)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_ping.c b/examples/z_ping.c index 87dc697ab..c5f531320 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -13,11 +13,11 @@ #define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) -z_loaned_condvar_t cond; -z_loaned_mutex_t mutex; +z_owned_condvar_t cond; +z_owned_mutex_t mutex; -void callback(const z_loaned_sample_t* sample, void* context) { z_condvar_signal(&cond); } -void drop(void* context) { z_condvar_free(&cond); } +void callback(const z_loaned_sample_t* sample, void* context) { z_condvar_signal(z_loan(cond)); } +void drop(void* context) { z_drop(z_move(cond)); } struct args_t { unsigned int size; // -s @@ -43,27 +43,42 @@ int main(int argc, char** argv) { } z_mutex_init(&mutex); z_condvar_init(&cond); - z_owned_config_t config = args.config_path ? zc_config_from_file(args.config_path) : z_config_default(); - z_owned_session_t session = z_open(z_move(config)); - z_loaned_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); - z_loaned_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); - z_owned_publisher_t pub = z_declare_publisher(z_loan(session), ping, NULL); - z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)(&pub)); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), pong, z_move(respond), NULL); + z_owned_config_t config; + if (args.config_path) { + zc_config_from_file(&config, args.config_path); + } else { + z_config_default(&config); + } + z_owned_session_t session; + z_open(&session, z_move(config)); + z_view_keyexpr_t ping; + z_view_keyexpr_unchecked(&ping, "test/ping"); + z_view_keyexpr_t pong; + z_view_keyexpr_unchecked(&pong, "test/pong"); + z_owned_publisher_t pub; + z_declare_publisher(&pub, z_loan(session), z_loan(ping), NULL); + z_owned_closure_sample_t respond; + z_closure(&respond, callback, drop, (void*)(&pub)); + z_owned_subscriber_t sub; + z_declare_subscriber(&sub, z_loan(session), z_loan(pong), z_move(respond), NULL); uint8_t* data = z_malloc(args.size); for (int i = 0; i < args.size; i++) { data[i] = i % 10; } - z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_loaned_slice_t){.start = data, .len = args.size}); - z_mutex_lock(&mutex); + z_owned_bytes_t payload; + z_view_slice_t data_slice; + z_view_slice_wrap(&data_slice, data, args.size); + + z_mutex_lock(z_loan_mut(mutex)); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); z_clock_t warmup_start = z_clock_now(); unsigned long elapsed_us = 0; while (elapsed_us < args.warmup_ms * 1000) { + z_bytes_encode_from_slice(&payload, z_loan(data_slice)); z_publisher_put(z_loan(pub), z_move(payload), NULL); - int s = z_condvar_wait(&cond, &mutex); + int s = z_condvar_wait(z_loan(cond), z_loan_mut(mutex)); if (s != 0) { handle_error_en(s, "z_condvar_wait"); } @@ -74,7 +89,7 @@ int main(int argc, char** argv) { for (int i = 0; i < args.number_of_pings; i++) { z_clock_t measure_start = z_clock_now(); z_publisher_put(z_loan(pub), z_move(payload), NULL); - int s = z_condvar_wait(&cond, &mutex); + int s = z_condvar_wait(z_loan(cond), z_loan_mut(mutex)); if (s != 0) { handle_error_en(s, "z_condvar_wait"); } @@ -83,11 +98,12 @@ int main(int argc, char** argv) { for (int i = 0; i < args.number_of_pings; i++) { printf("%d bytes: seq=%d rtt=%luµs, lat=%luµs\n", args.size, i, results[i], results[i] / 2); } - z_mutex_unlock(&mutex); + z_mutex_unlock(z_loan_mut(mutex)); z_free(results); z_free(data); - z_drop(z_move(sub)); - z_drop(z_move(pub)); + z_undeclare_subscriber(z_move(sub)); + z_undeclare_publisher(z_move(pub)); + z_drop(z_move(mutex)); z_close(z_move(session)); } diff --git a/examples/z_pong.c b/examples/z_pong.c index b8920f70d..d1f2b4a90 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -4,15 +4,16 @@ #include "zenoh.h" void callback(const z_loaned_sample_t* sample, void* context) { - z_loaned_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); + const z_loaned_publisher_t* pub = z_loan(*(z_owned_publisher_t*)context); #ifdef ZENOH_C // The z_owned_bytes_t API is exclusive to zenoh-c, but allows avoiding some copies. - z_owned_bytes_t payload = z_sample_owned_payload(sample); + z_owned_bytes_t payload; + z_bytes_clone(z_sample_payload(sample), &payload); z_publisher_put(pub, z_move(payload), NULL); #endif } void drop(void* context) { z_owned_publisher_t* pub = (z_owned_publisher_t*)context; - z_drop(pub); + z_undeclare_publisher(z_move(*pub)); // A note on lifetimes: // here, `sub` takes ownership of `pub` and will drop it before returning from its own `drop`, // which makes passing a pointer to the stack safe as long as `sub` is dropped in a scope where `pub` is still @@ -32,16 +33,27 @@ int main(int argc, char** argv) { "default configuration will be used.\n"); return 1; } - z_owned_config_t config = args.config_path ? zc_config_from_file(args.config_path) : z_config_default(); - z_owned_session_t session = z_open(z_move(config)); - z_loaned_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); - z_loaned_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); - z_owned_publisher_t pub = z_declare_publisher(z_loan(session), pong, NULL); - z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)z_move(pub)); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), ping, z_move(respond), NULL); + z_owned_config_t config; + if (args.config_path) { + zc_config_from_file(&config, args.config_path); + } else { + z_config_default(&config); + } + z_owned_session_t session; + z_open(&session, z_move(config)); + z_view_keyexpr_t ping; + z_view_keyexpr_unchecked(&ping, "test/ping"); + z_view_keyexpr_t pong; + z_view_keyexpr_unchecked(&pong, "test/pong"); + z_owned_publisher_t pub; + z_declare_publisher(&pub, z_loan(session), z_loan(pong), NULL); + z_owned_closure_sample_t respond; + z_closure(&respond, callback, drop, (void*)z_move(pub)); + z_owned_subscriber_t sub; + z_declare_subscriber(&sub, z_loan(session), z_loan(ping), z_move(respond), NULL); while (getchar() != 'q') { } - z_drop(z_move(sub)); + z_undeclare_subscriber(z_move(sub)); z_close(z_move(session)); } diff --git a/examples/z_pub.c b/examples/z_pub.c index 29ccd5c8e..e9ab32751 100644 --- a/examples/z_pub.c +++ b/examples/z_pub.c @@ -33,9 +33,10 @@ int main(int argc, char **argv) { if (argc > 2) value = argv[2]; if (argc > 3) add_matching_listener = atoi(argv[3]); - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 4) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[4]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[4]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -45,38 +46,46 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } printf("Declaring Publisher on '%s'...\n", keyexpr); - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); - if (!z_check(pub)) { + z_owned_publisher_t pub; + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, keyexpr); + if (z_declare_publisher(&pub, z_loan(s), z_loan(ke), NULL) < 0) { printf("Unable to declare Publisher for key expression!\n"); exit(-1); } zcu_owned_matching_listener_t listener; if (add_matching_listener) { - zcu_owned_closure_matching_status_t callback = z_closure(matching_status_handler); - listener = zcu_publisher_matching_listener_callback(z_loan(pub), z_move(callback)); + zcu_owned_closure_matching_status_t callback; + z_closure(&callback, matching_status_handler, NULL, NULL); + zcu_publisher_matching_listener_callback(&listener, z_loan(pub), z_move(callback)); } - char buf[256]; + char buf[256] = {}; for (int idx = 0; 1; ++idx) { z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_publisher_put_options_t options = z_publisher_put_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_owned_bytes_t payload = z_bytes_encode_from_string(buf); + z_publisher_put_options_t options; + z_publisher_put_options_default(&options); + + z_view_str_t payload_str; + z_view_str_wrap(&payload_str, buf); + + z_owned_bytes_t payload; + z_bytes_encode_from_string(&payload, z_loan(payload_str)); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); - z_close(z_move(s)); return 0; } diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index c45b25811..81064c2c7 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -23,9 +23,10 @@ int main(int argc, char **argv) { if (argc > 1) keyexpr = argv[1]; if (argc > 2) value = argv[2]; - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 3) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -35,30 +36,35 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } printf("Declaring Publisher on '%s'...\n", keyexpr); - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); - if (!z_check(pub)) { + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, keyexpr); + z_owned_publisher_t pub; + if (z_declare_publisher(&pub, z_loan(s), z_loan(ke), NULL)) { printf("Unable to declare Publisher for key expression!\n"); exit(-1); } - z_publisher_put_options_t options = z_publisher_put_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); + z_publisher_put_options_t options; + z_publisher_put_options_default(&options); // allocate attachment map - z_owned_bytes_map_t map = z_slice_map_new(); - - // set it as an attachment - options.attachment = z_slice_map_as_attachment(&map); - + z_owned_slice_map_t map; + z_slice_map_new(&map); + z_view_slice_t src_key, src_value; + z_view_slice_from_str(&src_key, "source"); + z_view_slice_from_str(&src_value, "C"); // add some value - z_slice_map_insert_by_alias(&map, z_slice_from_str("source"), z_slice_from_str("C")); + z_slice_map_insert_by_alias(z_loan_mut(map), z_loan(src_key), z_loan(src_value)); + // allocate attachment and payload + z_owned_bytes_t attachment; + z_owned_bytes_t payload; char buf[256]; char buf_ind[16]; @@ -67,11 +73,19 @@ int main(int argc, char **argv) { // add some other attachment value sprintf(buf_ind, "%d", idx); - z_slice_map_insert_by_alias(&map, z_slice_from_str("index"), z_slice_from_str(buf_ind)); + z_view_slice_t index_key, index_value; + z_view_slice_from_str(&index_key, "index"); + z_view_slice_from_str(&index_value, buf_ind); + z_slice_map_insert_by_alias(z_loan_mut(map), z_loan(index_key), z_loan(index_value)); + z_bytes_encode_from_bytes_map(&attachment, z_loan(map)); + options.attachment = &attachment; sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_owned_bytes_t payload = z_bytes_encode_from_string(buf); + z_view_str_t payload_str; + z_view_str_wrap(&payload_str, buf); + + z_bytes_encode_from_string(&payload, z_loan(payload_str)); z_publisher_put(z_loan(pub), z_move(payload), &options); } diff --git a/examples/z_pub_cache.c b/examples/z_pub_cache.c index 7594fee1f..f21bed5f7 100644 --- a/examples/z_pub_cache.c +++ b/examples/z_pub_cache.c @@ -23,9 +23,10 @@ int main(int argc, char **argv) { if (argc > 1) keyexpr = argv[1]; if (argc > 2) value = argv[2]; - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 3) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -34,25 +35,28 @@ int main(int argc, char **argv) { } } - if (zc_config_insert_json(z_loan(config), Z_CONFIG_ADD_TIMESTAMP_KEY, "true") < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_ADD_TIMESTAMP_KEY, "true") < 0) { printf("Unable to configure timestamps!\n"); exit(-1); } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } - ze_publication_cache_options_t pub_cache_opts = ze_publication_cache_options_default(); + ze_publication_cache_options_t pub_cache_opts; + ze_publication_cache_options_default(&pub_cache_opts); pub_cache_opts.history = 42; pub_cache_opts.queryable_complete = false; printf("Declaring publication cache on '%s'...\n", keyexpr); - ze_owned_publication_cache_t pub_cache = - ze_declare_publication_cache(z_loan(s), z_keyexpr(keyexpr), &pub_cache_opts); + ze_owned_publication_cache_t pub_cache; + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, keyexpr); + ze_declare_publication_cache(&pub_cache, z_loan(s), z_loan(ke), &pub_cache_opts); if (!z_check(pub_cache)) { printf("Unable to declare publication cache for key expression!\n"); exit(-1); @@ -63,11 +67,15 @@ int main(int argc, char **argv) { z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_owned_bytes_t payload = z_bytes_encode_from_string(buf); - z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); + z_owned_bytes_t payload; + z_view_str_t payload_str; + z_view_str_wrap(&payload_str, buf); + z_bytes_encode_from_string(&payload, z_loan(payload_str)); + + z_put(z_loan(s), z_loan(ke), z_move(payload), NULL); } - z_drop(z_move(pub_cache)); + ze_undeclare_publication_cache(z_move(pub_cache)); z_close(z_move(s)); return 0; diff --git a/examples/z_pub_thr.c b/examples/z_pub_thr.c index c59f3f6c7..2610bcf63 100644 --- a/examples/z_pub_thr.c +++ b/examples/z_pub_thr.c @@ -27,9 +27,10 @@ int main(int argc, char **argv) { uint8_t *value = (uint8_t *)z_malloc(len); memset(value, 1, len); - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -38,23 +39,29 @@ int main(int argc, char **argv) { } } - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } - z_publisher_options_t options = z_publisher_options_default(); + z_publisher_options_t options; + z_publisher_options_default(&options); options.congestion_control = Z_CONGESTION_CONTROL_BLOCK; - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), &options); - if (!z_check(pub)) { + z_owned_publisher_t pub; + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, keyexpr); + if (z_declare_publisher(&pub, z_loan(s), z_loan(ke), &options)) { printf("Unable to declare publisher for key expression!\n"); exit(-1); } + z_owned_bytes_t payload; + z_view_slice_t payload_data; + z_view_slice_wrap(&payload_data, value, len); while (1) { - z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_loaned_slice_t){.start = value, .len = len}); + z_bytes_encode_from_slice(&payload, z_loan(payload_data)); z_publisher_put(z_loan(pub), z_move(payload), NULL); } diff --git a/examples/z_put.c b/examples/z_put.c index c74f95672..7f33ff2d8 100644 --- a/examples/z_put.c +++ b/examples/z_put.c @@ -23,12 +23,18 @@ int main(int argc, char **argv) { if (argc > 1) keyexpr = argv[1]; if (argc > 2) value = argv[2]; - z_owned_bytes_map_t attachment = z_slice_map_new(); - z_slice_map_insert_by_alias(&attachment, z_slice_from_str("hello"), z_slice_from_str("there")); + z_owned_slice_map_t attachment_map; + z_slice_map_new(&attachment_map); + z_view_slice_t map_key, map_value; + z_view_slice_from_str(&map_key, "hello"); + z_view_slice_from_str(&map_value, "there"); + z_slice_map_insert_by_alias(z_loan_mut(attachment_map), z_loan(map_key), z_loan(map_value)); + + z_owned_config_t config; + z_config_default(&config); - z_owned_config_t config = z_config_default(); if (argc > 3) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -38,23 +44,36 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } printf("Putting Data ('%s': '%s')...\n", keyexpr, value); - z_put_options_t options = z_put_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - options.attachment = z_slice_map_as_attachment(&attachment); - z_owned_bytes_t payload = z_bytes_encode_from_string(value); - int res = z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), &options); + + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, keyexpr); + + z_view_str_t payload_string; + z_view_str_wrap(&payload_string, value); + + z_owned_bytes_t payload; + z_bytes_encode_from_string(&payload, z_loan(payload_string)); + + z_owned_bytes_t attachment; + z_bytes_encode_from_bytes_map(&attachment, z_loan(attachment_map)); + + z_put_options_t options; + z_put_options_default(&options); + options.attachment = &attachment; // attachement is going to be consumed by z_put, so no need to drop it manually + + int res = z_put(z_loan(s), z_loan(ke), z_move(payload), &options); if (res < 0) { printf("Put failed...\n"); } z_close(z_move(s)); - z_drop(z_move(attachment)); + z_drop(z_move(attachment_map)); return 0; } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index 4a2d72cc9..c2b7fceb7 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -17,24 +17,29 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_loaned_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); - printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload_value)); - z_drop(z_move(payload_value)); - z_drop(z_move(keystr)); + z_owned_str_t key_string; + z_keyexpr_to_string(z_sample_keyexpr(sample), &key_string); + + z_owned_str_t payload_string; + z_bytes_decode_into_string(z_sample_payload(sample), &payload_string); + + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), + z_str_data(z_loan(key_string)), z_str_data(z_loan(payload_string)) + ); + z_drop(z_move(payload_string)); + z_drop(z_move(key_string)); } int main(int argc, char **argv) { - char *expr = "demo/example/**"; + char *keyexpr = "demo/example/**"; if (argc > 1) { - expr = argv[1]; + keyexpr = argv[1]; } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -44,18 +49,24 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config))) { printf("Unable to open session!\n"); exit(-1); } - ze_querying_subscriber_options_t sub_opts = ze_querying_subscriber_options_default(); - z_owned_closure_sample_t callback = z_closure(data_handler); - printf("Declaring querying subscriber on '%s'...\n", expr); - ze_owned_querying_subscriber_t sub = - ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), z_move(callback), &sub_opts); - if (!z_check(sub)) { + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, keyexpr); + + ze_querying_subscriber_options_t sub_opts; + ze_querying_subscriber_options_default(&sub_opts); + + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); + printf("Declaring querying subscriber on '%s'...\n", keyexpr); + + ze_owned_querying_subscriber_t sub; + if (ze_declare_querying_subscriber(&sub, z_loan(s), z_loan(ke), z_move(callback), &sub_opts) < 0) { printf("Unable to declare querying subscriber.\n"); exit(-1); } @@ -69,7 +80,7 @@ int main(int argc, char **argv) { } } - z_drop(z_move(sub)); + ze_undeclare_querying_subscriber(z_move(sub)); z_close(z_move(s)); return 0; diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 191daf413..c3618081d 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -15,38 +15,53 @@ #include #include "zenoh.h" -const char *expr = "demo/example/zenoh-c-queryable"; +const char *keyexpr = "demo/example/zenoh-c-queryable"; const char *value = "Queryable from C!"; -z_loaned_keyexpr_t keyexpr; +z_view_keyexpr_t ke; void query_handler(const z_loaned_query_t *query, void *context) { - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); - z_loaned_slice_t pred = z_query_parameters(query); - z_loaned_bytes_t payload = z_query_value(query).payload; + z_owned_str_t key_string; + z_keyexpr_to_string(z_query_keyexpr(query), &key_string); + + z_view_slice_t params; + z_query_parameters(query, ¶ms); + + const z_loaned_bytes_t* payload = z_value_payload(z_query_value(query)); if (z_bytes_len(payload) > 0) { - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(payload, &payload_value); - printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, - pred.start, z_loan(payload_value)); - z_drop(z_move(payload_value)); + z_owned_str_t payload_string; + z_bytes_decode_into_string(payload, &payload_string); + + printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", + z_str_data(z_loan(key_string)), (int)z_slice_len(z_loan(params)), (const char*)z_slice_data(z_loan(params)), + z_str_data(z_loan(payload_string))); + z_drop(z_move(payload_string)); } else { - printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); + printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_str_data(z_loan(key_string)), + (int)z_slice_len(z_loan(params)), (const char*)z_slice_data(z_loan(params))); } - z_query_reply_options_t options = z_query_reply_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); + z_query_reply_options_t options; + z_query_reply_options_default(&options); - z_owned_bytes_t reply_payload = z_bytes_encode_from_string(value); - z_query_reply(query, z_keyexpr((const char *)context), z_move(reply_payload), &options); - z_drop(z_move(keystr)); + z_view_str_t reply_string; + z_view_str_wrap(&reply_string, value); + z_owned_bytes_t reply_payload; + z_bytes_encode_from_string(&reply_payload, z_loan(reply_string)); + + z_view_keyexpr_t reply_keyexpr; + z_view_keyexpr(&reply_keyexpr, (const char *)context); + + z_query_reply(query, z_loan(reply_keyexpr), z_move(reply_payload), &options); + z_drop(z_move(key_string)); } int main(int argc, char **argv) { if (argc > 1) { - expr = argv[1]; + keyexpr = argv[1]; } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -56,21 +71,23 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config))) { printf("Unable to open session!\n"); exit(-1); } - keyexpr = z_keyexpr(expr); - if (!z_check(keyexpr)) { - printf("%s is not a valid key expression", expr); + + if (z_view_keyexpr(&ke, keyexpr)) { + printf("%s is not a valid key expression", keyexpr); exit(-1); } - printf("Declaring Queryable on '%s'...\n", expr); - z_owned_closure_query_t callback = z_closure(query_handler, NULL, expr); - z_owned_queryable_t qable = z_declare_queryable(z_loan(s), keyexpr, z_move(callback), NULL); - if (!z_check(qable)) { + printf("Declaring Queryable on '%s'...\n", keyexpr); + z_owned_closure_query_t callback; + z_closure(&callback, query_handler, NULL, (void*)keyexpr); + z_owned_queryable_t qable; + + if (z_declare_queryable(&qable, z_loan(s), z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to create queryable.\n"); exit(-1); } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 0fec21120..13a79be4a 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -16,23 +16,25 @@ #include #include "zenoh.h" -const char *expr = "demo/example/zenoh-c-queryable"; +const char *keyexpr = "demo/example/zenoh-c-queryable"; const char *value = "Queryable from C!"; -z_loaned_keyexpr_t keyexpr; +z_view_keyexpr_t ke; void query_handler(const z_loaned_query_t *query, void *context) { z_owned_closure_owned_query_t *channel = (z_owned_closure_owned_query_t *)context; - z_owned_query_t oquery = z_query_clone(query); + z_owned_query_t oquery; + z_query_clone(query, &oquery); z_call(*channel, &oquery); } int main(int argc, char **argv) { if (argc > 1) { - expr = argv[1]; + keyexpr = argv[1]; } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -42,52 +44,68 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } - keyexpr = z_keyexpr(expr); - if (!z_check(keyexpr)) { - printf("%s is not a valid key expression", expr); + + if (z_view_keyexpr(&ke, keyexpr) < 0) { + printf("%s is not a valid key expression", keyexpr); exit(-1); } - printf("Declaring Queryable on '%s'...\n", expr); - z_owned_query_channel_t channel = zc_query_fifo_new(16); - z_owned_closure_query_t callback = z_closure(query_handler, NULL, &channel.send); - z_owned_queryable_t qable = z_declare_queryable(z_loan(s), keyexpr, z_move(callback), NULL); - if (!z_check(qable)) { + printf("Declaring Queryable on '%s'...\n", keyexpr); + z_owned_query_channel_t channel; + zc_query_fifo_new(&channel, 16); + z_owned_closure_query_t callback; + z_closure(&callback, query_handler, NULL, (void*)&channel.send); + z_owned_queryable_t qable; + + if (z_declare_queryable(&qable, z_loan(s), z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to create queryable.\n"); exit(-1); } printf("^C to quit...\n"); - z_owned_query_t oquery = z_query_null(); + z_owned_query_t oquery; for (z_call(channel.recv, &oquery); z_check(oquery); z_call(channel.recv, &oquery)) { - z_loaned_query_t query = z_loan(oquery); - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(&query)); - z_loaned_slice_t pred = z_query_parameters(&query); - z_loaned_bytes_t payload = z_query_value(&query).payload; + const z_loaned_query_t* query = z_loan(oquery); + z_owned_str_t key_string; + z_keyexpr_to_string(z_query_keyexpr(query), &key_string); + + z_view_slice_t params; + z_query_parameters(query, ¶ms); + + const z_loaned_bytes_t* payload = z_value_payload(z_query_value(query)); if (z_bytes_len(payload) > 0) { - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(payload, &payload_value); - printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, - pred.start, z_loan(payload_value)); - z_drop(z_move(payload_value)); + z_owned_str_t payload_string; + z_bytes_decode_into_string(payload, &payload_string); + + printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_str_data(z_loan(key_string)), + (int)z_slice_len(z_loan(params)), (const char*)z_slice_data(z_loan(params)), + z_str_data(z_loan(payload_string)) + ); + z_drop(z_move(payload_string)); } else { - printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); + printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_str_data(z_loan(key_string)), + (int)z_slice_len(z_loan(params)), (const char*)z_slice_data(z_loan(params)) + ); } - z_query_reply_options_t options = z_query_reply_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_owned_bytes_t reply_payload = z_bytes_encode_from_string(value); - z_query_reply(&query, keyexpr, z_move(reply_payload), &options); - z_drop(z_move(keystr)); + z_query_reply_options_t options; + z_query_reply_options_default(&options); + + z_view_str_t reply_string; + z_view_str_wrap(&reply_string, value); + z_owned_bytes_t reply_payload; + z_bytes_encode_from_string(&reply_payload, z_loan(reply_string)); + z_query_reply(query, z_loan(ke), z_move(reply_payload), &options); + z_drop(z_move(key_string)); z_drop(z_move(oquery)); } - z_drop(z_move(qable)); + z_undeclare_queryable(z_move(qable)); z_drop(z_move(channel)); - z_drop(z_move(s)); + z_close(z_move(s)); return 0; } diff --git a/examples/z_scout.c b/examples/z_scout.c index 1b7b3c21d..aeacb37bc 100644 --- a/examples/z_scout.c +++ b/examples/z_scout.c @@ -38,32 +38,37 @@ void fprintwhatami(FILE *stream, unsigned int whatami) { fprintf(stream, "%s", buf); } -void fprintlocators(FILE *stream, const z_str_array_t *locs) { +void fprintlocators(FILE *stream, const z_loaned_slice_array_t *locs) { fprintf(stream, "["); - for (unsigned int i = 0; i < locs->len; i++) { + for (unsigned int i = 0; i < z_slice_array_len(locs); i++) { fprintf(stream, "\""); - fprintf(stream, "%s", locs->val[i]); + const z_loaned_slice_t *loc = z_slice_array_get(locs, i); + fprintf(stream, "%.*s", (int)z_slice_len(loc), (const char*)z_slice_data(loc)); fprintf(stream, "\""); - if (i < locs->len - 1) { + if (i < z_slice_array_len(locs) - 1) { fprintf(stream, ", "); } } fprintf(stream, "]"); } -void fprinthello(FILE *stream, const z_hello_t hello) { +void fprinthello(FILE *stream, const z_loaned_hello_t* hello) { fprintf(stream, "Hello { pid: "); - fprintpid(stream, hello.pid); + fprintpid(stream, z_hello_zid(hello)); fprintf(stream, ", whatami: "); - fprintwhatami(stream, hello.whatami); + fprintwhatami(stream, z_hello_whatami(hello)); + fprintf(stream, ", locators: "); - fprintlocators(stream, &hello.locators); + z_owned_slice_array_t locators; + z_hello_locators(hello, &locators); + fprintlocators(stream, z_loan(locators)); + z_slice_array_drop(z_move(locators)); + fprintf(stream, " }"); } -void callback(z_owned_hello_t *hello, void *context) { - z_hello_t lhello = z_loan(*hello); - fprinthello(stdout, lhello); +void callback(const z_loaned_hello_t *hello, void *context) { + fprinthello(stdout, hello); fprintf(stdout, "\n"); (*(int *)context)++; } @@ -80,8 +85,11 @@ void drop(void *context) { int main(int argc, char **argv) { int *context = z_malloc(sizeof(int)); *context = 0; - z_owned_scouting_config_t config = z_scouting_config_default(); - z_owned_closure_hello_t closure = z_closure(callback, drop, context); + z_owned_scouting_config_t config; + z_scouting_config_default(&config); + + z_owned_closure_hello_t closure; + z_closure(&closure, callback, drop, context); printf("Scouting...\n"); z_scout(z_move(config), z_move(closure)); z_sleep_s(1); diff --git a/examples/z_sub.c b/examples/z_sub.c index f5b986634..144880e7b 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -17,24 +17,32 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_loaned_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); - printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload_value)); - z_drop(z_move(payload_value)); - z_drop(z_move(keystr)); + z_owned_str_t key_string; + z_keyexpr_to_string(z_sample_keyexpr(sample), &key_string); + + z_owned_str_t payload_string; + z_bytes_decode_into_string(z_sample_payload(sample), &payload_string); + + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), + z_str_data(z_loan(key_string)), z_str_data(z_loan(payload_string)) + ); + z_drop(z_move(payload_string)); + z_drop(z_move(key_string)); } int main(int argc, char **argv) { - char *expr = "demo/example/**"; + char *keyexpr = "demo/example/**"; if (argc > 1) { - expr = argv[1]; + keyexpr = argv[1]; } - z_owned_config_t config = z_config_default(); + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, keyexpr); + + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -45,22 +53,23 @@ int main(int argc, char **argv) { // A probing procedure for shared memory is performed upon session opening. To enable `z_pub_shm` to operate // over shared memory (and to not fallback on network mode), shared memory needs to be enabled also on the // subscriber side. By doing so, the probing procedure will succeed and shared memory will operate as expected. - if (zc_config_insert_json(z_loan(config), "transport/shared_memory/enabled", "true") < 0) { + if (zc_config_insert_json(z_loan_mut(config), "transport/shared_memory/enabled", "true") < 0) { printf("Error enabling Shared Memory"); exit(-1); } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } - z_owned_closure_sample_t callback = z_closure(data_handler); - printf("Declaring Subscriber on '%s'...\n", expr); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), z_move(callback), NULL); - if (!z_check(sub)) { + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); + printf("Declaring Subscriber on '%s'...\n", keyexpr); + z_owned_subscriber_t sub; + if (z_declare_subscriber(&sub, z_loan(s), z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to declare subscriber.\n"); exit(-1); } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 13412321a..970c197f4 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -17,43 +17,59 @@ const char *kind_to_str(z_sample_kind_t kind); -int8_t attachment_reader(z_loaned_slice_t key, z_loaned_slice_t val, void *ctx) { - printf(" attachment: %.*s: '%.*s'\n", (int)key.len, key.start, (int)val.len, val.start); - return 0; +bool attachment_map_reader(const z_loaned_slice_t* key, const z_loaned_slice_t* val, void *ctx) { + printf(" attachment: %.*s: '%.*s'\n", (int)z_slice_len(key), z_slice_data(key), + (int)z_slice_len(val), z_slice_data(val) + ); + return false; } void data_handler(const z_loaned_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); - printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload_value)); + z_owned_str_t key_string; + z_keyexpr_to_string(z_sample_keyexpr(sample), &key_string); + + z_owned_str_t payload_string; + z_bytes_decode_into_string(z_sample_payload(sample), &payload_string); + + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_str_data(z_loan(key_string)), + z_str_data(z_loan(payload_string)) + ); - z_loaned_bytes_t attachment = z_sample_attachment(sample); + const z_loaned_bytes_t* attachment = z_sample_attachment(sample); // checks if attachment exists - if (z_check(attachment)) { + if (attachment != NULL) { // reads full attachment - z_attachment_iterate(attachment, attachment_reader, NULL); + z_owned_slice_map_t attachment_map; + z_bytes_decode_into_bytes_map(attachment, &attachment_map); + + z_slice_map_iterate(z_loan(attachment_map), attachment_map_reader, NULL); // reads particular attachment item - z_loaned_slice_t index = z_attachment_get(attachment, z_slice_from_str("index")); - if (z_slice_is_initialized(&index)) { - printf(" message number: %.*s\n", (int)index.len, index.start); + z_view_slice_t attachment_key; + z_view_slice_from_str(&attachment_key, "index"); + const z_loaned_slice_t* index = z_slice_map_get(z_loan(attachment_map), z_loan(attachment_key)); + if (index != NULL) { + printf(" message number: %.*s\n", (int)z_slice_len(index), z_slice_data(index)); } + z_drop(z_move(attachment_map)); } - z_drop(z_move(payload_value)); - z_drop(z_move(keystr)); + z_drop(z_move(payload_string)); + z_drop(z_move(key_string)); } int main(int argc, char **argv) { - char *expr = "demo/example/**"; + char *keyexpr = "demo/example/**"; if (argc > 1) { - expr = argv[1]; + keyexpr = argv[1]; } - z_owned_config_t config = z_config_default(); + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, keyexpr); + + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -63,16 +79,17 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config))) { printf("Unable to open session!\n"); exit(-1); } - z_owned_closure_sample_t callback = z_closure(data_handler); - printf("Declaring Subscriber on '%s'...\n", expr); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), z_move(callback), NULL); - if (!z_check(sub)) { + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); + printf("Declaring Subscriber on '%s'...\n", keyexpr); + z_owned_subscriber_t sub; + if (z_declare_subscriber(&sub, z_loan(s), z_loan(ke), z_move(callback), NULL)) { printf("Unable to declare subscriber.\n"); exit(-1); } diff --git a/examples/z_sub_liveliness.c b/examples/z_sub_liveliness.c index 5c6b49d6a..5dc05a1f1 100644 --- a/examples/z_sub_liveliness.c +++ b/examples/z_sub_liveliness.c @@ -15,33 +15,35 @@ #include "zenoh.h" void data_handler(const z_loaned_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t key_string; + z_keyexpr_to_string(z_sample_keyexpr(sample), &key_string); switch (z_sample_kind(sample)) { case Z_SAMPLE_KIND_PUT: - printf(">> [LivelinessSubscriber] New alive token ('%s')\n", z_loan(keystr)); + printf(">> [LivelinessSubscriber] New alive token ('%s')\n", z_str_data(z_loan(key_string))); break; case Z_SAMPLE_KIND_DELETE: - printf(">> [LivelinessSubscriber] Dropped token ('%s')\n", z_loan(keystr)); + printf(">> [LivelinessSubscriber] Dropped token ('%s')\n", z_str_data(z_loan(key_string))); break; } - z_drop(z_move(keystr)); + z_drop(z_move(key_string)); } int main(int argc, char **argv) { - char *expr = "group1/**"; + char *keyexpr = "group1/**"; if (argc > 1) { - expr = argv[1]; + keyexpr = argv[1]; } - z_loaned_keyexpr_t keyexpr = z_keyexpr(expr); - if (!z_check(keyexpr)) { - printf("%s is not a valid key expression\n", expr); + z_view_keyexpr_t ke; + if (z_view_keyexpr(&ke, keyexpr) < 0) { + printf("%s is not a valid key expression\n", keyexpr); exit(-1); } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -51,16 +53,17 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } - printf("Declaring liveliness subscriber on '%s'...\n", expr); - z_owned_closure_sample_t callback = z_closure(data_handler); - z_owned_subscriber_t sub = zc_liveliness_declare_subscriber(z_loan(s), keyexpr, z_move(callback), NULL); - if (!z_check(sub)) { + printf("Declaring liveliness subscriber on '%s'...\n", keyexpr); + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); + z_owned_subscriber_t sub; + if (zc_liveliness_declare_subscriber(&sub, z_loan(s), z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to declare liveliness subscriber.\n"); exit(-1); } diff --git a/examples/z_sub_thr.c b/examples/z_sub_thr.c index d7e69a29f..2513cd654 100644 --- a/examples/z_sub_thr.c +++ b/examples/z_sub_thr.c @@ -34,7 +34,7 @@ z_stats_t *z_stats_make() { return stats; } -void on_sample(z_loaned_sample_t sample, void *context) { +void on_sample(const z_loaned_sample_t* sample, void *context) { z_stats_t *stats = (z_stats_t *)context; if (stats->count == 0) { stats->start = z_clock_now(); @@ -64,7 +64,7 @@ int main(int argc, char **argv) { z_owned_config_t config; z_config_default(&config); if (argc > 1) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[1]) < 0) { + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, argv[1]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", @@ -80,13 +80,14 @@ int main(int argc, char **argv) { exit(-1); } - z_owned_keyexpr_t ke; - z_keyexpr(&ke, "test/thr"); + z_view_keyexpr_t ke; + z_view_keyexpr(&ke, "test/thr"); z_owned_keyexpr_t declared_ke; - z_declare_keyexpr(&ke, z_loan(s), z_loan(ke)); + z_declare_keyexpr(&declared_ke, z_loan(s), z_loan(ke)); z_stats_t *context = z_stats_make(); - z_owned_closure_sample_t callback = z_closure(on_sample, drop_stats, context); + z_owned_closure_sample_t callback; + z_closure(&callback, on_sample, drop_stats, context); z_owned_subscriber_t sub; if (z_declare_subscriber(&sub, z_loan(s), z_loan(declared_ke), z_move(callback), NULL)) { printf("Unable to create subscriber.\n"); @@ -99,7 +100,6 @@ int main(int argc, char **argv) { } z_undeclare_subscriber(z_move(sub)); - z_keyexpr_drop(z_move(ke)); z_undeclare_keyexpr(z_loan(s), z_move(declared_ke)); z_close(z_move(s)); return 0; diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 463f37575..05bc707c5 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -139,7 +139,7 @@ typedef struct ALIGN(8) z_owned_slice_t { uint8_t _0[16]; } z_owned_slice_t; /** - * A map of maybe-owned vector of bytes to maybe-owned vector of bytes. + * A map of maybe-owned slices to maybe-owned slices. * * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher */ @@ -154,12 +154,12 @@ typedef struct ALIGN(8) z_owned_slice_map_t { typedef struct ALIGN(8) z_owned_str_t { uint8_t _0[16]; } z_owned_str_t; -typedef struct ALIGN(8) z_loaned_slice_t { - uint8_t _0[16]; -} z_loaned_slice_t; typedef struct ALIGN(8) z_loaned_slice_map_t { uint8_t _0[48]; } z_loaned_slice_map_t; +typedef struct ALIGN(8) z_loaned_slice_t { + uint8_t _0[16]; +} z_loaned_slice_t; typedef struct ALIGN(8) z_loaned_str_t { uint8_t _0[16]; } z_loaned_str_t; @@ -180,52 +180,15 @@ typedef struct z_clock_t { uint64_t t; const void *t_base; } z_clock_t; -/** - * Represents a Zenoh ID. - * - * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. - */ -typedef struct ALIGN(1) z_id_t { - uint8_t id[16]; -} z_id_t; -/** - * An owned array of owned, zenoh allocated, NULL terminated strings. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_str_array_t { - char **val; - size_t len; -} z_owned_str_array_t; -/** - * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct z_owned_hello_t { - unsigned int _whatami; - struct z_id_t _pid; - struct z_owned_str_array_t _locators; -} z_owned_hello_t; +typedef struct ALIGN(8) z_loaned_hello_t { + uint8_t _0[48]; +} z_loaned_hello_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * * Members: * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *call(const struct z_hello_t* hello, const void *context): the typical callback function. `context` will be passed as its last argument. * void *drop(void*): allows the callback's state to be freed. * * Closures are not guaranteed not to be called concurrently. @@ -238,7 +201,7 @@ typedef struct z_owned_hello_t { */ typedef struct z_owned_closure_hello_t { void *context; - void (*call)(struct z_owned_hello_t*, void*); + void (*call)(const struct z_loaned_hello_t*, void*); void (*drop)(void*); } z_owned_closure_hello_t; /** @@ -339,6 +302,14 @@ typedef struct z_owned_closure_sample_t { void (*call)(const struct z_loaned_sample_t*, void *context); void (*drop)(void*); } z_owned_closure_sample_t; +/** + * Represents a Zenoh ID. + * + * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. + */ +typedef struct ALIGN(1) z_id_t { + uint8_t id[16]; +} z_id_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * @@ -521,19 +492,7 @@ typedef struct z_get_options_t { uint64_t timeout_ms; } z_get_options_t; /** - * An borrowed array of borrowed, zenoh allocated, NULL terminated strings. - */ -typedef struct z_str_array_t { - size_t len; - const char *const *val; -} z_str_array_t; -/** - * A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. + * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. * * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. @@ -541,17 +500,19 @@ typedef struct z_str_array_t { * * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ -typedef struct z_hello_t { - unsigned int whatami; - struct z_id_t pid; - struct z_str_array_t locators; -} z_hello_t; +typedef struct ALIGN(8) z_owned_hello_t { + uint8_t _0[48]; +} z_owned_hello_t; +/** + * An array of maybe-owned slices + * + */ +typedef struct ALIGN(8) z_owned_slice_array_t { + uint8_t _0[24]; +} z_owned_slice_array_t; typedef struct ALIGN(8) z_view_slice_t { uint8_t _0[16]; } z_view_slice_t; -typedef struct ALIGN(8) z_view_keyexpr_t { - uint8_t _0[32]; -} z_view_keyexpr_t; typedef struct ALIGN(8) z_timestamp_t { uint8_t _0[24]; } z_timestamp_t; @@ -685,13 +646,16 @@ typedef struct z_owned_scouting_config_t { unsigned long zc_timeout_ms; uint8_t zc_what; } z_owned_scouting_config_t; +typedef struct ALIGN(8) z_loaned_slice_array_t { + uint8_t _0[24]; +} z_loaned_slice_array_t; /** * The body of a loop over a z_slice_map's key-value pairs. * * `key` and `value` are loaned to the body for the duration of a single call. * `context` is passed transparently through the iteration driver. * - * Returning `true` is treated as `continue`. + * Returning `true` is treated as `break`. */ typedef bool (*z_slice_map_iter_body_t)(const struct z_loaned_slice_t *key, const struct z_loaned_slice_t *value, @@ -712,6 +676,9 @@ typedef struct z_task_attr_t { typedef struct z_time_t { uint64_t t; } z_time_t; +typedef struct ALIGN(8) z_view_keyexpr_t { + uint8_t _0[32]; +} z_view_keyexpr_t; typedef struct ALIGN(8) z_view_str_t { uint8_t _0[16]; } z_view_str_t; @@ -894,7 +861,7 @@ z_error_t z_bytes_decode_into_bytes(const struct z_loaned_bytes_t *payload, * Decodes payload into bytes map. */ ZENOHC_API -z_error_t z_bytes_decode_into_bytes_map(struct z_loaned_bytes_t payload, +z_error_t z_bytes_decode_into_bytes_map(const struct z_loaned_bytes_t *payload, struct z_owned_slice_map_t *dst); /** * Decodes payload into null-terminated string. @@ -908,12 +875,6 @@ z_error_t z_bytes_decode_into_string(const struct z_loaned_bytes_t *payload, * `this` will be reset to `z_buffer_null`, preventing UB on double-frees. */ ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); -/** - * Encodes byte sequence by aliasing. - */ -ZENOHC_API -void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, - const struct z_loaned_slice_t *bytes); /** * Encodes bytes map by copying. */ @@ -921,7 +882,13 @@ ZENOHC_API void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, const struct z_loaned_slice_map_t *bytes_map); /** - * Encodes a null-terminated string by aliasing. + * Encodes byte sequence by aliasing. + */ +ZENOHC_API +void z_bytes_encode_from_slice(struct z_owned_bytes_t *this_, + const struct z_loaned_slice_t *bytes); +/** + * Encodes a loaned string by aliasing. */ ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, @@ -989,7 +956,7 @@ ZENOHC_API z_error_t z_close(struct z_owned_session_t *session); */ ZENOHC_API void z_closure_hello_call(const struct z_owned_closure_hello_t *closure, - struct z_owned_hello_t *hello); + const struct z_loaned_hello_t *hello); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -997,7 +964,7 @@ ZENOHC_API void z_closure_hello_drop(struct z_owned_closure_hello_t *closure); /** * Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type */ -ZENOHC_API struct z_owned_closure_hello_t z_closure_hello_null(void); +ZENOHC_API void z_closure_hello_null(struct z_owned_closure_hello_t *this_); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1025,7 +992,7 @@ ZENOHC_API void z_closure_query_drop(struct z_owned_closure_query_t *closure); /** * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type */ -ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); +ZENOHC_API void z_closure_query_null(struct z_owned_closure_query_t *this_); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1039,7 +1006,7 @@ ZENOHC_API void z_closure_reply_drop(struct z_owned_closure_reply_t *closure); /** * Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type */ -ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); +ZENOHC_API void z_closure_reply_null(struct z_owned_closure_reply_t *this_); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1053,7 +1020,7 @@ ZENOHC_API void z_closure_sample_drop(struct z_owned_closure_sample_t *closure); /** * Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type */ -ZENOHC_API struct z_owned_closure_sample_t z_closure_sample_null(void); +ZENOHC_API void z_closure_sample_null(struct z_owned_closure_sample_t *this_); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1067,7 +1034,7 @@ ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); /** * Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type */ -ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); +ZENOHC_API void z_closure_zid_null(struct z_owned_closure_zid_t *this_); ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); @@ -1301,22 +1268,26 @@ z_error_t z_get(const struct z_loaned_session_t *session, struct z_owned_closure_reply_t *callback, struct z_get_options_t *options); ZENOHC_API void z_get_options_default(struct z_get_options_t *this_); -/** - * Returns ``true`` if `hello` is valid. - */ -ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *hello); +ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *this_); /** * Frees `hello`, invalidating it for double-drop safety. */ -ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); +ZENOHC_API void z_hello_drop(struct z_owned_hello_t *this_); /** * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. */ -ZENOHC_API const struct z_hello_t *z_hello_loan(const struct z_owned_hello_t *hello); +ZENOHC_API const struct z_loaned_hello_t *z_hello_loan(const struct z_owned_hello_t *this_); /** - * Constructs a gravestone value for hello, useful to steal one from a callback + * Returns an array of non-owned locators as an array of non-null terminated strings. + * + * The lifetime of locator strings is bound to `this`. */ +ZENOHC_API +void z_hello_locators(const struct z_loaned_hello_t *this_, + struct z_owned_slice_array_t *locators_out); ZENOHC_API void z_hello_null(struct z_owned_hello_t *this_); +ZENOHC_API uint8_t z_hello_whatami(const struct z_loaned_hello_t *this_); +ZENOHC_API struct z_id_t z_hello_zid(const struct z_loaned_hello_t *this_); /** * Fetches the Zenoh IDs of all connected peers. * @@ -1326,7 +1297,7 @@ ZENOHC_API void z_hello_null(struct z_owned_hello_t *this_); * Retuns 0 on success, negative values on failure */ ZENOHC_API -z_error_t z_info_peers_zid(struct z_loaned_session_t session, +z_error_t z_info_peers_zid(const struct z_loaned_session_t *session, struct z_owned_closure_zid_t *callback); /** * Fetches the Zenoh IDs of all connected routers. @@ -1337,7 +1308,7 @@ z_error_t z_info_peers_zid(struct z_loaned_session_t session, * Retuns 0 on success, negative values on failure. */ ZENOHC_API -z_error_t z_info_routers_zid(struct z_loaned_session_t session, +z_error_t z_info_routers_zid(const struct z_loaned_session_t *session, struct z_owned_closure_zid_t *callback); /** * Returns the local Zenoh ID. @@ -1346,7 +1317,7 @@ z_error_t z_info_routers_zid(struct z_loaned_session_t session, * In other words, this function returning an array of 16 zeros means you failed * to pass it a valid session. */ -ZENOHC_API struct z_id_t z_info_zid(struct z_loaned_session_t session); +ZENOHC_API struct z_id_t z_info_zid(const struct z_loaned_session_t *session); /** * Returns the key expression's internal string by aliasing it. * @@ -1459,32 +1430,15 @@ ZENOHC_API enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_loaned_keyexpr_t *left, const struct z_loaned_keyexpr_t *right); /** - * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: - * - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. - * - any instance of `**` may only be lead or followed by `/`. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. + * Constructs a null-terminated string departing from a :c:type:`z_loaned_keyexpr_t`. + * The user is responsible of droping the returned string using `z_drop` */ -ZENOHC_API -void z_keyexpr_unchecked(struct z_view_keyexpr_t *this_, - const char *name); +ZENOHC_API void z_keyexpr_to_string(const struct z_loaned_keyexpr_t *ke, struct z_owned_str_t *s); /** * Returns the read position indicator. * Returns read position indicator on success or -1L if failure occurs. */ ZENOHC_API int64_t z_loaned_bytes_reader_tell(struct z_loaned_bytes_reader_t *this_); -/** - * Constructs a null-terminated string departing from a :c:type:`z_loaned_keyexpr_t`. - * The user is responsible of droping the returned string using `z_drop` - */ -ZENOHC_API -void z_loaned_keyexpr_to_string(const struct z_loaned_keyexpr_t *ke, - struct z_owned_str_t *s); ZENOHC_API z_error_t z_loaned_mutex_try_lock(struct z_loaned_mutex_t *this_); /** * Create a default :c:type:`z_loaned_query_target_t`. @@ -1621,7 +1575,7 @@ ZENOHC_API void z_query_channel_closure_drop(struct z_owned_query_channel_closur /** * Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type */ -ZENOHC_API struct z_owned_query_channel_closure_t z_query_channel_closure_null(void); +ZENOHC_API void z_query_channel_closure_null(struct z_owned_query_channel_closure_t *this_); ZENOHC_API void z_query_channel_drop(struct z_owned_query_channel_t *channel); /** * Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type @@ -1718,8 +1672,8 @@ void z_query_parameters(const struct z_loaned_query_t *query, * The payload and all owned options fields are consumed upon function return. */ ZENOHC_API -z_error_t z_query_reply(struct z_loaned_query_t query, - struct z_loaned_keyexpr_t key_expr, +z_error_t z_query_reply(const struct z_loaned_query_t *query, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_bytes_t *payload, struct z_query_reply_options_t *options); /** @@ -1764,12 +1718,12 @@ ZENOHC_API void z_reply_channel_closure_drop(struct z_owned_reply_channel_closur /** * Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type */ -ZENOHC_API struct z_owned_reply_channel_closure_t z_reply_channel_closure_null(void); +ZENOHC_API void z_reply_channel_closure_null(struct z_owned_reply_channel_closure_t *this_); ZENOHC_API void z_reply_channel_drop(struct z_owned_reply_channel_t *channel); /** * Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type */ -ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); +ZENOHC_API void z_reply_channel_null(struct z_owned_reply_channel_t *this_); /** * Returns ``true`` if `reply` is valid. */ @@ -1793,7 +1747,7 @@ const struct z_loaned_value_t *z_reply_err(const struct z_loaned_reply_t *reply) */ ZENOHC_API bool z_reply_is_ok(const struct z_loaned_reply_t *reply); -ZENOHC_API const struct z_loaned_reply_t *z_reply_loan(struct z_owned_reply_t *this_); +ZENOHC_API const struct z_loaned_reply_t *z_reply_loan(const struct z_owned_reply_t *this_); /** * Returns an invalidated :c:type:`z_owned_reply_t`. * @@ -1911,6 +1865,60 @@ ZENOHC_API void z_session_null(struct z_owned_session_t *this_); ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); +/** + * Returns `true` if the array is not in its gravestone state + */ +ZENOHC_API bool z_slice_array_check(const struct z_owned_slice_array_t *this_); +/** + * Destroys the array, resetting `this` to its gravestone value. + * + * This function is double-free safe, passing a pointer to the gravestone value will have no effect. + */ +ZENOHC_API void z_slice_array_drop(struct z_owned_slice_array_t *this_); +/** + * Returns the value at the position of index in the array. + * + * Will return NULL if the index is out of bounds. + */ +ZENOHC_API +const struct z_loaned_slice_t *z_slice_array_get(const struct z_loaned_slice_array_t *this_, + size_t index); +/** + * Returns true if the array is empty, false otherwise. + */ +ZENOHC_API bool z_slice_array_is_empty(const struct z_loaned_slice_array_t *this_); +/** + * Returns number of key-value pairs in the map. + */ +ZENOHC_API size_t z_slice_array_len(const struct z_loaned_slice_array_t *this_); +ZENOHC_API +const struct z_loaned_slice_array_t *z_slice_array_loan(const struct z_owned_slice_array_t *this_); +ZENOHC_API +struct z_loaned_slice_array_t *z_slice_array_loan_mut(struct z_owned_slice_array_t *this_); +/** + * Constructs a new empty array. + */ +ZENOHC_API void z_slice_array_new(struct z_owned_slice_array_t *this_); +/** + * Constructs the gravestone value for `z_owned_slice_array_t` + */ +ZENOHC_API void z_slice_array_null(struct z_owned_slice_array_t *this_); +/** + * Appends specified value to the end of the array by aliasing. + * + * Returns the new length of the array. + */ +ZENOHC_API +size_t z_slice_array_push_by_alias(struct z_loaned_slice_array_t *this_, + const struct z_loaned_slice_t *value); +/** + * Appends specified value to the end of the array by copying. + * + * Returns the new length of the array. + */ +ZENOHC_API +size_t z_slice_array_push_by_copy(struct z_loaned_slice_array_t *this_, + const struct z_loaned_slice_t *value); ZENOHC_API void z_slice_clone(const struct z_loaned_slice_t *this_, struct z_owned_slice_t *dst); ZENOHC_API const uint8_t *z_slice_data(const struct z_loaned_slice_t *this_); /** @@ -1997,23 +2005,13 @@ ZENOHC_API void z_slice_null(struct z_owned_slice_t *this_); * Constructs a `len` bytes long view starting at `start`. */ ZENOHC_API void z_slice_wrap(struct z_owned_slice_t *this_, const uint8_t *start, size_t len); -/** - * Returns ``true`` if `strs` is valid. - */ -ZENOHC_API bool z_str_array_check(const struct z_owned_str_array_t *strs); -/** - * Frees `strs` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); -/** - * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. - */ -ZENOHC_API const struct z_str_array_t *z_str_array_loan(const struct z_owned_str_array_t *strs); +ZENOHC_API const struct z_loaned_slice_t *z_str_as_slice(const struct z_loaned_str_t *this_); /** * Returns ``true`` if `s` is a valid string */ ZENOHC_API bool z_str_check(const struct z_owned_str_t *this_); ZENOHC_API void z_str_clone(const struct z_loaned_str_t *this_, struct z_owned_str_t *dst); +ZENOHC_API const char *z_str_data(const struct z_loaned_str_t *this_); /** * Frees `z_owned_str_t`, invalidating it for double-drop safety. */ @@ -2039,7 +2037,7 @@ ZENOHC_API void z_str_null(struct z_owned_str_t *this_); * Calling this with `str == NULL` is equivalent to `z_str_null`. */ ZENOHC_API -void z_str_wrap(struct z_owned_slice_t *this_, +void z_str_wrap(struct z_owned_str_t *this_, const char *str); /** * Returns ``true`` if `sub` is valid. @@ -2109,13 +2107,15 @@ ZENOHC_API z_error_t z_undeclare_queryable(struct z_owned_queryable_t *qable); */ ZENOHC_API z_error_t z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); +ZENOHC_API const struct z_loaned_encoding_t *z_value_encoding(const struct z_loaned_value_t *this_); +ZENOHC_API const struct z_loaned_bytes_t *z_value_payload(const struct z_loaned_value_t *this_); /** - * Constructs a :c:type:`z_loaned_keyexpr_t` departing from a string. + * Constructs a :c:type:`z_view_keyexpr_t` departing from a string. * It is a loaned key expression that aliases `name`. */ ZENOHC_API z_error_t z_view_keyexpr(struct z_view_keyexpr_t *this_, const char *name); /** - * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string. * 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). */ @@ -2127,14 +2127,14 @@ z_error_t z_view_keyexpr_autocanonize(struct z_view_keyexpr_t *this_, */ ZENOHC_API bool z_view_keyexpr_check(const struct z_view_keyexpr_t *keyexpr); /** - * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string. */ ZENOHC_API z_error_t z_view_keyexpr_from_slice(struct z_view_keyexpr_t *this_, const char *name, size_t len); /** - * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string. * 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). */ @@ -2143,7 +2143,7 @@ z_error_t z_view_keyexpr_from_slice_autocanonize(struct z_view_keyexpr_t *this_, char *name, size_t *len); /** - * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: + * Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string without checking any of `z_view_keyexpr_t`'s assertions: * - `name` MUST be valid UTF8. * - `name` MUST follow the Key Expression specification, ie: * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -2157,11 +2157,26 @@ void z_view_keyexpr_from_slice_unchecked(struct z_view_keyexpr_t *this_, const char *start, size_t len); /** - * Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + * Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_view_keyexpr_t`. */ ZENOHC_API const struct z_loaned_keyexpr_t *z_view_keyexpr_loan(const struct z_view_keyexpr_t *key_expr); ZENOHC_API void z_view_keyexpr_null(struct z_view_keyexpr_t *this_); +/** + * Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string without checking any of `z_view_keyexpr_t`'s assertions: + * + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * + * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. + * - any instance of `**` may only be lead or followed by `/`. + * - the key expression must have canon form. + * + * It is a view key expression that aliases `name`. + */ +ZENOHC_API +void z_view_keyexpr_unchecked(struct z_view_keyexpr_t *this_, + const char *s); /** * Returns ``true`` if `this` is initialized. */ @@ -2182,7 +2197,6 @@ ZENOHC_API void z_view_slice_null(struct z_view_slice_t *this_); * Constructs a `len` bytes long view starting at `start`. */ ZENOHC_API void z_view_slice_wrap(struct z_view_slice_t *this_, const uint8_t *start, size_t len); -ZENOHC_API const char *z_view_str_data(const struct z_loaned_str_t *this_); ZENOHC_API void z_view_str_empty(struct z_view_str_t *this_); ZENOHC_API size_t z_view_str_len(const struct z_loaned_str_t *this_); /** @@ -2198,7 +2212,7 @@ ZENOHC_API void z_view_str_null(struct z_view_str_t *this_); * * Calling this with `str == NULL` is equivalent to `z_view_str_null`. */ -ZENOHC_API void z_view_str_wrap(struct z_view_slice_t *this_, const char *str); +ZENOHC_API void z_view_str_wrap(struct z_view_str_t *this_, const char *str); /** * Converts the kind of zenoh entity into a string. * @@ -2314,6 +2328,7 @@ void zc_liveliness_subscriber_options_default(struct zc_liveliness_declare_subsc * Returns `true` unless the token is at its gravestone value. */ ZENOHC_API bool zc_liveliness_token_check(const struct zc_owned_liveliness_token_t *this_); +ZENOHC_API void zc_liveliness_token_drop(struct zc_owned_liveliness_token_t *this_); /** * The gravestone value for liveliness tokens. */ @@ -2334,7 +2349,8 @@ ZENOHC_API z_error_t zc_liveliness_undeclare_token(struct zc_owned_liveliness_to * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. */ ZENOHC_API -struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); +void zc_query_fifo_new(struct z_owned_query_channel_t *this_, + size_t bound); /** * Creates a new non-blocking fifo channel, returned as a pair of closures. * @@ -2347,7 +2363,8 @@ struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. */ ZENOHC_API -struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); +void zc_query_non_blocking_fifo_new(struct z_owned_query_channel_t *this_, + size_t bound); /** * Creates a new blocking fifo channel, returned as a pair of closures. * @@ -2360,7 +2377,8 @@ struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. */ ZENOHC_API -struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); +void zc_reply_fifo_new(struct z_owned_reply_channel_t *this_, + size_t bound); /** * Creates a new non-blocking fifo channel, returned as a pair of closures. * @@ -2373,7 +2391,8 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. */ ZENOHC_API -struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); +void zc_reply_non_blocking_fifo_new(struct z_owned_reply_channel_t *this_, + size_t bound); /** * Increments the session's reference count, returning a new owning handle. */ @@ -2394,7 +2413,7 @@ void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t /** * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type */ -ZENOHC_API struct zcu_owned_closure_matching_status_t zcu_closure_matching_status_null(void); +ZENOHC_API void zcu_closure_matching_status_null(struct zcu_owned_closure_matching_status_t *this_); ZENOHC_API enum zcu_locality_t zcu_locality_default(void); /** * Register callback for notifying subscribers matching. diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index d432f0650..f3d9a5315 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -1,4 +1,7 @@ #pragma once + +#define z_move(x) (&x) + // clang-format off #ifndef __cplusplus @@ -13,11 +16,12 @@ z_owned_keyexpr_t : z_keyexpr_loan, \ z_owned_publisher_t : z_publisher_loan, \ z_owned_query_t : z_query_loan, \ + z_owned_reply_t : z_reply_loan, \ z_owned_sample_t : z_sample_loan, \ z_owned_session_t : z_session_loan, \ + z_owned_slice_array_t : z_slice_array_loan, \ z_owned_slice_t : z_slice_loan, \ z_owned_slice_map_t : z_slice_map_loan, \ - z_owned_str_array_t : z_str_array_loan, \ z_owned_str_t : z_str_loan, \ z_owned_subscriber_t : z_subscriber_loan, \ z_view_keyexpr_t : z_view_keyexpr_loan, \ @@ -32,6 +36,7 @@ z_owned_condvar_t : z_condvar_loan_mut, \ z_owned_config_t : z_config_loan_mut, \ z_owned_mutex_t : z_mutex_loan_mut, \ + z_owned_slice_array_t : z_slice_array_loan_mut, \ z_owned_slice_map_t : z_slice_map_loan_mut \ )(&x) @@ -59,10 +64,11 @@ z_owned_reply_t * : z_reply_drop,\ z_owned_sample_t * : z_sample_drop,\ z_owned_scouting_config_t * : z_scouting_config_drop,\ + z_owned_slice_array_t * : z_slice_array_drop,\ z_owned_slice_t * : z_slice_drop,\ z_owned_slice_map_t * : z_slice_map_drop,\ - z_owned_str_array_t * : z_str_array_drop,\ z_owned_str_t * : z_str_drop,\ + zc_owned_liveliness_token_t * : zc_liveliness_token_drop,\ zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop \ )(x) @@ -70,6 +76,11 @@ _Generic((x), \ z_owned_bytes_t * : z_bytes_null, \ z_owned_bytes_reader_t * : z_bytes_reader_null, \ + z_owned_closure_hello_t * : z_closure_hello_null, \ + z_owned_closure_query_t * : z_closure_query_null, \ + z_owned_closure_reply_t * : z_closure_reply_null, \ + z_owned_closure_sample_t * : z_closure_sample_null, \ + z_owned_closure_zid_t * : z_closure_zid_null, \ z_owned_condvar_t * : z_condvar_null, \ z_owned_config_t * : z_config_null, \ z_owned_encoding_t * : z_encoding_null, \ @@ -77,12 +88,16 @@ z_owned_keyexpr_t * : z_keyexpr_null, \ z_owned_mutex_t * : z_mutex_null, \ z_owned_publisher_t * : z_publisher_null, \ + z_owned_query_channel_closure_t * : z_query_channel_closure_null, \ z_owned_query_t * : z_query_null, \ z_owned_queryable_t * : z_queryable_null, \ + z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ + z_owned_reply_channel_t * : z_reply_channel_null, \ z_owned_reply_t * : z_reply_null, \ z_owned_sample_t * : z_sample_null, \ z_owned_scouting_config_t * : z_scouting_config_null, \ z_owned_session_t * : z_session_null, \ + z_owned_slice_array_t * : z_slice_array_null, \ z_owned_slice_map_t * : z_slice_map_null, \ z_owned_slice_t * : z_slice_null, \ z_owned_str_t * : z_str_null, \ @@ -92,6 +107,7 @@ z_view_slice_t * : z_view_slice_null, \ z_view_str_t * : z_view_str_null, \ zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ + zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ ze_owned_publication_cache_t * : ze_publication_cache_null, \ ze_owned_querying_subscriber_t * : ze_querying_subscriber_null \ )(x) @@ -114,8 +130,8 @@ z_owned_sample_t : z_sample_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ z_owned_session_t : z_session_check, \ + z_owned_slice_array_t : z_slice_array_check, \ z_owned_slice_map_t : z_slice_map_check, \ - z_owned_str_array_t : z_str_array_check, \ z_owned_str_t : z_str_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_task_t : z_task_check, \ @@ -140,17 +156,7 @@ )(&x, __VA_ARGS__) #define z_closure(x, callback, dropper, ctx) \ - _Generic((x), \ - z_owned_closure_hello_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_closure_owned_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_closure_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_closure_reply_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_closure_sample_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_closure_zid_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_query_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_reply_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - zcu_owned_closure_matching_status_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; } \ - ) + {{(x)->context = (void*)(ctx); (x)->call = (callback); (x)->drop = (dropper);}} #else // #ifndef __cplusplus @@ -160,15 +166,16 @@ inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t* reade inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t* this_) { return z_condvar_loan(this_); }; inline const z_loaned_config_t* z_loan(const z_owned_config_t* this_) { return z_config_loan(this_); }; inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* encoding) { return z_encoding_loan(encoding); }; -inline const z_hello_t* z_loan(const z_owned_hello_t* hello) { return z_hello_loan(hello); }; +inline const z_loaned_hello_t* z_loan(const z_owned_hello_t* this_) { return z_hello_loan(this_); }; inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t* key_expr) { return z_keyexpr_loan(key_expr); }; inline const z_loaned_publisher_t* z_loan(const z_owned_publisher_t* this_) { return z_publisher_loan(this_); }; inline const z_loaned_query_t* z_loan(const z_owned_query_t* this_) { return z_query_loan(this_); }; +inline const z_loaned_reply_t* z_loan(const z_owned_reply_t* this_) { return z_reply_loan(this_); }; inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* sample) { return z_sample_loan(sample); }; inline const z_loaned_session_t* z_loan(const z_owned_session_t* this_) { return z_session_loan(this_); }; +inline const z_loaned_slice_array_t* z_loan(const z_owned_slice_array_t* this_) { return z_slice_array_loan(this_); }; inline const z_loaned_slice_t* z_loan(const z_owned_slice_t* this_) { return z_slice_loan(this_); }; inline const z_loaned_slice_map_t* z_loan(const z_owned_slice_map_t* this_) { return z_slice_map_loan(this_); }; -inline const z_str_array_t* z_loan(const z_owned_str_array_t* strs) { return z_str_array_loan(strs); }; inline const z_loaned_str_t* z_loan(const z_owned_str_t* this_) { return z_str_loan(this_); }; inline const z_loaned_subscriber_t* z_loan(const z_owned_subscriber_t* this_) { return z_subscriber_loan(this_); }; inline const z_loaned_keyexpr_t* z_loan(const z_view_keyexpr_t* key_expr) { return z_view_keyexpr_loan(key_expr); }; @@ -181,6 +188,7 @@ inline z_loaned_bytes_reader_t* z_loan_mut( z_owned_bytes_reader_t& reader) { re inline z_loaned_condvar_t* z_loan_mut( z_owned_condvar_t& this_) { return z_condvar_loan_mut(&this_); }; inline z_loaned_config_t* z_loan_mut( z_owned_config_t& this_) { return z_config_loan_mut(&this_); }; inline z_loaned_mutex_t* z_loan_mut( z_owned_mutex_t& this_) { return z_mutex_loan_mut(&this_); }; +inline z_loaned_slice_array_t* z_loan_mut( z_owned_slice_array_t& this_) { return z_slice_array_loan_mut(&this_); }; inline z_loaned_slice_map_t* z_loan_mut( z_owned_slice_map_t& this_) { return z_slice_map_loan_mut(&this_); }; @@ -195,7 +203,7 @@ inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_ inline void z_drop(const z_owned_condvar_t* this_) { return z_condvar_drop(this_); }; inline void z_drop(const z_owned_config_t* config) { return z_config_drop(config); }; inline void z_drop(const z_owned_encoding_t* encoding) { return z_encoding_drop(encoding); }; -inline void z_drop(const z_owned_hello_t* hello) { return z_hello_drop(hello); }; +inline void z_drop(const z_owned_hello_t* this_) { return z_hello_drop(this_); }; inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; inline void z_drop(const z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; inline void z_drop(const z_owned_query_channel_closure_t* closure) { return z_query_channel_closure_drop(closure); }; @@ -206,15 +214,21 @@ inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_chan inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; inline void z_drop(const z_owned_sample_t* sample) { return z_sample_drop(sample); }; inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; +inline void z_drop(const z_owned_slice_array_t* this_) { return z_slice_array_drop(this_); }; inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; inline void z_drop(const z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; -inline void z_drop(const z_owned_str_array_t* strs) { return z_str_array_drop(strs); }; inline void z_drop(const z_owned_str_t* this_) { return z_str_drop(this_); }; +inline void z_drop(const zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_drop(this_); }; inline void z_drop(const zcu_owned_closure_matching_status_t* closure) { return zcu_closure_matching_status_drop(closure); }; inline void z_null( z_owned_bytes_t* this_) { return z_bytes_null(this_); }; inline void z_null( z_owned_bytes_reader_t* this_) { return z_bytes_reader_null(this_); }; +inline void z_null( z_owned_closure_hello_t* this_) { return z_closure_hello_null(this_); }; +inline void z_null( z_owned_closure_query_t* this_) { return z_closure_query_null(this_); }; +inline void z_null( z_owned_closure_reply_t* this_) { return z_closure_reply_null(this_); }; +inline void z_null( z_owned_closure_sample_t* this_) { return z_closure_sample_null(this_); }; +inline void z_null( z_owned_closure_zid_t* this_) { return z_closure_zid_null(this_); }; inline void z_null( z_owned_condvar_t* this_) { return z_condvar_null(this_); }; inline void z_null( z_owned_config_t* this_) { return z_config_null(this_); }; inline void z_null( z_owned_encoding_t* encoding) { return z_encoding_null(encoding); }; @@ -222,12 +236,16 @@ inline void z_null( z_owned_hello_t* this_) { return z_hello_null(this_); }; inline void z_null( z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; inline void z_null( z_owned_mutex_t* this_) { return z_mutex_null(this_); }; inline void z_null( z_owned_publisher_t* this_) { return z_publisher_null(this_); }; +inline void z_null( z_owned_query_channel_closure_t* this_) { return z_query_channel_closure_null(this_); }; inline void z_null( z_owned_query_t* this_) { return z_query_null(this_); }; inline void z_null( z_owned_queryable_t* this_) { return z_queryable_null(this_); }; +inline void z_null( z_owned_reply_channel_closure_t* this_) { return z_reply_channel_closure_null(this_); }; +inline void z_null( z_owned_reply_channel_t* this_) { return z_reply_channel_null(this_); }; inline void z_null( z_owned_reply_t* this_) { return z_reply_null(this_); }; inline void z_null( z_owned_sample_t* sample) { return z_sample_null(sample); }; inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; inline void z_null( z_owned_session_t* this_) { return z_session_null(this_); }; +inline void z_null( z_owned_slice_array_t* this_) { return z_slice_array_null(this_); }; inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; inline void z_null( z_owned_slice_t* this_) { return z_slice_null(this_); }; inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; @@ -237,6 +255,7 @@ inline void z_null( z_view_keyexpr_t* this_) { return z_view_keyexpr_null(this_) inline void z_null( z_view_slice_t* this_) { return z_view_slice_null(this_); }; inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; inline void z_null( zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_null(this_); }; +inline void z_null( zcu_owned_closure_matching_status_t* this_) { return zcu_closure_matching_status_null(this_); }; inline void z_null( ze_owned_publication_cache_t* this_) { return ze_publication_cache_null(this_); }; inline void z_null( ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_null(this_); }; @@ -246,7 +265,7 @@ inline bool z_check(const z_owned_bytes_reader_t& this_) { return z_bytes_reader inline bool z_check(const z_owned_condvar_t& this_) { return z_condvar_check(&this_); }; inline bool z_check(const z_owned_config_t& config) { return z_config_check(&config); }; inline bool z_check(const z_owned_encoding_t& encoding) { return z_encoding_check(&encoding); }; -inline bool z_check(const z_owned_hello_t& hello) { return z_hello_check(&hello); }; +inline bool z_check(const z_owned_hello_t& this_) { return z_hello_check(&this_); }; inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; inline bool z_check(const z_owned_mutex_t& this_) { return z_mutex_check(&this_); }; inline bool z_check(const z_owned_slice_t& this_) { return z_owned_slice_check(&this_); }; @@ -257,8 +276,8 @@ inline bool z_check(const z_owned_reply_t& this_) { return z_reply_check(&this_) inline bool z_check(const z_owned_sample_t& sample) { return z_sample_check(&sample); }; inline bool z_check(const z_owned_scouting_config_t& config) { return z_scouting_config_check(&config); }; inline bool z_check(const z_owned_session_t& this_) { return z_session_check(&this_); }; +inline bool z_check(const z_owned_slice_array_t& this_) { return z_slice_array_check(&this_); }; inline bool z_check(const z_owned_slice_map_t& map) { return z_slice_map_check(&map); }; -inline bool z_check(const z_owned_str_array_t& strs) { return z_str_array_check(&strs); }; inline bool z_check(const z_owned_str_t& this_) { return z_str_check(&this_); }; inline bool z_check(const z_owned_subscriber_t& subscriber) { return z_subscriber_check(&subscriber); }; inline bool z_check(const z_owned_task_t& this_) { return z_task_check(&this_); }; @@ -269,7 +288,7 @@ inline bool z_check(const ze_owned_publication_cache_t& this_) { return ze_publi inline bool z_check(const ze_owned_querying_subscriber_t& this_) { return ze_querying_subscriber_check(&this_); }; -inline void z_call(const z_owned_closure_hello_t& closure, z_owned_hello_t* hello) { +inline void z_call(const z_owned_closure_hello_t& closure, const z_loaned_hello_t* hello) { return z_closure_hello_call(&closure, hello); }; inline void z_call(const z_owned_closure_owned_query_t& closure, z_owned_query_t* query) { @@ -300,7 +319,7 @@ inline void z_call(const zcu_owned_closure_matching_status_t& closure, const zcu inline void z_closure( z_owned_closure_hello_t* closure, - void (*call)( z_owned_hello_t*, void*), + void (*call)(const z_loaned_hello_t*, void*), void (*drop)(void*), void *context) { closure->context = context; diff --git a/src/closures/hello_closure.rs b/src/closures/hello_closure.rs index 4e7f76323..b0a7f8d54 100644 --- a/src/closures/hello_closure.rs +++ b/src/closures/hello_closure.rs @@ -1,11 +1,13 @@ -use crate::z_owned_hello_t; +use std::mem::MaybeUninit; + +use crate::z_loaned_hello_t; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(const struct z_hello_t* hello, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. @@ -18,7 +20,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_hello_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } @@ -42,14 +44,14 @@ impl Drop for z_owned_closure_hello_t { } /// Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type #[no_mangle] -pub extern "C" fn z_closure_hello_null() -> z_owned_closure_hello_t { - z_owned_closure_hello_t::empty() +pub unsafe extern "C" fn z_closure_hello_null(this: *mut MaybeUninit) { + (*this).write(z_owned_closure_hello_t::empty()); } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] pub extern "C" fn z_closure_hello_call( closure: &z_owned_closure_hello_t, - hello: &mut z_owned_hello_t, + hello: &z_loaned_hello_t, ) { match closure.call { Some(call) => call(hello, closure.context), @@ -64,15 +66,15 @@ pub extern "C" fn z_closure_hello_drop(closure: &mut z_owned_closure_hello_t) { let mut empty_closure = z_owned_closure_hello_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_hello_t { +impl From for z_owned_closure_hello_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call( - response: &mut z_owned_hello_t, + extern "C" fn call( + response: *const z_loaned_hello_t, this: *mut c_void, ) { let this = unsafe { &*(this as *const F) }; - this(response) + unsafe { this(response.as_ref().unwrap()) } } extern "C" fn drop(this: *mut c_void) { std::mem::drop(unsafe { Box::from_raw(this as *mut F) }) diff --git a/src/closures/matching_status_closure.rs b/src/closures/matching_status_closure.rs index 05792b7d8..e07285593 100644 --- a/src/closures/matching_status_closure.rs +++ b/src/closures/matching_status_closure.rs @@ -1,3 +1,5 @@ +use std::mem::MaybeUninit; + use libc::c_void; use crate::zcu_matching_status_t; @@ -42,8 +44,8 @@ impl Drop for zcu_owned_closure_matching_status_t { } /// Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type #[no_mangle] -pub extern "C" fn zcu_closure_matching_status_null() -> zcu_owned_closure_matching_status_t { - zcu_owned_closure_matching_status_t::empty() +pub unsafe extern "C" fn zcu_closure_matching_status_null(this: *mut MaybeUninit) { + (*this).write(zcu_owned_closure_matching_status_t::empty()); } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index c4bf36a2a..88e1a1f4b 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -87,9 +87,9 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver /// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { +pub unsafe extern "C" fn zc_query_fifo_new(this: *mut MaybeUninit, bound: usize) { let (send, rx) = get_send_recv_ends(bound); - z_owned_query_channel_t { + let c = z_owned_query_channel_t { send, recv: From::from(move |this: *mut MaybeUninit| { if let Ok(val) = rx.recv() { @@ -99,7 +99,8 @@ pub unsafe extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channe } true }), - } + }; + (*this).write(c); } /// Creates a new non-blocking fifo channel, returned as a pair of closures. @@ -113,9 +114,9 @@ pub unsafe extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channe /// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned_query_channel_t { +pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(this: *mut MaybeUninit, bound: usize) { let (send, rx) = get_send_recv_ends(bound); - z_owned_query_channel_t { + let c = z_owned_query_channel_t { send, recv: From::from( move |this: *mut MaybeUninit| match rx.try_recv() { @@ -133,7 +134,8 @@ pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned } }, ), - } + }; + (*this).write(c); } impl z_owned_query_channel_closure_t { @@ -157,8 +159,8 @@ impl Drop for z_owned_query_channel_closure_t { /// Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type #[no_mangle] -pub extern "C" fn z_query_channel_closure_null() -> z_owned_query_channel_closure_t { - z_owned_query_channel_closure_t::empty() +pub unsafe extern "C" fn z_query_channel_closure_null(this: *mut MaybeUninit) { + (*this).write(z_owned_query_channel_closure_t::empty()); } /// Calls the closure. Calling an uninitialized closure is a no-op. diff --git a/src/closures/query_closure.rs b/src/closures/query_closure.rs index 98f774cd8..bc641470c 100644 --- a/src/closures/query_closure.rs +++ b/src/closures/query_closure.rs @@ -1,3 +1,5 @@ +use std::mem::MaybeUninit; + use crate::{z_loaned_query_t, z_owned_query_t}; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: @@ -40,8 +42,8 @@ impl Drop for z_owned_closure_query_t { } /// Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type #[no_mangle] -pub extern "C" fn z_closure_query_null() -> z_owned_closure_query_t { - z_owned_closure_query_t::empty() +pub unsafe extern "C" fn z_closure_query_null(this: *mut MaybeUninit) { + (*this).write(z_owned_closure_query_t::empty()); } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index d41c6580a..7a9f3aeaa 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -1,3 +1,5 @@ +use std::mem::MaybeUninit; + use crate::z_loaned_reply_t; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: @@ -41,8 +43,8 @@ impl Drop for z_owned_closure_reply_t { } /// Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type #[no_mangle] -pub extern "C" fn z_closure_reply_null() -> z_owned_closure_reply_t { - z_owned_closure_reply_t::empty() +pub unsafe extern "C" fn z_closure_reply_null(this: *mut MaybeUninit) { + (*this).write(z_owned_closure_reply_t::empty()); } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 4b0d52123..8f67163d9 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -38,11 +38,12 @@ pub extern "C" fn z_reply_channel_drop(channel: &mut z_owned_reply_channel_t) { } /// Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type #[no_mangle] -pub extern "C" fn z_reply_channel_null() -> z_owned_reply_channel_t { - z_owned_reply_channel_t { +pub unsafe extern "C" fn z_reply_channel_null(this: *mut MaybeUninit) { + let c = z_owned_reply_channel_t { send: z_owned_closure_reply_t::empty(), recv: z_owned_reply_channel_closure_t::empty(), - } + }; + (*this).write(c); } unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver) { @@ -85,9 +86,9 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver /// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { +pub unsafe extern "C" fn zc_reply_fifo_new(this: *mut MaybeUninit ,bound: usize) { let (send, rx) = get_send_recv_ends(bound); - z_owned_reply_channel_t { + let c = z_owned_reply_channel_t { send, recv: From::from(move |this: *mut MaybeUninit| { if let Ok(val) = rx.recv() { @@ -97,7 +98,8 @@ pub unsafe extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channe } true }), - } + }; + (*this).write(c); } /// Creates a new non-blocking fifo channel, returned as a pair of closures. @@ -111,9 +113,9 @@ pub unsafe extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channe /// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned_reply_channel_t { +pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(this: *mut MaybeUninit, bound: usize) { let (send, rx) = get_send_recv_ends(bound); - z_owned_reply_channel_t { + let c = z_owned_reply_channel_t { send, recv: From::from( move |this: *mut MaybeUninit| match rx.try_recv() { @@ -131,7 +133,8 @@ pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned } }, ), - } + }; + (*this).write(c); } impl z_owned_reply_channel_closure_t { @@ -155,8 +158,8 @@ impl Drop for z_owned_reply_channel_closure_t { /// Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type #[no_mangle] -pub extern "C" fn z_reply_channel_closure_null() -> z_owned_reply_channel_closure_t { - z_owned_reply_channel_closure_t::empty() +pub unsafe extern "C" fn z_reply_channel_closure_null(this: *mut MaybeUninit) { + (*this).write(z_owned_reply_channel_closure_t::empty()); } /// Calls the closure. Calling an uninitialized closure is a no-op. diff --git a/src/closures/sample_closure.rs b/src/closures/sample_closure.rs index e706b0b7a..9416d956f 100644 --- a/src/closures/sample_closure.rs +++ b/src/closures/sample_closure.rs @@ -1,3 +1,5 @@ +use std::mem::MaybeUninit; + use crate::z_loaned_sample_t; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. @@ -41,8 +43,8 @@ impl Drop for z_owned_closure_sample_t { /// Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type #[no_mangle] -pub extern "C" fn z_closure_sample_null() -> z_owned_closure_sample_t { - z_owned_closure_sample_t::empty() +pub unsafe extern "C" fn z_closure_sample_null(this: *mut MaybeUninit) { + (*this).write(z_owned_closure_sample_t::empty()); } /// Calls the closure. Calling an uninitialized closure is a no-op. diff --git a/src/closures/zenohid_closure.rs b/src/closures/zenohid_closure.rs index 1ad7796fd..5c6d8c03d 100644 --- a/src/closures/zenohid_closure.rs +++ b/src/closures/zenohid_closure.rs @@ -1,3 +1,5 @@ +use std::mem::MaybeUninit; + use libc::c_void; use crate::z_id_t; @@ -42,8 +44,8 @@ impl Drop for z_owned_closure_zid_t { } /// Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type #[no_mangle] -pub extern "C" fn z_closure_zid_null() -> z_owned_closure_zid_t { - z_owned_closure_zid_t::empty() +pub unsafe extern "C" fn z_closure_zid_null(this: *mut MaybeUninit) { + (*this).write(z_owned_closure_zid_t::empty()); } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] diff --git a/src/collections.rs b/src/collections.rs index 395ee57e3..95345255e 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -241,7 +241,7 @@ pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_loaned_str_t #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_wrap( - this: *mut MaybeUninit, + this: *mut MaybeUninit, str: *const libc::c_char, ) { z_slice_wrap(this as *mut _, str as _, strlen(str) + 1) @@ -269,7 +269,7 @@ pub unsafe extern "C" fn z_str_from_substring( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_view_str_wrap( - this: *mut MaybeUninit, + this: *mut MaybeUninit, str: *const libc::c_char, ) { z_view_slice_wrap(this as *mut _, str as _, strlen(str) + 1) @@ -281,8 +281,7 @@ pub extern "C" fn z_view_str_len(this: &z_loaned_str_t) -> usize { } #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_view_str_data(this: &z_loaned_str_t) -> *const libc::c_char { +pub extern "C" fn z_str_data(this: &z_loaned_str_t) -> *const libc::c_char { z_slice_data(this.transmute_ref().transmute_handle()) as _ } @@ -292,17 +291,21 @@ pub extern "C" fn z_str_clone(this: &z_loaned_str_t, dst: *mut MaybeUninit &z_loaned_slice_t { + this.transmute_ref().transmute_handle() +} + pub use crate::opaque_types::z_loaned_slice_map_t; pub use crate::opaque_types::z_owned_slice_map_t; pub type ZHashMap = HashMap, Cow<'static, [u8]>>; -pub use crate::opaque_types::z_loaned_config_t; decl_transmute_handle!( HashMap, Cow<'static, [u8]>>, z_loaned_slice_map_t ); -pub use crate::opaque_types::z_owned_config_t; decl_transmute_owned!( Option, Cow<'static, [u8]>>>, z_owned_slice_map_t @@ -372,7 +375,7 @@ pub extern "C" fn z_slice_map_is_empty(this: &z_loaned_slice_map_t) -> bool { /// `key` and `value` are loaned to the body for the duration of a single call. /// `context` is passed transparently through the iteration driver. /// -/// Returning `true` is treated as `continue`. +/// Returning `true` is treated as `break`. #[allow(non_camel_case_types)] pub type z_slice_map_iter_body_t = extern "C" fn(key: &z_loaned_slice_t, value: &z_loaned_slice_t, context: *mut c_void) -> bool; @@ -387,7 +390,7 @@ pub extern "C" fn z_slice_map_iterate( for (key, value) in this { let key_slice = key.as_ref(); let value_slice = value.as_ref(); - if !body( + if body( key_slice.transmute_handle(), value_slice.transmute_handle(), context, @@ -450,3 +453,123 @@ pub extern "C" fn z_slice_map_insert_by_alias( None => 0, } } + + +pub use crate::opaque_types::z_owned_slice_array_t; +pub use crate::opaque_types::z_loaned_slice_array_t; + +pub type ZVector = Vec>; +decl_transmute_handle!( + Vec>, + z_loaned_slice_array_t +); + +decl_transmute_owned!( + Option>>, + z_owned_slice_array_t +); + +/// Constructs a new empty array. +#[no_mangle] +pub extern "C" fn z_slice_array_new(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + let a = ZVector::new(); + Inplace::init(this, Some(a)); +} + +/// Constructs the gravestone value for `z_owned_slice_array_t` +#[no_mangle] +pub extern "C" fn z_slice_array_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); +} + +/// Returns `true` if the array is not in its gravestone state +#[no_mangle] +pub extern "C" fn z_slice_array_check(this: &z_owned_slice_array_t) -> bool { + let this = this.transmute_ref(); + this.as_ref().is_some() +} + +/// Destroys the array, resetting `this` to its gravestone value. +/// +/// This function is double-free safe, passing a pointer to the gravestone value will have no effect. +#[no_mangle] +pub extern "C" fn z_slice_array_drop(this: &mut z_owned_slice_array_t) { + let this = this.transmute_mut(); + Inplace::drop(this); +} + +#[no_mangle] +pub extern "C" fn z_slice_array_loan(this: &z_owned_slice_array_t) -> &z_loaned_slice_array_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() +} + +#[no_mangle] +pub extern "C" fn z_slice_array_loan_mut( + this: &mut z_owned_slice_array_t, +) -> &mut z_loaned_slice_array_t { + let this = this.transmute_mut(); + let this = unwrap_ref_unchecked_mut(this); + this.transmute_handle_mut() +} + +/// Returns number of key-value pairs in the map. +#[no_mangle] +pub extern "C" fn z_slice_array_len(this: &z_loaned_slice_array_t) -> usize { + this.transmute_ref().len() +} + +/// Returns true if the array is empty, false otherwise. +#[no_mangle] +pub extern "C" fn z_slice_array_is_empty(this: &z_loaned_slice_array_t) -> bool { + z_slice_array_len(this) == 0 +} + + +/// Returns the value at the position of index in the array. +/// +/// Will return NULL if the index is out of bounds. +#[no_mangle] +pub extern "C" fn z_slice_array_get( + this: &z_loaned_slice_array_t, + index: usize, +) -> *const z_loaned_slice_t { + let a = this.transmute_ref(); + if index >= a.len() { + return null(); + } + + a[index].as_ref().transmute_handle() as *const _ +} + +/// Appends specified value to the end of the array by copying. +/// +/// Returns the new length of the array. +#[no_mangle] +pub extern "C" fn z_slice_array_push_by_copy( + this: &mut z_loaned_slice_array_t, + value: &z_loaned_slice_t, +) -> usize { + let this = this.transmute_mut(); + let v = (*value.transmute_ref()).to_owned(); + this.push(Cow::Owned(v)); + + this.len() +} + +/// Appends specified value to the end of the array by aliasing. +/// +/// Returns the new length of the array. +#[no_mangle] +pub extern "C" fn z_slice_array_push_by_alias( + this: &mut z_loaned_slice_array_t, + value: &z_loaned_slice_t, +) -> usize { + let this = this.transmute_mut(); + this.push(Cow::Borrowed(value.transmute_ref())); + + this.len() +} \ No newline at end of file diff --git a/src/commons.rs b/src/commons.rs index 11a6a28b3..d13b5b4d4 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -34,13 +34,13 @@ use zenoh::prelude::SampleKind; use zenoh::publication::CongestionControl; use zenoh::publication::Priority; use zenoh::query::ConsolidationMode; -use zenoh::query::Mode; use zenoh::query::QueryTarget; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::Sample; use zenoh::time::Timestamp; use zenoh::value::Value; +use zenoh_protocol::zenoh::Consolidation; /// A zenoh unsigned integer #[allow(non_camel_case_types)] @@ -281,6 +281,17 @@ decl_transmute_owned!(Value, z_owned_value_t); pub use crate::opaque_types::z_loaned_value_t; decl_transmute_handle!(Value, z_loaned_value_t); + +#[no_mangle] +pub extern "C" fn z_value_payload(this: &z_loaned_value_t) -> &z_loaned_bytes_t { + this.transmute_ref().payload().transmute_handle() +} + +#[no_mangle] +pub extern "C" fn z_value_encoding(this: &z_loaned_value_t) -> &z_loaned_encoding_t { + this.transmute_ref().encoding().transmute_handle() +} + #[repr(C)] #[derive(Clone, Copy, Debug)] pub enum zcu_locality_t { @@ -408,16 +419,6 @@ pub enum z_consolidation_mode_t { LATEST = 2, } -impl From> for z_consolidation_mode_t { - #[inline] - fn from(cm: Mode) -> Self { - match cm { - Mode::Manual(cm) => Self::from(cm), - Mode::Auto => z_consolidation_mode_t::AUTO, - } - } -} - impl From for z_consolidation_mode_t { #[inline] fn from(cm: ConsolidationMode) -> Self { @@ -430,14 +431,14 @@ impl From for z_consolidation_mode_t { } } -impl From for Mode { +impl From for ConsolidationMode { #[inline] fn from(val: z_consolidation_mode_t) -> Self { match val { - z_consolidation_mode_t::AUTO => Mode::Auto, - z_consolidation_mode_t::NONE => Mode::Manual(ConsolidationMode::None), - z_consolidation_mode_t::MONOTONIC => Mode::Manual(ConsolidationMode::Monotonic), - z_consolidation_mode_t::LATEST => Mode::Manual(ConsolidationMode::Latest), + z_consolidation_mode_t::AUTO => Consolidation::Auto, + z_consolidation_mode_t::NONE => ConsolidationMode::None, + z_consolidation_mode_t::MONOTONIC => ConsolidationMode::Monotonic, + z_consolidation_mode_t::LATEST => ConsolidationMode::Latest, } } } diff --git a/src/get.rs b/src/get.rs index d627a9075..78f2d184e 100644 --- a/src/get.rs +++ b/src/get.rs @@ -13,6 +13,7 @@ // use libc::c_char; +use zenoh::selector::Selector; use std::ffi::CStr; use std::mem::MaybeUninit; use std::ptr::null; @@ -20,7 +21,7 @@ use std::ptr::null_mut; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; -use zenoh::prelude::{ConsolidationMode, Mode, QueryConsolidation, QueryTarget, Reply}; +use zenoh::prelude::{ConsolidationMode, QueryConsolidation, QueryTarget, Reply}; use crate::errors; use crate::transmute::unwrap_ref_unchecked; @@ -162,8 +163,7 @@ pub unsafe extern "C" fn z_get( }; let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - - let mut get = session.get(key_expr.clone().with_parameters(p)); + let mut get = session.get(Selector::new(key_expr, p)); if let Some(options) = options { if !options.payload.is_null() { if let Some(payload) = unsafe { *options.payload }.transmute_mut().extract() { @@ -201,6 +201,7 @@ pub unsafe extern "C" fn z_get( pub extern "C" fn z_reply_drop(this: &mut z_owned_reply_t) { Inplace::drop(this.transmute_mut()) } + /// Returns ``true`` if `reply` is valid. #[no_mangle] pub extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { @@ -208,7 +209,7 @@ pub extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { } #[no_mangle] -pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> &z_loaned_reply_t { +pub extern "C" fn z_reply_loan(this: & z_owned_reply_t) -> &z_loaned_reply_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -233,11 +234,8 @@ impl From for z_query_consolidation_t { impl From for QueryConsolidation { #[inline] fn from(val: z_query_consolidation_t) -> Self { - let cm: Mode = val.mode.into(); - match cm { - Mode::Manual(cm) => QueryConsolidation::from(cm), - Mode::Auto => QueryConsolidation::AUTO, - } + let cm: ConsolidationMode = val.mode.into(); + cm.into() } } diff --git a/src/info.rs b/src/info.rs index a7a23131e..c3b951d38 100644 --- a/src/info.rs +++ b/src/info.rs @@ -34,7 +34,7 @@ impl From<[u8; 16]> for z_id_t { /// to pass it a valid session. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_info_zid(session: z_loaned_session_t) -> z_id_t { +pub unsafe extern "C" fn z_info_zid(session: &z_loaned_session_t) -> z_id_t { let session = session.transmute_ref(); session.info().zid().res_sync().transmute_copy() } @@ -48,7 +48,7 @@ pub unsafe extern "C" fn z_info_zid(session: z_loaned_session_t) -> z_id_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_peers_zid( - session: z_loaned_session_t, + session: &z_loaned_session_t, callback: &mut z_owned_closure_zid_t, ) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); @@ -69,7 +69,7 @@ pub unsafe extern "C" fn z_info_peers_zid( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_routers_zid( - session: z_loaned_session_t, + session: &z_loaned_session_t, callback: &mut z_owned_closure_zid_t, ) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 4c2e75494..a4496aa09 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -149,7 +149,7 @@ pub extern "C" fn z_keyexpr_loan(key_expr: &z_owned_keyexpr_t) -> &z_loaned_keye unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } -/// Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. +/// Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_view_keyexpr_t`. #[no_mangle] pub extern "C" fn z_view_keyexpr_loan(key_expr: &z_view_keyexpr_t) -> &z_loaned_keyexpr_t { unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() @@ -237,7 +237,7 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) } } -/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_view_keyexpr_from_slice( @@ -263,7 +263,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice( } } -/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string. /// 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)] @@ -293,7 +293,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice_autocanonize( } } -/// Constructs a :c:type:`z_loaned_keyexpr_t` departing from a string. +/// Constructs a :c:type:`z_view_keyexpr_t` departing from a string. /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] @@ -310,7 +310,7 @@ pub unsafe extern "C" fn z_view_keyexpr( } } -/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string. /// 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)] @@ -332,7 +332,7 @@ pub unsafe extern "C" fn z_view_keyexpr_autocanonize( } } -/// Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string without checking any of `z_view_keyexpr_t`'s assertions: /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: /// - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -353,7 +353,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice_unchecked( Inplace::init(this.transmute_uninit_ptr(), Some(name)) } -/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string without checking any of `z_view_keyexpr_t`'s assertions: /// /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: @@ -362,21 +362,21 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice_unchecked( /// - any instance of `**` may only be lead or followed by `/`. /// - the key expression must have canon form. /// -/// It is a loaned key expression that aliases `name`. +/// It is a view key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_unchecked( +pub unsafe extern "C" fn z_view_keyexpr_unchecked( this: *mut MaybeUninit, - name: *const c_char, + s: *const c_char ) { - z_view_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) + z_view_keyexpr_from_slice_unchecked(this, s, libc::strlen(s)) } /// Constructs a null-terminated string departing from a :c:type:`z_loaned_keyexpr_t`. /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_loaned_keyexpr_to_string( +pub unsafe extern "C" fn z_keyexpr_to_string( ke: &z_loaned_keyexpr_t, s: *mut MaybeUninit, ) { diff --git a/src/liveliness.rs b/src/liveliness.rs index ae48097e7..c42e25e12 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -47,6 +47,12 @@ pub extern "C" fn zc_liveliness_token_null(this: *mut MaybeUninit bool { this.transmute_ref().is_some() } + +#[no_mangle] +pub extern "C" fn zc_liveliness_token_drop(this: &mut zc_owned_liveliness_token_t) { + let this = this.transmute_mut(); + Inplace::drop(this); +} /// The options for `zc_liveliness_declare_token` #[repr(C)] pub struct zc_liveliness_declaration_options_t { diff --git a/src/payload.rs b/src/payload.rs index 1283f28a6..b760245a2 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -4,8 +4,7 @@ use crate::transmute::{ TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{ - z_loaned_slice_map_t, z_loaned_slice_t, z_loaned_str_t, z_owned_slice_map_t, z_owned_slice_t, - z_owned_str_t, ZHashMap, + z_loaned_slice_map_t, z_loaned_slice_t, z_loaned_str_t, z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, ZHashMap }; use core::fmt; use std::any::Any; @@ -95,7 +94,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( - payload: z_loaned_bytes_t, + payload: &z_loaned_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let dst = dst.transmute_uninit_ptr(); @@ -157,7 +156,7 @@ impl ZSliceBuffer for z_loaned_slice_t { /// Encodes byte sequence by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_encode_from_bytes( +pub unsafe extern "C" fn z_bytes_encode_from_slice( this: *mut MaybeUninit, bytes: &z_loaned_slice_t, ) { @@ -179,7 +178,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( Inplace::init(dst, Some(payload)); } -/// Encodes a null-terminated string by aliasing. +/// Encodes a loaned string by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_string( @@ -189,7 +188,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( let s = s.transmute_ref(); let ss = &s[0..s.len() - 1]; let b = ss.transmute_handle(); - z_bytes_encode_from_bytes(this, b); + z_bytes_encode_from_slice(this, b); } pub use crate::opaque_types::z_owned_bytes_reader_t; diff --git a/src/queryable.rs b/src/queryable.rs index 03da4edbe..fd2589d3d 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -211,8 +211,8 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_reply( - query: z_loaned_query_t, - key_expr: z_loaned_keyexpr_t, + query: &z_loaned_query_t, + key_expr: &z_loaned_keyexpr_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_query_reply_options_t>, ) -> errors::z_error_t { diff --git a/src/scouting.rs b/src/scouting.rs index 7a7931301..b13a4bd2f 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -12,165 +12,70 @@ // ZettaScale Zenoh team, // use crate::{ - errors::{self, Z_OK}, - transmute::{Inplace, TransmuteRef}, - z_closure_hello_call, z_config_check, z_config_clone, z_config_default, z_config_drop, - z_config_null, z_id_t, z_loaned_config_t, z_owned_closure_hello_t, z_owned_config_t, - zc_init_logger, CopyableToCArray, + errors::{self, Z_OK}, transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}, z_closure_hello_call, z_config_check, z_config_clone, z_config_default, z_config_drop, z_config_null, z_id_t, z_loaned_config_t, z_owned_closure_hello_t, z_owned_config_t, z_owned_slice_array_t, zc_init_logger, CopyableToCArray, ZVector }; use async_std::task; -use libc::{c_char, c_uint, c_ulong, size_t}; -use std::{ffi::CString, mem::MaybeUninit, os::raw::c_void}; +use libc::{c_char, c_ulong}; +use std::{borrow::Cow, mem::MaybeUninit, os::raw::c_void}; use zenoh::scouting::Hello; use zenoh_protocol::core::{whatami::WhatAmIMatcher, WhatAmI}; use zenoh_util::core::AsyncResolve; -/// An owned array of owned, zenoh allocated, NULL terminated strings. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C)] -pub struct z_owned_str_array_t { - pub val: *mut *mut c_char, - pub len: size_t, -} +pub use crate::opaque_types::z_owned_hello_t; +pub use crate::opaque_types::z_loaned_hello_t; -/// Frees `strs` and invalidates it for double-drop safety. -#[allow(clippy::missing_safety_doc)] +decl_transmute_owned!(Option, z_owned_hello_t); +decl_transmute_handle!(Hello, z_loaned_hello_t); + + +/// Frees `hello`, invalidating it for double-drop safety. #[no_mangle] -pub unsafe extern "C" fn z_str_array_drop(strs: &mut z_owned_str_array_t) { - let vals = Vec::from_raw_parts(strs.val as *mut *const c_char, strs.len, strs.len); - for val in vals { - std::mem::drop(CString::from_raw(val as *mut c_char)); - } - strs.val = std::ptr::null_mut(); - strs.len = 0; +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_hello_drop(this: &mut z_owned_hello_t) { + Inplace::drop(this.transmute_mut()) } -/// Returns ``true`` if `strs` is valid. -#[allow(clippy::missing_safety_doc)] +/// Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. #[no_mangle] -pub extern "C" fn z_str_array_check(strs: &z_owned_str_array_t) -> bool { - !strs.val.is_null() +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_hello_loan(this: &z_owned_hello_t) -> &z_loaned_hello_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } -/// An borrowed array of borrowed, zenoh allocated, NULL terminated strings. -#[repr(C)] -pub struct z_str_array_t { - pub len: size_t, - pub val: *const *const c_char, +#[no_mangle] +pub extern "C" fn z_hello_check(this: &z_owned_hello_t) -> bool { + this.transmute_ref().is_some() } -/// Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. -#[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_str_array_loan(strs: &z_owned_str_array_t) -> &z_str_array_t { - std::mem::transmute(strs) -} -/// A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. -/// -/// Members: -/// unsigned int whatami: The kind of zenoh entity. -/// z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). -/// z_owned_str_array_t locators: The locators of the scouted entity. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[repr(C)] -pub struct z_owned_hello_t { - pub _whatami: c_uint, - pub _pid: z_id_t, - pub _locators: z_owned_str_array_t, -} -/// A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. -/// -/// Members: -/// unsigned int whatami: The kind of zenoh entity. -/// z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). -/// z_owned_str_array_t locators: The locators of the scouted entity. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[repr(C)] -pub struct z_hello_t { - pub whatami: c_uint, - pub pid: z_id_t, - pub locators: z_str_array_t, +pub extern "C" fn z_hello_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } -impl From for z_owned_hello_t { - fn from(h: Hello) -> Self { - z_owned_hello_t { - _whatami: h.whatami as c_uint, - _pid: unsafe { std::mem::transmute(h.zid) }, - _locators: if !h.locators.is_empty() { - let mut locators = h - .locators - .into_iter() - .map(|l| CString::new(l.to_string()).unwrap().into_raw()) - .collect::>(); - let val = locators.as_mut_ptr(); - let len = locators.len(); - std::mem::forget(locators); - z_owned_str_array_t { val, len } - } else { - z_owned_str_array_t { - val: std::ptr::null_mut(), - len: 0, - } - }, - } - } -} -/// Frees `hello`, invalidating it for double-drop safety. #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_hello_drop(hello: &mut z_owned_hello_t) { - z_str_array_drop(&mut hello._locators); - hello._whatami = 0; +pub extern "C" fn z_hello_zid(this: &z_loaned_hello_t) -> z_id_t { + this.transmute_ref().zid.transmute_copy() } -/// Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_hello_loan(hello: &z_owned_hello_t) -> &z_hello_t { - std::mem::transmute(hello) +pub extern "C" fn z_hello_whatami(this: &z_loaned_hello_t) -> u8 { + this.transmute_ref().whatami as u8 } -/// Constructs a gravestone value for hello, useful to steal one from a callback +/// Returns an array of non-owned locators as an array of non-null terminated strings. +/// +/// The lifetime of locator strings is bound to `this`. #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_hello_null(this: *mut MaybeUninit) { - let h = z_owned_hello_t { - _whatami: 0, - _pid: [0; 16].into(), - _locators: z_owned_str_array_t { - val: std::ptr::null_mut(), - len: 0, - }, - }; - (*this).write(h); -} -impl Drop for z_owned_hello_t { - fn drop(&mut self) { - unsafe { z_hello_drop(self) }; +pub extern "C" fn z_hello_locators(this: &z_loaned_hello_t, locators_out: *mut MaybeUninit) { + let this = this.transmute_ref(); + let mut locators = ZVector::with_capacity(this.locators.len()); + for l in this.locators.iter() { + locators.push(Cow::Borrowed(l.as_str().as_bytes())); } -} -/// Returns ``true`` if `hello` is valid. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_hello_check(hello: &z_owned_hello_t) -> bool { - hello._whatami != 0 && z_str_array_check(&hello._locators) + Inplace::init(locators_out.transmute_uninit_ptr(), Some(locators)); } #[repr(C)] @@ -277,8 +182,7 @@ pub extern "C" fn z_scout( task::block_on(async move { let scout = zenoh::scout(what, config) .callback(move |h| { - let mut hello = h.into(); - z_closure_hello_call(&closure, &mut hello) + z_closure_hello_call(&closure, h.transmute_handle()) }) .res_async() .await diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 57bb31fd9..d7041a7dc 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -44,7 +44,7 @@ volatile unsigned int queries = 0; void query_handler(const z_loaned_query_t *query, void *arg) { queries++; - z_owned_str_t k_str = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); + z_owned_str_t k_str = z_keyexpr_to_string(z_query_keyexpr(query)); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, z_query_keyexpr(query)); @@ -69,7 +69,7 @@ void reply_handler(z_owned_reply_t *reply, void *arg) { if (z_reply_is_ok(reply)) { z_loaned_sample_t sample = z_reply_ok(reply); - z_owned_str_t k_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, sample.keyexpr); @@ -88,7 +88,7 @@ volatile unsigned int datas = 0; void data_handler(const z_loaned_sample_t *sample, void *arg) { datas++; - z_owned_str_t k_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(sample)); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, sample->keyexpr); diff --git a/tests/z_api_keyexpr_drop_test.c b/tests/z_api_keyexpr_drop_test.c index 08b77038d..f451fa974 100644 --- a/tests/z_api_keyexpr_drop_test.c +++ b/tests/z_api_keyexpr_drop_test.c @@ -29,7 +29,7 @@ void test_publisher() { z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); strncpy(keyexpr, "baz/quax", 256); // Update source string to ensure that the correct keyexpr z_owned_keyexpr_t pub_keyexpr = z_publisher_keyexpr(z_loan(pub)); - z_owned_str_t pub_keyexpr_str = z_loaned_keyexpr_to_string(z_loan(pub_keyexpr)); + z_owned_str_t pub_keyexpr_str = z_keyexpr_to_string(z_loan(pub_keyexpr)); assert(strcmp(z_loan(pub_keyexpr_str), "foo/bar") == 0); // Check that publisher keeps the correct keyexpr z_drop(z_move(pub_keyexpr_str)); z_drop(z_move(pub)); @@ -59,7 +59,7 @@ void test_subscriber() { z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); strncpy(keyexpr, "baz/quax", 256); // Update source string to ensure that the keyexpr is copied into the subscriber z_owned_keyexpr_t sub_keyexpr = z_subscriber_keyexpr(z_loan(sub)); - z_owned_str_t sub_keyexpr_str = z_loaned_keyexpr_to_string(z_loan(sub_keyexpr)); + z_owned_str_t sub_keyexpr_str = z_keyexpr_to_string(z_loan(sub_keyexpr)); assert(strcmp(z_loan(sub_keyexpr_str), "foo/bar") == 0); // Check that subscriber keeps the correct keyexpr z_drop(z_move(sub_keyexpr_str)); z_drop(z_move(sub)); diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 742f2d656..aba2262c9 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -87,7 +87,7 @@ int run_publisher() { void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index a2dba9b6b..4ca671d46 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -67,7 +67,7 @@ int run_publisher() { void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index 4907af56e..1892095e7 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -60,7 +60,7 @@ int run_publisher() { void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 7582a9e92..1c3e203d1 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -32,7 +32,7 @@ const char *const V_CONST = "v const"; void query_handler(const z_loaned_query_t *query, void *context) { static int value_num = 0; - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); + z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); z_loaned_slice_t pred = z_query_parameters(query); z_loaned_value_t payload_value = z_query_value(query); @@ -109,7 +109,7 @@ int run_get() { assert(z_reply_is_ok(&reply)); z_loaned_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index d22d5b6ab..025e35746 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -28,7 +28,7 @@ const size_t values_count = sizeof(values) / sizeof(values[0]); void query_handler(const z_loaned_query_t *query, void *context) { static int value_num = 0; - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); + z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); z_loaned_slice_t pred = z_query_parameters(query); z_loaned_value_t payload_value = z_query_value(query); @@ -85,7 +85,7 @@ int run_get() { assert(z_reply_is_ok(&reply)); z_loaned_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { From 45d04d9e9d29287993dbb2f263527b7eedecc09f Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 30 Apr 2024 23:15:13 +0200 Subject: [PATCH 066/377] tests build --- docs/api.rst | 2 +- examples/z_delete.c | 2 +- examples/z_get.c | 4 +- examples/z_get_liveliness.c | 2 +- examples/z_liveliness.c | 2 +- examples/z_non_blocking_get.c | 2 +- examples/z_pub.c | 2 +- examples/z_pub_attachment.c | 4 +- examples/z_pub_cache.c | 2 +- examples/z_pub_thr.c | 2 +- examples/z_put.c | 4 +- examples/z_query_sub.c | 2 +- examples/z_queryable.c | 4 +- examples/z_queryable_with_channels.c | 2 +- examples/z_sub.c | 2 +- examples/z_sub_attachment.c | 4 +- examples/z_sub_liveliness.c | 2 +- examples/z_sub_thr.c | 2 +- include/zenoh_commons.h | 70 +++++----- src/keyexpr.rs | 12 +- src/payload.rs | 10 +- tests/z_api_alignment_test.c | 178 +++++++++++------------- tests/z_api_attachment_test.c | 125 ----------------- tests/z_api_config_test.c | 17 ++- tests/z_api_double_drop_test.c | 95 +++++++------ tests/z_api_keyexpr_drop_test.c | 81 +++++------ tests/z_api_keyexpr_test.c | 79 ++++++----- tests/z_api_map_test.c | 109 +++++++++++++++ tests/z_api_null_drop_test.c | 132 +++++++++++------- tests/z_api_payload_test.c | 28 ++-- tests/z_api_unitinialized_check.c | 6 +- tests/z_int_helpers.h | 6 +- tests/z_int_pub_cache_query_sub_test.c | 76 ++++++---- tests/z_int_pub_sub_attachment_test.c | 94 +++++++++---- tests/z_int_pub_sub_test.c | 60 +++++--- tests/z_int_queryable_attachment_test.c | 149 ++++++++++++++------ tests/z_int_queryable_test.c | 86 +++++++----- 37 files changed, 811 insertions(+), 648 deletions(-) delete mode 100644 tests/z_api_attachment_test.c create mode 100644 tests/z_api_map_test.c diff --git a/docs/api.rst b/docs/api.rst index f7af3cf82..7cdae18fe 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -111,7 +111,7 @@ Key expression .. 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 +.. autocfunction:: zenoh_commons.h::z_keyexpr_as_slice .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize_null_terminated .. autocfunction:: zenoh_commons.h::z_keyexpr_is_canon diff --git a/examples/z_delete.c b/examples/z_delete.c index 7ff5e3078..14d39c6fc 100644 --- a/examples/z_delete.c +++ b/examples/z_delete.c @@ -42,7 +42,7 @@ int main(int argc, char **argv) { printf("Deleting resources matching '%s'...\n", keyexpr); z_view_keyexpr_t ke; - z_view_keyexpr(&ke, keyexpr); + z_view_keyexpr_new(&ke, keyexpr); int res = z_delete(z_loan(s), z_loan(ke), NULL); if (res < 0) { printf("Delete failed...\n"); diff --git a/examples/z_get.c b/examples/z_get.c index 5973f43c5..7662d4b46 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -31,7 +31,7 @@ int main(int argc, char **argv) { break; } z_view_keyexpr_t keyexpr; - if (z_view_keyexpr(&keyexpr, expr) < 0) { + if (z_view_keyexpr_new(&keyexpr, expr) < 0) { printf("%s is not a valid key expression", expr); exit(-1); } @@ -88,9 +88,9 @@ int main(int argc, char **argv) { } else { printf("Received an error\n"); } + z_drop(z_move(reply)); } - z_drop(z_move(reply)); z_drop(z_move(channel)); z_close(z_move(s)); return 0; diff --git a/examples/z_get_liveliness.c b/examples/z_get_liveliness.c index ffcd58d9b..62b76b006 100644 --- a/examples/z_get_liveliness.c +++ b/examples/z_get_liveliness.c @@ -23,7 +23,7 @@ int main(int argc, char **argv) { } z_view_keyexpr_t keyexpr; - if (z_view_keyexpr(&keyexpr, expr) < 0) { + if (z_view_keyexpr_new(&keyexpr, expr) < 0) { printf("%s is not a valid key expression\n", expr); exit(-1); } diff --git a/examples/z_liveliness.c b/examples/z_liveliness.c index 5359fcde9..3d6f4561b 100644 --- a/examples/z_liveliness.c +++ b/examples/z_liveliness.c @@ -22,7 +22,7 @@ int main(int argc, char **argv) { } z_view_keyexpr_t keyexpr; - if (z_view_keyexpr(&keyexpr, expr) < 0) { + if (z_view_keyexpr_new(&keyexpr, expr) < 0) { printf("%s is not a valid key expression\n", expr); exit(-1); } diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index 64929d0ca..746fb2e7b 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -22,7 +22,7 @@ int main(int argc, char **argv) { expr = argv[1]; } z_view_keyexpr_t keyexpr; - if (z_view_keyexpr(&keyexpr, expr) < 0) { + if (z_view_keyexpr_new(&keyexpr, expr) < 0) { printf("%s is not a valid key expression", expr); exit(-1); } diff --git a/examples/z_pub.c b/examples/z_pub.c index e9ab32751..7c0222f05 100644 --- a/examples/z_pub.c +++ b/examples/z_pub.c @@ -55,7 +55,7 @@ int main(int argc, char **argv) { printf("Declaring Publisher on '%s'...\n", keyexpr); z_owned_publisher_t pub; z_view_keyexpr_t ke; - z_view_keyexpr(&ke, keyexpr); + z_view_keyexpr_new(&ke, keyexpr); if (z_declare_publisher(&pub, z_loan(s), z_loan(ke), NULL) < 0) { printf("Unable to declare Publisher for key expression!\n"); exit(-1); diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index 81064c2c7..eef6c57c8 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -44,7 +44,7 @@ int main(int argc, char **argv) { printf("Declaring Publisher on '%s'...\n", keyexpr); z_view_keyexpr_t ke; - z_view_keyexpr(&ke, keyexpr); + z_view_keyexpr_new(&ke, keyexpr); z_owned_publisher_t pub; if (z_declare_publisher(&pub, z_loan(s), z_loan(ke), NULL)) { printf("Unable to declare Publisher for key expression!\n"); @@ -77,7 +77,7 @@ int main(int argc, char **argv) { z_view_slice_from_str(&index_key, "index"); z_view_slice_from_str(&index_value, buf_ind); z_slice_map_insert_by_alias(z_loan_mut(map), z_loan(index_key), z_loan(index_value)); - z_bytes_encode_from_bytes_map(&attachment, z_loan(map)); + z_bytes_encode_from_slice_map(&attachment, z_loan(map)); options.attachment = &attachment; sprintf(buf, "[%4d] %s", idx, value); diff --git a/examples/z_pub_cache.c b/examples/z_pub_cache.c index f21bed5f7..a1a995773 100644 --- a/examples/z_pub_cache.c +++ b/examples/z_pub_cache.c @@ -55,7 +55,7 @@ int main(int argc, char **argv) { printf("Declaring publication cache on '%s'...\n", keyexpr); ze_owned_publication_cache_t pub_cache; z_view_keyexpr_t ke; - z_view_keyexpr(&ke, keyexpr); + z_view_keyexpr_new(&ke, keyexpr); ze_declare_publication_cache(&pub_cache, z_loan(s), z_loan(ke), &pub_cache_opts); if (!z_check(pub_cache)) { printf("Unable to declare publication cache for key expression!\n"); diff --git a/examples/z_pub_thr.c b/examples/z_pub_thr.c index 2610bcf63..41ad1164d 100644 --- a/examples/z_pub_thr.c +++ b/examples/z_pub_thr.c @@ -51,7 +51,7 @@ int main(int argc, char **argv) { z_owned_publisher_t pub; z_view_keyexpr_t ke; - z_view_keyexpr(&ke, keyexpr); + z_view_keyexpr_new(&ke, keyexpr); if (z_declare_publisher(&pub, z_loan(s), z_loan(ke), &options)) { printf("Unable to declare publisher for key expression!\n"); exit(-1); diff --git a/examples/z_put.c b/examples/z_put.c index 7f33ff2d8..11ae536bc 100644 --- a/examples/z_put.c +++ b/examples/z_put.c @@ -53,7 +53,7 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, value); z_view_keyexpr_t ke; - z_view_keyexpr(&ke, keyexpr); + z_view_keyexpr_new(&ke, keyexpr); z_view_str_t payload_string; z_view_str_wrap(&payload_string, value); @@ -62,7 +62,7 @@ int main(int argc, char **argv) { z_bytes_encode_from_string(&payload, z_loan(payload_string)); z_owned_bytes_t attachment; - z_bytes_encode_from_bytes_map(&attachment, z_loan(attachment_map)); + z_bytes_encode_from_slice_map(&attachment, z_loan(attachment_map)); z_put_options_t options; z_put_options_default(&options); diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index c2b7fceb7..b7272901e 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -56,7 +56,7 @@ int main(int argc, char **argv) { } z_view_keyexpr_t ke; - z_view_keyexpr(&ke, keyexpr); + z_view_keyexpr_new(&ke, keyexpr); ze_querying_subscriber_options_t sub_opts; ze_querying_subscriber_options_default(&sub_opts); diff --git a/examples/z_queryable.c b/examples/z_queryable.c index c3618081d..be7866d02 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -48,7 +48,7 @@ void query_handler(const z_loaned_query_t *query, void *context) { z_bytes_encode_from_string(&reply_payload, z_loan(reply_string)); z_view_keyexpr_t reply_keyexpr; - z_view_keyexpr(&reply_keyexpr, (const char *)context); + z_view_keyexpr_new(&reply_keyexpr, (const char *)context); z_query_reply(query, z_loan(reply_keyexpr), z_move(reply_payload), &options); z_drop(z_move(key_string)); @@ -77,7 +77,7 @@ int main(int argc, char **argv) { exit(-1); } - if (z_view_keyexpr(&ke, keyexpr)) { + if (z_view_keyexpr_new(&ke, keyexpr)) { printf("%s is not a valid key expression", keyexpr); exit(-1); } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 13a79be4a..2a88c3ed0 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -50,7 +50,7 @@ int main(int argc, char **argv) { exit(-1); } - if (z_view_keyexpr(&ke, keyexpr) < 0) { + if (z_view_keyexpr_new(&ke, keyexpr) < 0) { printf("%s is not a valid key expression", keyexpr); exit(-1); } diff --git a/examples/z_sub.c b/examples/z_sub.c index 144880e7b..56bed9d86 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -37,7 +37,7 @@ int main(int argc, char **argv) { } z_view_keyexpr_t ke; - z_view_keyexpr(&ke, keyexpr); + z_view_keyexpr_new(&ke, keyexpr); z_owned_config_t config; z_config_default(&config); diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 970c197f4..ffe588288 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -40,7 +40,7 @@ void data_handler(const z_loaned_sample_t *sample, void *arg) { if (attachment != NULL) { // reads full attachment z_owned_slice_map_t attachment_map; - z_bytes_decode_into_bytes_map(attachment, &attachment_map); + z_bytes_decode_into_slice_map(attachment, &attachment_map); z_slice_map_iterate(z_loan(attachment_map), attachment_map_reader, NULL); @@ -64,7 +64,7 @@ int main(int argc, char **argv) { } z_view_keyexpr_t ke; - z_view_keyexpr(&ke, keyexpr); + z_view_keyexpr_new(&ke, keyexpr); z_owned_config_t config; z_config_default(&config); diff --git a/examples/z_sub_liveliness.c b/examples/z_sub_liveliness.c index 5dc05a1f1..1bc76a72d 100644 --- a/examples/z_sub_liveliness.c +++ b/examples/z_sub_liveliness.c @@ -35,7 +35,7 @@ int main(int argc, char **argv) { } z_view_keyexpr_t ke; - if (z_view_keyexpr(&ke, keyexpr) < 0) { + if (z_view_keyexpr_new(&ke, keyexpr) < 0) { printf("%s is not a valid key expression\n", keyexpr); exit(-1); } diff --git a/examples/z_sub_thr.c b/examples/z_sub_thr.c index 2513cd654..b844121d3 100644 --- a/examples/z_sub_thr.c +++ b/examples/z_sub_thr.c @@ -81,7 +81,7 @@ int main(int argc, char **argv) { } z_view_keyexpr_t ke; - z_view_keyexpr(&ke, "test/thr"); + z_view_keyexpr_new(&ke, "test/thr"); z_owned_keyexpr_t declared_ke; z_declare_keyexpr(&declared_ke, z_loan(s), z_loan(ke)); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 05bc707c5..c010593d1 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -154,12 +154,12 @@ typedef struct ALIGN(8) z_owned_slice_map_t { typedef struct ALIGN(8) z_owned_str_t { uint8_t _0[16]; } z_owned_str_t; -typedef struct ALIGN(8) z_loaned_slice_map_t { - uint8_t _0[48]; -} z_loaned_slice_map_t; typedef struct ALIGN(8) z_loaned_slice_t { uint8_t _0[16]; } z_loaned_slice_t; +typedef struct ALIGN(8) z_loaned_slice_map_t { + uint8_t _0[48]; +} z_loaned_slice_map_t; typedef struct ALIGN(8) z_loaned_str_t { uint8_t _0[16]; } z_loaned_str_t; @@ -861,7 +861,7 @@ z_error_t z_bytes_decode_into_bytes(const struct z_loaned_bytes_t *payload, * Decodes payload into bytes map. */ ZENOHC_API -z_error_t z_bytes_decode_into_bytes_map(const struct z_loaned_bytes_t *payload, +z_error_t z_bytes_decode_into_slice_map(const struct z_loaned_bytes_t *payload, struct z_owned_slice_map_t *dst); /** * Decodes payload into null-terminated string. @@ -875,18 +875,18 @@ z_error_t z_bytes_decode_into_string(const struct z_loaned_bytes_t *payload, * `this` will be reset to `z_buffer_null`, preventing UB on double-frees. */ ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); -/** - * Encodes bytes map by copying. - */ -ZENOHC_API -void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, - const struct z_loaned_slice_map_t *bytes_map); /** * Encodes byte sequence by aliasing. */ ZENOHC_API void z_bytes_encode_from_slice(struct z_owned_bytes_t *this_, const struct z_loaned_slice_t *bytes); +/** + * Encodes bytes map by copying. + */ +ZENOHC_API +void z_bytes_encode_from_slice_map(struct z_owned_bytes_t *this_, + const struct z_loaned_slice_map_t *bytes_map); /** * Encodes a loaned string by aliasing. */ @@ -913,12 +913,10 @@ ZENOHC_API struct z_loaned_bytes_reader_t *z_bytes_reader_loan_mut(struct z_owned_bytes_reader_t *reader); /** * Creates a reader for the specified `payload`. - * - * Returns 0 in case of success, -1 if `payload` is not valid. */ ZENOHC_API -void z_bytes_reader_new(struct z_loaned_bytes_t payload, - struct z_owned_bytes_reader_t *this_); +void z_bytes_reader_new(struct z_owned_bytes_reader_t *this_, + const struct z_loaned_bytes_t *payload); ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); /** * Reads data into specified destination. @@ -940,6 +938,11 @@ ZENOHC_API z_error_t z_bytes_reader_seek(struct z_loaned_bytes_reader_t *this_, int64_t offset, int origin); +/** + * Returns the read position indicator. + * Returns read position indicator on success or -1L if failure occurs. + */ +ZENOHC_API int64_t z_bytes_reader_tell(struct z_loaned_bytes_reader_t *this_); ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); @@ -1323,7 +1326,7 @@ ZENOHC_API struct z_id_t z_info_zid(const struct z_loaned_session_t *session); * * Currently exclusive to zenoh-c */ -ZENOHC_API void z_keyexpr_as_bytes(const struct z_loaned_keyexpr_t *ke, struct z_view_slice_t *b); +ZENOHC_API void z_keyexpr_as_slice(const struct z_loaned_keyexpr_t *ke, struct z_view_slice_t *b); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. * @@ -1376,14 +1379,14 @@ ZENOHC_API bool z_keyexpr_equals(const struct z_loaned_keyexpr_t *left, const struct z_loaned_keyexpr_t *right); /** - * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set + * Returns ``true`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set * defined by ``right``. */ ZENOHC_API bool z_keyexpr_includes(const struct z_loaned_keyexpr_t *left, const struct z_loaned_keyexpr_t *right); /** - * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the + * Returns ``true`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the * sets defined by ``left`` and ``right``. */ ZENOHC_API @@ -1410,7 +1413,7 @@ const struct z_loaned_keyexpr_t *z_keyexpr_loan(const struct z_owned_keyexpr_t * /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. */ -ZENOHC_API z_error_t z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); +ZENOHC_API z_error_t z_keyexpr_new(struct z_owned_keyexpr_t *this_, const char *name); /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. */ @@ -1434,11 +1437,6 @@ enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_loaned_ * The user is responsible of droping the returned string using `z_drop` */ ZENOHC_API void z_keyexpr_to_string(const struct z_loaned_keyexpr_t *ke, struct z_owned_str_t *s); -/** - * Returns the read position indicator. - * Returns read position indicator on success or -1L if failure occurs. - */ -ZENOHC_API int64_t z_loaned_bytes_reader_tell(struct z_loaned_bytes_reader_t *this_); ZENOHC_API z_error_t z_loaned_mutex_try_lock(struct z_loaned_mutex_t *this_); /** * Create a default :c:type:`z_loaned_query_target_t`. @@ -2109,19 +2107,6 @@ ZENOHC_API z_error_t z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); ZENOHC_API const struct z_loaned_encoding_t *z_value_encoding(const struct z_loaned_value_t *this_); ZENOHC_API const struct z_loaned_bytes_t *z_value_payload(const struct z_loaned_value_t *this_); -/** - * Constructs a :c:type:`z_view_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API z_error_t z_view_keyexpr(struct z_view_keyexpr_t *this_, const char *name); -/** - * Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string. - * 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 -z_error_t z_view_keyexpr_autocanonize(struct z_view_keyexpr_t *this_, - char *name); /** * Returns ``true`` if `keyexpr` is valid. */ @@ -2161,6 +2146,19 @@ void z_view_keyexpr_from_slice_unchecked(struct z_view_keyexpr_t *this_, */ ZENOHC_API const struct z_loaned_keyexpr_t *z_view_keyexpr_loan(const struct z_view_keyexpr_t *key_expr); +/** + * Constructs a :c:type:`z_view_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API z_error_t z_view_keyexpr_new(struct z_view_keyexpr_t *this_, const char *name); +/** + * Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string. + * 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 +z_error_t z_view_keyexpr_new_autocanonize(struct z_view_keyexpr_t *this_, + char *name); ZENOHC_API void z_view_keyexpr_null(struct z_view_keyexpr_t *this_); /** * Constructs a :c:type:`z_view_keyexpr_t` by aliasing a string without checking any of `z_view_keyexpr_t`'s assertions: diff --git a/src/keyexpr.rs b/src/keyexpr.rs index a4496aa09..75d25f977 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -97,8 +97,8 @@ unsafe fn keyexpr_create( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr_new( - name: *const c_char, this: *mut MaybeUninit, + name: *const c_char, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); if name.is_null() { @@ -297,7 +297,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice_autocanonize( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_view_keyexpr( +pub unsafe extern "C" fn z_view_keyexpr_new( this: *mut MaybeUninit, name: *const c_char, ) -> z_error_t { @@ -315,7 +315,7 @@ pub unsafe extern "C" fn z_view_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_view_keyexpr_autocanonize( +pub unsafe extern "C" fn z_view_keyexpr_new_autocanonize( this: *mut MaybeUninit, name: *mut c_char, ) -> z_error_t { @@ -389,7 +389,7 @@ pub unsafe extern "C" fn z_keyexpr_to_string( /// Currently exclusive to zenoh-c #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_as_bytes( +pub unsafe extern "C" fn z_keyexpr_as_slice( ke: &z_loaned_keyexpr_t, b: *mut MaybeUninit, ) { @@ -460,7 +460,7 @@ pub extern "C" fn z_keyexpr_equals(left: &z_loaned_keyexpr_t, right: &z_loaned_k #[allow(clippy::missing_safety_doc)] #[no_mangle] -/// Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the +/// Returns ``true`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the /// sets defined by ``left`` and ``right``. pub extern "C" fn z_keyexpr_intersects( left: &z_loaned_keyexpr_t, @@ -473,7 +473,7 @@ pub extern "C" fn z_keyexpr_intersects( #[allow(clippy::missing_safety_doc)] #[no_mangle] -/// Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set +/// Returns ``true`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set /// defined by ``right``. pub extern "C" fn z_keyexpr_includes( left: &z_loaned_keyexpr_t, diff --git a/src/payload.rs b/src/payload.rs index b760245a2..d6d5920f2 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -93,7 +93,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( /// Decodes payload into bytes map. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( +pub unsafe extern "C" fn z_bytes_decode_into_slice_map( payload: &z_loaned_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { @@ -168,7 +168,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_slice( /// Encodes bytes map by copying. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( +pub unsafe extern "C" fn z_bytes_encode_from_slice_map( this: *mut MaybeUninit, bytes_map: &z_loaned_slice_map_t, ) { @@ -198,13 +198,11 @@ pub use crate::opaque_types::z_loaned_bytes_reader_t; decl_transmute_handle!(ZBytesReader<'static>, z_loaned_bytes_reader_t); /// Creates a reader for the specified `payload`. -/// -/// Returns 0 in case of success, -1 if `payload` is not valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_new( - payload: z_loaned_bytes_t, this: *mut MaybeUninit, + payload: &z_loaned_bytes_t, ) { let this = this.transmute_uninit_ptr(); let payload = payload.transmute_ref(); @@ -293,7 +291,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( /// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_loaned_bytes_reader_tell(this: &mut z_loaned_bytes_reader_t) -> i64 { +pub unsafe extern "C" fn z_bytes_reader_tell(this: &mut z_loaned_bytes_reader_t) -> i64 { let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index d7041a7dc..7b18d7bd6 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -33,43 +33,51 @@ void zid_handler(const z_id_t *id, void *arg) { } volatile unsigned int hellos = 0; -void hello_handler(z_owned_hello_t *hello, void *arg) { +void hello_handler(const z_loaned_hello_t *hello, void *arg) { (void)(arg); (void)(hello); hellos++; - z_hello_null(); } volatile unsigned int queries = 0; void query_handler(const z_loaned_query_t *query, void *arg) { queries++; - z_owned_str_t k_str = z_keyexpr_to_string(z_query_keyexpr(query)); + const z_loaned_keyexpr_t* query_ke = z_query_keyexpr(query); + z_owned_str_t k_str; + z_keyexpr_to_string(query_ke, &k_str); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, z_query_keyexpr(query)); } #endif - z_loaned_slice_t pred = z_query_parameters(query); - (void)(pred); - z_loaned_value_t payload_value = z_query_value(query); + z_view_slice_t params; + z_query_parameters(query, ¶ms); + (void)(params); + const z_loaned_value_t* payload_value = z_query_value(query); (void)(payload_value); - z_query_reply_options_t _ret_qreply_opt = z_query_reply_options_default(); - z_owned_bytes_t payload = z_bytes_encode_from_string(value); - z_query_reply(query, z_keyexpr(z_loan(k_str)), z_move(payload), &_ret_qreply_opt); + z_query_reply_options_t _ret_qreply_opt; + z_query_reply_options_default(&_ret_qreply_opt); + + z_view_str_t value_str; + z_view_str_wrap(&value_str, value); + z_owned_bytes_t payload; + z_bytes_encode_from_string(&payload, z_loan(value_str)); + z_query_reply(query, query_ke, z_move(payload), &_ret_qreply_opt); z_drop(z_move(k_str)); } volatile unsigned int replies = 0; -void reply_handler(z_owned_reply_t *reply, void *arg) { +void reply_handler(const z_loaned_reply_t *reply, void *arg) { replies++; if (z_reply_is_ok(reply)) { - z_loaned_sample_t sample = z_reply_ok(reply); + const z_loaned_sample_t* sample = z_reply_ok(reply); - z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_owned_str_t k_str; + z_keyexpr_to_string(z_sample_keyexpr(sample), &k_str); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, sample.keyexpr); @@ -77,18 +85,17 @@ void reply_handler(z_owned_reply_t *reply, void *arg) { #endif z_drop(z_move(k_str)); } else { - z_loaned_value_t _ret_zvalue = z_reply_err(reply); + const z_loaned_value_t* _ret_zvalue = z_reply_err(reply); (void)(_ret_zvalue); } - - z_reply_null(); // Does nothing. Just to test compilation } volatile unsigned int datas = 0; void data_handler(const z_loaned_sample_t *sample, void *arg) { datas++; - z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t k_str; + z_keyexpr_to_string(z_sample_keyexpr(sample), &k_str); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, sample->keyexpr); @@ -104,24 +111,27 @@ int main(int argc, char **argv) { zc_init_logger(); #endif - z_loaned_keyexpr_t key = z_keyexpr("demo/example"); - _Bool _ret_bool = z_keyexpr_is_initialized(&key); + z_view_keyexpr_t key_demo_example, key_demo_example_a, key_demo_example_starstar; + z_view_keyexpr_new(&key_demo_example, "demo/example"); + z_view_keyexpr_new(&key_demo_example_a, "demo/example/a"); + z_view_keyexpr_new(&key_demo_example_starstar, "demo/example/**"); + _Bool _ret_bool = z_view_keyexpr_check(&key_demo_example); assert(_ret_bool == true); int8_t _ret_int; - _ret_int = z_keyexpr_includes(z_keyexpr("demo/example/**"), z_keyexpr("demo/example/a")); + _ret_int = z_keyexpr_includes(z_loan(key_demo_example_starstar), z_loan(key_demo_example_a)); assert(_ret_int == 0); #ifdef ZENOH_PICO _ret_bool = zp_keyexpr_includes_null_terminated("demo/example/**", "demo/example/a"); assert(_ret_int == 0); #endif - _ret_int = z_keyexpr_intersects(z_keyexpr("demo/example/**"), z_keyexpr("demo/example/a")); + _ret_int = z_keyexpr_intersects(z_loan(key_demo_example_starstar), z_loan(key_demo_example_a)); assert(_ret_int == 0); #ifdef ZENOH_PICO _ret_bool = zp_keyexpr_intersect_null_terminated("demo/example/**", "demo/example/a"); assert(_ret_int == 0); #endif - _ret_int = z_keyexpr_equals(z_keyexpr("demo/example/**"), z_keyexpr("demo/example")); + _ret_int = z_keyexpr_equals(z_loan(key_demo_example_starstar), z_loan(key_demo_example)); assert(_ret_int == -1); #ifdef ZENOH_PICO _ret_bool = zp_keyexpr_equals_null_terminated("demo/example/**", "demo/example"); @@ -152,11 +162,10 @@ int main(int argc, char **argv) { z_sleep_s(SLEEP); - z_owned_config_t _ret_config = z_config_new(); + z_owned_config_t _ret_config; + z_config_default(&_ret_config); assert(z_check(_ret_config)); z_drop(z_move(_ret_config)); - _ret_config = z_config_default(); - assert(z_check(_ret_config)); #ifdef ZENOH_PICO _ret_int8 = zp_config_insert(z_loan(_ret_config), Z_CONFIG_PEER_KEY, z_string_make(argv[1])); assert(_ret_int8 == 0); @@ -165,7 +174,8 @@ int main(int argc, char **argv) { assert(strncmp(_ret_cstr, argv[1], strlen(_ret_cstr)) == 0); #endif - z_owned_scouting_config_t _ret_sconfig = z_scouting_config_default(); + z_owned_scouting_config_t _ret_sconfig; + z_scouting_config_default(&_ret_sconfig); assert(z_check(_ret_sconfig)); #ifdef ZENOH_PICO _ret_int8 = @@ -178,9 +188,10 @@ int main(int argc, char **argv) { z_drop(z_move(_ret_sconfig)); z_sleep_s(SLEEP); - - _ret_sconfig = z_scouting_config_from(z_loan(_ret_config)); - z_owned_closure_hello_t _ret_closure_hello = z_closure(hello_handler, NULL, NULL); + z_config_default(&_ret_config); + z_scouting_config_from(&_ret_sconfig, z_loan(_ret_config)); + z_owned_closure_hello_t _ret_closure_hello; + z_closure(&_ret_closure_hello, hello_handler, NULL, NULL); _ret_int8 = z_scout(z_move(_ret_sconfig), z_move(_ret_closure_hello)); assert(_ret_int8 == 0); assert(hellos == 1); @@ -188,7 +199,8 @@ int main(int argc, char **argv) { z_sleep_s(atoi(SCOUTING_TIMEOUT) / 1000); z_sleep_s(SLEEP); - z_owned_session_t s1 = z_open(z_move(_ret_config)); + z_owned_session_t s1; + assert(0 == z_open(&s1, z_move(_ret_config))); assert(z_check(s1)); z_id_t _ret_zid = z_info_zid(z_loan(s1)); printf("Session 1 with PID: 0x"); @@ -197,12 +209,14 @@ int main(int argc, char **argv) { } printf("\n"); - z_owned_closure_zid_t _ret_closure_zid = z_closure(zid_handler, NULL, NULL); + z_owned_closure_zid_t _ret_closure_zid; + z_closure(&_ret_closure_zid, zid_handler, NULL, NULL); _ret_int8 = z_info_peers_zid(z_loan(s1), z_move(_ret_closure_zid)); assert(_ret_int8 == 0); z_sleep_s(SLEEP); assert(zids == 0); + z_closure(&_ret_closure_zid, zid_handler, NULL, NULL); _ret_int8 = z_info_routers_zid(z_loan(s1), z_move(_ret_closure_zid)); assert(_ret_int8 == 0); @@ -218,7 +232,7 @@ int main(int argc, char **argv) { z_sleep_s(SLEEP); - _ret_config = z_config_default(); + z_config_default(&_ret_config); #ifdef ZENOH_PICO _ret_int8 = zp_config_insert(z_loan(_ret_config), Z_CONFIG_PEER_KEY, z_string_make(argv[1])); assert(_ret_int8 == 0); @@ -227,7 +241,8 @@ int main(int argc, char **argv) { assert(strncmp(_ret_cstr, argv[1], strlen(_ret_cstr)) == 0); #endif - z_owned_session_t s2 = z_open(z_move(_ret_config)); + z_owned_session_t s2; + assert(0 == z_open(&s2, z_move(_ret_config))); assert(z_check(s2)); _ret_zid = z_info_zid(z_loan(s2)); printf("Session 2 with PID: 0x"); @@ -243,32 +258,44 @@ int main(int argc, char **argv) { z_sleep_s(SLEEP); - z_loaned_session_t ls1 = z_loan(s1); - z_owned_closure_sample_t _ret_closure_sample = z_closure(data_handler, NULL, &ls1); - z_subscriber_options_t _ret_sub_opt = z_subscriber_options_default(); - z_owned_subscriber_t _ret_sub = - z_declare_subscriber(z_loan(s2), z_keyexpr(keyexpr_str), z_move(_ret_closure_sample), &_ret_sub_opt); + const z_loaned_session_t* ls1 = z_loan(s1); + z_owned_closure_sample_t _ret_closure_sample; + z_closure(&_ret_closure_sample, data_handler, NULL, ls1); + z_subscriber_options_t _ret_sub_opt; + z_subscriber_options_default(&_ret_sub_opt); + + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr_str); + z_owned_subscriber_t _ret_sub; + z_declare_subscriber(&_ret_sub, z_loan(s2), z_loan(ke), z_move(_ret_closure_sample), &_ret_sub_opt); assert(z_check(_ret_sub)); z_sleep_s(SLEEP); char s1_res[64]; sprintf(s1_res, "%s/chunk/%d", keyexpr_str, 1); - z_owned_keyexpr_t _ret_expr = z_declare_keyexpr(z_loan(s1), z_keyexpr(s1_res)); + z_view_keyexpr_t s1_key; + z_view_keyexpr_new(&s1_key, s1_res); + z_owned_keyexpr_t _ret_expr; + z_declare_keyexpr(&_ret_expr, z_loan(s1), z_loan(s1_key)); assert(z_check(_ret_expr)); - z_put_options_t _ret_put_opt = z_put_options_default(); + z_put_options_t _ret_put_opt; + z_put_options_default(&_ret_put_opt); _ret_put_opt.congestion_control = Z_CONGESTION_CONTROL_BLOCK; - z_loaned_encoding_t _ret_encoding = z_encoding_default(); - _ret_encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - _ret_put_opt.encoding = _ret_encoding; - z_owned_bytes_t payload = z_bytes_encode_from_string(value); + // TODO: set encoding option + z_view_str_t value_str; + z_view_str_wrap(&value_str, value); + + z_owned_bytes_t payload; + z_bytes_encode_from_string(&payload, z_loan(value_str)); _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), z_move(payload), &_ret_put_opt); assert(_ret_int8 == 0); z_sleep_s(SLEEP); assert(datas == 1); - z_delete_options_t _ret_delete_opt = z_delete_options_default(); + z_delete_options_t _ret_delete_opt; + z_delete_options_default(&_ret_delete_opt); _ret_int8 = z_delete(z_loan(s1), z_loan(_ret_expr), &_ret_delete_opt); assert(_ret_int8 == 0); @@ -282,67 +309,30 @@ int main(int argc, char **argv) { _ret_int8 = z_undeclare_subscriber(z_move(_ret_sub)); assert(_ret_int8 == 0); - z_owned_closure_sample_t _ret_closure_sample2 = z_closure(data_handler, NULL, &ls1); - z_pull_subscriber_options_t _ret_psub_opt = z_pull_subscriber_options_default(); - z_owned_pull_subscriber_t _ret_psub = - z_declare_pull_subscriber(z_loan(s2), z_keyexpr(keyexpr_str), z_move(_ret_closure_sample2), &_ret_psub_opt); - assert(z_check(_ret_psub)); - - z_publisher_options_t _ret_pub_opt = z_publisher_options_default(); - _ret_pub_opt.congestion_control = Z_CONGESTION_CONTROL_BLOCK; - z_owned_publisher_t _ret_pub = z_declare_publisher(z_loan(s1), z_keyexpr(keyexpr_str), &_ret_pub_opt); - assert(z_check(_ret_pub)); - - z_publisher_put_options_t _ret_pput_opt = z_publisher_put_options_default(); - payload = z_bytes_encode_from_string(value); - _ret_int8 = z_publisher_put(z_loan(_ret_pub), z_move(payload), &_ret_pput_opt); - assert(_ret_int8 == 0); - - z_sleep_s(SLEEP); - - _ret_int8 = z_subscriber_pull(z_loan(_ret_psub)); - assert(_ret_int8 == 0); - - z_sleep_s(SLEEP); - assert(datas == 3); - - z_publisher_delete_options_t _ret_pdelete_opt = z_publisher_delete_options_default(); - _ret_int8 = z_publisher_delete(z_loan(_ret_pub), &_ret_pdelete_opt); - - z_sleep_s(SLEEP); - - _ret_int8 = z_subscriber_pull(z_loan(_ret_psub)); - assert(_ret_int8 == 0); - - z_sleep_s(SLEEP); - assert(datas == 4); - - _ret_int8 = z_undeclare_publisher(z_move(_ret_pub)); - assert(!z_check(_ret_pub)); - - _ret_int8 = z_undeclare_pull_subscriber(z_move(_ret_psub)); - assert(_ret_int8 == 0); - - z_sleep_s(SLEEP); + // TODO: test for pull subscriber - z_owned_closure_query_t _ret_closure_query = z_closure(query_handler, NULL, &ls1); - z_queryable_options_t _ret_qle_opt = z_queryable_options_default(); - z_owned_queryable_t qle = - z_declare_queryable(z_loan(s1), z_keyexpr(s1_res), z_move(_ret_closure_query), &_ret_qle_opt); + z_owned_closure_query_t _ret_closure_query; + z_closure(&_ret_closure_query, query_handler, NULL, ls1); + z_queryable_options_t _ret_qle_opt; + z_queryable_options_default(&_ret_qle_opt); + z_owned_queryable_t qle; + z_declare_queryable(&qle, z_loan(s1), z_loan(s1_key), z_move(_ret_closure_query), &_ret_qle_opt); assert(z_check(qle)); z_sleep_s(SLEEP); - z_loaned_session_t ls2 = z_loan(s2); - z_owned_closure_reply_t _ret_closure_reply = z_closure(reply_handler, NULL, &ls2); - z_get_options_t _ret_get_opt = z_get_options_default(); + const z_loaned_session_t* ls2 = z_loan(s2); + z_owned_closure_reply_t _ret_closure_reply; + z_closure(&_ret_closure_reply, reply_handler, NULL, &ls2); + z_get_options_t _ret_get_opt; + z_get_options_default(&_ret_get_opt); _ret_get_opt.target = z_loaned_query_target_default(); _ret_get_opt.consolidation = z_query_consolidation_auto(); _ret_get_opt.consolidation = z_query_consolidation_default(); _ret_get_opt.consolidation = z_query_consolidation_latest(); _ret_get_opt.consolidation = z_query_consolidation_monotonic(); _ret_get_opt.consolidation = z_query_consolidation_none(); - _ret_int8 = z_get(z_loan(s2), z_keyexpr(s1_res), "", z_move(_ret_closure_reply), &_ret_get_opt); + _ret_int8 = z_get(z_loan(s2), z_loan(s1_key), "", z_move(_ret_closure_reply), &_ret_get_opt); assert(_ret_int8 == 0); z_sleep_s(SLEEP); diff --git a/tests/z_api_attachment_test.c b/tests/z_api_attachment_test.c deleted file mode 100644 index ebcdc6993..000000000 --- a/tests/z_api_attachment_test.c +++ /dev/null @@ -1,125 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, - -#include -#include -#include - -#include "z_int_helpers.h" -#include "zenoh.h" - -#undef NDEBUG -#include - -void writting_through_map_by_alias_read_by_get() { - // Writing - z_owned_bytes_map_t map = z_slice_map_new(); - z_slice_map_insert_by_alias(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); - z_slice_map_insert_by_alias(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); - z_loaned_bytes_t attachment = z_slice_map_as_attachment(&map); - - // Elements check - - assert(z_slice_map_len(&map) == 2); - assert(z_attachment_len(attachment) == 2); - assert(!z_attachment_is_empty(attachment)); - - z_loaned_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); - ASSERT_STR_BYTES_EQUAL("v1", a1); - - z_loaned_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); - ASSERT_STR_BYTES_EQUAL("v2", a2); - - z_loaned_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); - assert(a_non.start == NULL); - assert(a_non.len == 0); - - z_drop(z_move(map)); -} - -int8_t _attachment_reader(z_loaned_slice_t key, z_loaned_slice_t value, void* ctx) { - assert((size_t)ctx == 42); - if (!strncmp(key.start, "k1", key.len)) { - assert(!strncmp(value.start, "v1", value.len)); - } - if (!strncmp(key.start, "k2", key.len)) { - assert(!strncmp(value.start, "v2", value.len)); - } - return 24; -} - -void writting_through_map_by_copy_read_by_iter() { - // Writing - z_owned_bytes_map_t map = z_slice_map_new(); - z_slice_map_insert_by_copy(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); - z_slice_map_insert_by_copy(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); - z_loaned_bytes_t attachment = z_slice_map_as_attachment(&map); - - // Elements check - assert(z_slice_map_len(&map) == 2); - assert(z_attachment_len(attachment) == 2); - assert(!z_attachment_is_empty(attachment)); - - int res = z_attachment_iterate(attachment, _attachment_reader, (void*)42); - assert(res == 24); - - z_drop(z_move(map)); -} - -int8_t _iteration_driver(const void* data, z_attachment_iter_body_t body, void* ctx) { - int8_t ret = 0; - ret = body(z_slice_from_str("k1"), z_slice_from_str("v1"), ctx); - if (ret) { - return ret; - } - ret = body(z_slice_from_str("k2"), z_slice_from_str("v2"), ctx); - return ret; -} - -void writting_no_map_read_by_get() { - z_loaned_bytes_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; - - // Elements check - assert(z_attachment_len(attachment) == 2); - assert(!z_attachment_is_empty(attachment)); - - z_loaned_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); - ASSERT_STR_BYTES_EQUAL("v1", a1); - - z_loaned_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); - ASSERT_STR_BYTES_EQUAL("v2", a2); - - z_loaned_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); - assert(a_non.start == NULL); - assert(a_non.len == 0); -} - -void invalid_attachment_safety() { - z_loaned_bytes_t attachment = z_attachment_null(); - assert(z_attachment_is_empty(attachment)); - assert(z_attachment_len(attachment) == 0); - - z_loaned_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); - assert(a_non.start == NULL); - assert(a_non.len == 0); - - int res = z_attachment_iterate(attachment, _attachment_reader, NULL); - assert(res != 0); -} - -int main(int argc, char** argv) { - writting_through_map_by_alias_read_by_get(); - writting_through_map_by_copy_read_by_iter(); - writting_no_map_read_by_get(); - invalid_attachment_safety(); -} diff --git a/tests/z_api_config_test.c b/tests/z_api_config_test.c index 9ffda6390..ad63ce450 100644 --- a/tests/z_api_config_test.c +++ b/tests/z_api_config_test.c @@ -20,16 +20,21 @@ void config_client() { const char *peers[] = {"tcp/127.0.0.1", "tcp/192.168.0.1", "tcp/10.0.0.1"}; - z_owned_config_t config = z_config_client(peers, 3); - z_owned_str_t endpoints = zc_config_get(z_loan(config), "connect/endpoints"); - assert(strcmp(z_loan(endpoints), "[\"tcp/127.0.0.1\",\"tcp/192.168.0.1\",\"tcp/10.0.0.1\"]") == 0); + z_owned_config_t config; + z_config_client(&config, peers, 3); + z_owned_str_t endpoints; + zc_config_get(z_loan(config), "connect/endpoints", &endpoints); + assert(strcmp(z_str_data(z_loan(endpoints)), "[\"tcp/127.0.0.1\",\"tcp/192.168.0.1\",\"tcp/10.0.0.1\"]") == 0); z_drop(z_move(endpoints)); + z_drop(z_move(config)); } void config_peer() { - z_owned_config_t config = z_config_peer(); - z_owned_str_t mode = zc_config_get(z_loan(config), "mode"); - assert(strcmp(z_loan(mode), "\"peer\"") == 0); + z_owned_config_t config; + z_config_peer(&config); + z_owned_str_t mode; + zc_config_get(z_loan(config), "mode", &mode); + assert(strcmp(z_str_data(z_loan(mode)), "\"peer\"") == 0); z_drop(z_move(mode)); } diff --git a/tests/z_api_double_drop_test.c b/tests/z_api_double_drop_test.c index 48b5927f6..279dc66b8 100644 --- a/tests/z_api_double_drop_test.c +++ b/tests/z_api_double_drop_test.c @@ -23,29 +23,40 @@ #define URL "demo/example" void test_session() { - z_owned_config_t config = z_config_default(); - z_owned_session_t session = z_open(z_move(config)); + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t session; + z_open(&session, z_move(config)); assert(z_check(session)); - z_drop(z_move(session)); + z_close(z_move(session)); assert(!z_check(session)); - z_drop(z_move(session)); + z_close(z_move(session)); assert(!z_check(session)); } void test_publisher() { - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(URL), NULL); + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + z_open(&s, z_move(config)); + + z_owned_keyexpr_t keyexpr; + z_keyexpr_new(&keyexpr, URL); + + z_owned_publisher_t pub; + z_declare_publisher(&pub, z_loan(s), z_loan(keyexpr), NULL); assert(z_check(pub)); - z_drop(z_move(pub)); + z_undeclare_publisher(z_move(pub)); assert(!z_check(pub)); - z_drop(z_move(pub)); + z_undeclare_publisher(z_move(pub)); assert(!z_check(pub)); - z_drop(z_move(s)); + z_close(z_move(s)); } void test_keyexpr() { - z_owned_keyexpr_t keyexpr = z_keyexpr_new(URL); + z_owned_keyexpr_t keyexpr; + z_keyexpr_new(&keyexpr, URL); + assert(z_check(keyexpr)); z_drop(z_move(keyexpr)); assert(!z_check(keyexpr)); @@ -54,7 +65,8 @@ void test_keyexpr() { } void test_config() { - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); assert(z_check(config)); z_drop(z_move(config)); assert(!z_check(config)); @@ -63,7 +75,8 @@ void test_config() { } void test_scouting_config() { - z_owned_scouting_config_t config = z_scouting_config_default(); + z_owned_scouting_config_t config; + z_scouting_config_default(&config); assert(z_check(config)); z_drop(z_move(config)); assert(!z_check(config)); @@ -73,45 +86,46 @@ void test_scouting_config() { void data_handler(const z_loaned_sample_t *sample, void *arg) {} -void test_pull_subscriber() { - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - z_owned_closure_sample_t callback = z_closure(data_handler); - z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(URL), z_move(callback), NULL); - assert(z_check(sub)); - z_drop(z_move(sub)); - assert(!z_check(sub)); - z_drop(z_move(sub)); - assert(!z_check(sub)); - z_drop(z_move(s)); -} - void test_subscriber() { - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - z_owned_closure_sample_t callback = z_closure(data_handler); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(URL), z_move(callback), NULL); + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + z_open(&s, z_move(config)); + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); + + z_view_keyexpr_t keyexpr; + z_view_keyexpr_new(&keyexpr, URL); + z_owned_subscriber_t sub; + z_declare_subscriber(&sub, z_loan(s), z_loan(keyexpr), z_move(callback), NULL); assert(z_check(sub)); - z_drop(z_move(sub)); + z_undeclare_subscriber(z_move(sub)); assert(!z_check(sub)); - z_drop(z_move(sub)); + z_undeclare_subscriber(z_move(sub)); assert(!z_check(sub)); - z_drop(z_move(s)); + z_close(z_move(s)); } void query_handler(const z_loaned_query_t *query, void *context) {} void test_queryable() { - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - z_owned_closure_query_t callback = z_closure(query_handler); - z_owned_queryable_t queryable = z_declare_queryable(z_loan(s), z_keyexpr(URL), z_move(callback), NULL); + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + z_open(&s, z_move(config)); + z_owned_closure_query_t callback; + z_closure(&callback, query_handler, NULL, NULL); + + z_view_keyexpr_t keyexpr; + z_view_keyexpr_new(&keyexpr, URL); + z_owned_queryable_t queryable; + z_declare_queryable(&queryable, z_loan(s), z_loan(keyexpr), z_move(callback), NULL); assert(z_check(queryable)); - z_drop(z_move(queryable)); + z_undeclare_queryable(z_move(queryable)); assert(!z_check(queryable)); - z_drop(z_move(queryable)); + z_undeclare_queryable(z_move(queryable)); assert(!z_check(queryable)); - z_drop(z_move(s)); + z_close(z_move(s)); } int main(int argc, char **argv) { @@ -120,7 +134,6 @@ int main(int argc, char **argv) { test_keyexpr(); test_config(); test_scouting_config(); - test_pull_subscriber(); test_subscriber(); test_queryable(); diff --git a/tests/z_api_keyexpr_drop_test.c b/tests/z_api_keyexpr_drop_test.c index f451fa974..3cab653ae 100644 --- a/tests/z_api_keyexpr_drop_test.c +++ b/tests/z_api_keyexpr_drop_test.c @@ -21,65 +21,54 @@ #include void test_publisher() { - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + z_open(&s, z_move(config)); assert(z_check(s)); char keyexpr[256]; strncpy(keyexpr, "foo/bar", 256); - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); - strncpy(keyexpr, "baz/quax", 256); // Update source string to ensure that the correct keyexpr - z_owned_keyexpr_t pub_keyexpr = z_publisher_keyexpr(z_loan(pub)); - z_owned_str_t pub_keyexpr_str = z_keyexpr_to_string(z_loan(pub_keyexpr)); - assert(strcmp(z_loan(pub_keyexpr_str), "foo/bar") == 0); // Check that publisher keeps the correct keyexpr - z_drop(z_move(pub_keyexpr_str)); - z_drop(z_move(pub)); - z_drop(z_move(s)); + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + z_owned_publisher_t pub; + z_declare_publisher(&pub, z_loan(s), z_loan(ke), NULL); + strncpy(keyexpr, "baz/quax", 256); // Update source string to ensure that the keyexpr is copied into publisher + z_view_keyexpr_new(&ke, keyexpr); + const z_loaned_keyexpr_t* pub_ke = z_publisher_keyexpr(z_loan(pub)); + z_owned_str_t pub_keyexpr; + z_keyexpr_to_string(pub_ke, &pub_keyexpr); + assert(strcmp(z_str_data(z_loan(pub_keyexpr)), "foo/bar") == 0); // Check that publisher keeps the correct keyexpr + z_drop(z_move(pub_keyexpr)); + z_undeclare_publisher(z_move(pub)); + z_close(z_move(s)); } void data_handler(const z_loaned_sample_t *sample, void *arg) {} -// void test_pull_subscriber() { -// z_owned_config_t config = z_config_default(); -// z_owned_session_t s = z_open(z_move(config)); -// z_owned_closure_sample_t callback = z_closure(data_handler); -// char keyexpr[256]; -// strncpy(keyexpr, "foo/bar", 256); -// z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); -// strncpy(keyexpr, "baz/quax", 256); -// z_drop(z_move(sub)); -// z_drop(z_move(s)); -// } - void test_subscriber() { - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - z_owned_closure_sample_t callback = z_closure(data_handler); + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + z_open(&s, z_move(config)); + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); char keyexpr[256]; strncpy(keyexpr, "foo/bar", 256); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + z_owned_subscriber_t sub; + z_declare_subscriber(&sub, z_loan(s), z_loan(ke), z_move(callback), NULL); strncpy(keyexpr, "baz/quax", 256); // Update source string to ensure that the keyexpr is copied into the subscriber - z_owned_keyexpr_t sub_keyexpr = z_subscriber_keyexpr(z_loan(sub)); - z_owned_str_t sub_keyexpr_str = z_keyexpr_to_string(z_loan(sub_keyexpr)); - assert(strcmp(z_loan(sub_keyexpr_str), "foo/bar") == 0); // Check that subscriber keeps the correct keyexpr - z_drop(z_move(sub_keyexpr_str)); - z_drop(z_move(sub)); - z_drop(z_move(s)); + z_view_keyexpr_new(&ke, keyexpr); + const z_loaned_keyexpr_t* sub_ke = z_subscriber_keyexpr(z_loan(sub)); + z_owned_str_t sub_keyexpr; + z_keyexpr_to_string(sub_ke, &sub_keyexpr); + assert(strcmp(z_str_data(z_loan(sub_keyexpr)), "foo/bar") == 0); // Check that subscriber keeps the correct keyexpr + z_drop(z_move(sub_keyexpr)); + z_undeclare_subscriber(z_move(sub)); + z_close(z_move(s)); } -// void query_handler(const z_loaned_query_t *query, void *context) {} - -// void test_queryable() { -// z_owned_config_t config = z_config_default(); -// z_owned_session_t s = z_open(z_move(config)); -// z_owned_closure_query_t callback = z_closure(query_handler); -// char keyexpr[256]; -// strncpy(keyexpr, "foo/bar", 256); -// z_owned_queryable_t queryable = z_declare_queryable(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); -// strncpy(keyexpr, "baz/quax", 256); -// z_drop(z_move(queryable)); -// z_drop(z_move(s)); -// } - int main(int argc, char **argv) { test_publisher(); test_subscriber(); diff --git a/tests/z_api_keyexpr_test.c b/tests/z_api_keyexpr_test.c index e62e27d09..02a6a886e 100644 --- a/tests/z_api_keyexpr_test.c +++ b/tests/z_api_keyexpr_test.c @@ -43,63 +43,70 @@ void canonize() { assert(strcmp(keyexpr, "a/**/c") == 0); strcpy(keyexpr, "a/**/**/c"); - z_loaned_keyexpr_t key_expr_canonized = z_keyexpr_autocanonize(keyexpr); - assert(z_keyexpr_check(keyexpr) == true); + z_view_keyexpr_t key_expr_canonized; + z_view_keyexpr_new_autocanonize(&key_expr_canonized, keyexpr); + assert(z_view_keyexpr_check(&key_expr_canonized) == 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); + z_view_slice_t key_exp_canonized_bytes; + z_keyexpr_as_slice(z_loan(key_expr_canonized), &key_exp_canonized_bytes); + assert(z_slice_len(z_loan(key_exp_canonized_bytes)) == len_new); + assert(strncmp((const char*)z_slice_data(z_loan(key_exp_canonized_bytes)), "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); + int8_t res = z_view_keyexpr_from_slice_autocanonize(&key_expr_canonized, keyexpr, &len_new); + assert(res == 0); 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); + z_keyexpr_as_slice(z_loan(key_expr_canonized), &key_exp_canonized_bytes); + assert(z_slice_len(z_loan(key_exp_canonized_bytes)) == len_new); + assert(strncmp((const char*)z_slice_data(z_loan(key_exp_canonized_bytes)), "a/**/c", len_new) == 0); } void includes() { - z_loaned_keyexpr_t nul = z_keyexpr(NULL); - z_loaned_keyexpr_t foobar = z_keyexpr("foo/bar"); - z_loaned_keyexpr_t foostar = z_keyexpr("foo/*"); - assert(z_keyexpr_includes(foostar, foobar) == 0); - assert(z_keyexpr_includes(foobar, foostar) == -1); - assert(z_keyexpr_includes(nul, foobar) < -1); - assert(z_keyexpr_includes(foobar, nul) < -1); + z_view_keyexpr_t foobar, foostar; + z_view_keyexpr_new(&foobar, "foo/bar"); + z_view_keyexpr_new(&foostar, "foo/*"); + + assert(z_keyexpr_includes(z_loan(foostar), z_loan(foobar)) == false); + assert(z_keyexpr_includes(z_loan(foobar), z_loan(foostar)) == true); } void intersects() { - z_loaned_keyexpr_t nul = z_keyexpr(NULL); - z_loaned_keyexpr_t foobar = z_keyexpr("foo/bar"); - z_loaned_keyexpr_t foostar = z_keyexpr("foo/*"); - z_loaned_keyexpr_t barstar = z_keyexpr("bar/*"); - assert(z_keyexpr_intersects(foostar, foobar) == 0); - assert(z_keyexpr_intersects(barstar, foobar) == -1); - assert(z_keyexpr_intersects(nul, foobar) < -1); - assert(z_keyexpr_intersects(foobar, nul) < -1); + z_view_keyexpr_t foobar, foostar, barstar; + z_view_keyexpr_new(&foobar, "foo/bar"); + z_view_keyexpr_new(&foostar, "foo/*"); + z_view_keyexpr_new(&barstar, "bar/*"); + + assert(z_keyexpr_intersects(z_loan(foostar), z_loan(foobar)) == true); + assert(z_keyexpr_intersects(z_loan(barstar), z_loan(foobar)) == false); } void undeclare() { - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - z_owned_keyexpr_t ke = z_declare_keyexpr(z_loan(s), z_keyexpr("test/thr")); + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + z_open(&s, z_move(config)); + + z_view_keyexpr_t view_ke; + z_view_keyexpr_new(&view_ke, "test/thr"); + z_owned_keyexpr_t ke; + z_declare_keyexpr(&ke, z_loan(s), z_loan(view_ke)); assert(z_keyexpr_check(&ke)); z_undeclare_keyexpr(z_loan(s), &ke); assert(!z_keyexpr_check(&ke)); } void relation_to() { - z_loaned_keyexpr_t nul = z_keyexpr(NULL); - z_loaned_keyexpr_t foobar = z_keyexpr("foo/bar"); - z_loaned_keyexpr_t foostar = z_keyexpr("foo/*"); - z_loaned_keyexpr_t barstar = z_keyexpr("bar/*"); - assert(z_keyexpr_relation_to(foostar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES); - assert(z_keyexpr_relation_to(foobar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS); - assert(z_keyexpr_relation_to(foostar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS); - assert(z_keyexpr_relation_to(barstar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); - assert(z_keyexpr_relation_to(nul, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); - assert(z_keyexpr_relation_to(foobar, nul) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); + z_view_keyexpr_t foobar, foostar, barstar; + z_view_keyexpr_new(&foobar, "foo/bar"); + z_view_keyexpr_new(&foostar, "foo/*"); + z_view_keyexpr_new(&barstar, "bar/*"); + + assert(z_keyexpr_relation_to(z_loan(foostar), z_loan(foobar)) == Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES); + assert(z_keyexpr_relation_to(z_loan(foobar), z_loan(foostar)) == Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS); + assert(z_keyexpr_relation_to(z_loan(foostar), z_loan(foostar)) == Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS); + assert(z_keyexpr_relation_to(z_loan(barstar), z_loan(foobar)) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); } int main(int argc, char **argv) { diff --git a/tests/z_api_map_test.c b/tests/z_api_map_test.c new file mode 100644 index 000000000..c6e2f1545 --- /dev/null +++ b/tests/z_api_map_test.c @@ -0,0 +1,109 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#include +#include +#include + +#include "z_int_helpers.h" +#include "zenoh.h" + +#undef NDEBUG +#include + +void writting_by_alias_read_by_get() { + // Writing + z_owned_slice_map_t map; + z_slice_map_new(&map); + z_view_slice_t k1, k2, v1, v2, k0; + z_view_slice_from_str(&k0, "k0"); + z_view_slice_from_str(&k1, "k1"); + z_view_slice_from_str(&k2, "k2"); + z_view_slice_from_str(&v1, "v1"); + z_view_slice_from_str(&v2, "v2"); + z_slice_map_insert_by_alias(z_loan_mut(map), z_loan(k1), z_loan(v1)); + z_slice_map_insert_by_alias(z_loan_mut(map), z_loan(k2), z_loan(v2)); + z_owned_bytes_t attachment; + z_bytes_encode_from_slice_map(&attachment, z_loan(map)); + + // Elements check + + assert(z_slice_map_len(z_loan(map)) == 2); + assert(!z_slice_map_is_empty(z_loan(map))); + + const z_loaned_slice_t* a1 = z_slice_map_get(z_loan(map), z_loan(k1)); + ASSERT_STR_SLICE_EQUAL("v1", a1); + + const z_loaned_slice_t* a2 = z_slice_map_get(z_loan(map), z_loan(k1)); + ASSERT_STR_SLICE_EQUAL("v2", a2); + + const z_loaned_slice_t* a_null = z_slice_map_get(z_loan(map), z_loan(k0)); + assert(a_null == NULL); + + z_drop(z_move(map)); +} + +bool map_reader(const z_loaned_slice_t* key, const z_loaned_slice_t* value, void* ctx) { + assert((size_t)ctx == 42); + if (!strncmp((const char*)z_slice_data(key), "k1", z_slice_len(key))) { + assert(!strncmp((const char*)z_slice_data(value), "v1", z_slice_len(value))); + } else if (!strncmp((const char*)z_slice_data(key), "k2", z_slice_len(key))) { + assert(!strncmp((const char*)z_slice_data(value), "v2", z_slice_len(value))); + } else { + assert(false); + } + return true; +} + +void writting_by_copy_read_by_iter() { + // Writing + z_owned_slice_map_t map; + z_slice_map_new(&map); + + z_view_slice_t k1, k2, v1, v2, k0; + z_view_slice_from_str(&k0, "k0"); + z_view_slice_from_str(&k1, "k1"); + z_view_slice_from_str(&k2, "k2"); + z_view_slice_from_str(&v1, "v1"); + z_view_slice_from_str(&v2, "v2"); + z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k1), z_loan(v1)); + z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k2), z_loan(v2)); + + // Elements check + assert(z_slice_map_len(z_loan(map)) == 2); + + z_slice_map_iterate(z_loan(map), map_reader, (void*)42); + + z_drop(z_move(map)); +} + +void empty_map_safety() { + z_owned_slice_map_t map; + z_slice_map_new(&map); + assert(z_slice_map_is_empty(z_loan(map))); + assert(z_slice_map_len(z_loan(map)) == 0); + + z_view_slice_t k0; + z_view_slice_from_str(&k0, "k0"); + + const z_loaned_slice_t* a_null = z_slice_map_get(z_loan(map), z_loan(k0)); + assert(a_null == NULL); + + z_slice_map_iterate(z_loan(map), map_reader, NULL); +} + +int main(int argc, char** argv) { + writting_by_alias_read_by_get(); + writting_by_copy_read_by_iter(); + empty_map_safety(); +} diff --git a/tests/z_api_null_drop_test.c b/tests/z_api_null_drop_test.c index b82f27aef..47a65e3f8 100644 --- a/tests/z_api_null_drop_test.c +++ b/tests/z_api_null_drop_test.c @@ -24,28 +24,50 @@ int main(int argc, char **argv) { // // Check that all null functions exists // - z_owned_session_t session_null_1 = z_session_null(); - z_owned_publisher_t publisher_null_1 = z_publisher_null(); - z_owned_keyexpr_t keyexpr_null_1 = z_keyexpr_null(); - z_owned_config_t config_null_1 = z_config_null(); - z_owned_scouting_config_t scouting_config_null_1 = z_scouting_config_null(); - z_owned_pull_subscriber_t pull_subscriber_null_1 = z_pull_subscriber_null(); - z_owned_subscriber_t subscriber_null_1 = z_subscriber_null(); - z_owned_queryable_t queryable_null_1 = z_queryable_null(); - z_owned_encoding_t encoding_null_1 = z_encoding_null(); - z_owned_reply_t reply_null_1 = z_reply_null(); - z_owned_hello_t hello_null_1 = z_hello_null(); - z_owned_closure_sample_t closure_sample_null_1 = z_closure_sample_null(); - z_owned_closure_query_t closure_query_null_1 = z_closure_query_null(); - z_owned_closure_reply_t closure_reply_null_1 = z_closure_reply_null(); - z_owned_closure_hello_t closure_hello_null_1 = z_closure_hello_null(); - z_owned_closure_zid_t closure_zid_null_1 = z_closure_zid_null(); - z_owned_reply_channel_closure_t reply_channel_closure_null_1 = z_reply_channel_closure_null(); - z_owned_reply_channel_t reply_channel_null_1 = z_reply_channel_null(); - z_owned_str_t str_null_1 = z_str_null(); - z_owned_bytes_t payload_null_1 = z_bytes_null(); - zc_owned_shmbuf_t shmbuf_null_1 = zc_shmbuf_null(); - zc_owned_shm_manager_t shm_manager_null_1 = zc_shm_manager_null(); + z_owned_session_t session_null_1; + z_session_null(&session_null_1); + z_owned_publisher_t publisher_null_1; + z_publisher_null(&publisher_null_1); + z_owned_keyexpr_t keyexpr_null_1; + z_keyexpr_null(&keyexpr_null_1); + z_owned_config_t config_null_1; + z_config_null(&config_null_1); + z_owned_scouting_config_t scouting_config_null_1; + z_scouting_config_null(&scouting_config_null_1); + z_owned_subscriber_t subscriber_null_1; + z_subscriber_null(&subscriber_null_1); + z_owned_queryable_t queryable_null_1; + z_queryable_null(&queryable_null_1); + z_owned_encoding_t encoding_null_1; + z_encoding_null(&encoding_null_1); + z_owned_reply_t reply_null_1; + z_reply_null(&reply_null_1); + z_owned_hello_t hello_null_1; + z_hello_null(&hello_null_1); + z_owned_closure_sample_t closure_sample_null_1; + z_closure_sample_null(&closure_sample_null_1); + z_owned_closure_query_t closure_query_null_1; + z_closure_query_null(&closure_query_null_1); + z_owned_closure_reply_t closure_reply_null_1; + z_closure_reply_null(&closure_reply_null_1); + z_owned_closure_hello_t closure_hello_null_1; + z_closure_hello_null(&closure_hello_null_1); + z_owned_closure_zid_t closure_zid_null_1; + z_closure_zid_null(&closure_zid_null_1); + z_owned_reply_channel_closure_t reply_channel_closure_null_1; + z_reply_channel_closure_null(&reply_channel_closure_null_1); + z_owned_reply_channel_t reply_channel_null_1; + z_reply_channel_null(&reply_channel_null_1); + z_owned_str_t str_null_1; + z_str_null(&str_null_1); + z_owned_slice_t slice_null_1; + z_slice_null(&slice_null_1); + z_owned_slice_map_t slice_map_null_1; + z_slice_map_null(&slice_map_null_1); + z_owned_bytes_t bytes_null_1; + z_bytes_null(&bytes_null_1); + z_owned_bytes_reader_t bytes_reader_null_1; + z_bytes_reader_null(&bytes_reader_null_1); // // Test that they actually make invalid value (where applicable) @@ -55,16 +77,17 @@ int main(int argc, char **argv) { assert(!z_check(keyexpr_null_1)); assert(!z_check(config_null_1)); assert(!z_check(scouting_config_null_1)); - assert(!z_check(pull_subscriber_null_1)); assert(!z_check(subscriber_null_1)); assert(!z_check(queryable_null_1)); assert(!z_check(encoding_null_1)); assert(!z_check(reply_null_1)); assert(!z_check(hello_null_1)); assert(!z_check(str_null_1)); - assert(!z_check(payload_null_1)); - assert(!z_check(shmbuf_null_1)); - assert(!z_check(shm_manager_null_1)); + assert(!z_check(slice_null_1)); + assert(!z_check(slice_map_null_1)); + assert(!z_check(bytes_null_1)); + assert(!z_check(bytes_reader_null_1)); + // // Test that z_null macro defined for all types @@ -74,7 +97,6 @@ int main(int argc, char **argv) { z_owned_keyexpr_t keyexpr_null_2; z_owned_config_t config_null_2; z_owned_scouting_config_t scouting_config_null_2; - z_owned_pull_subscriber_t pull_subscriber_null_2; z_owned_subscriber_t subscriber_null_2; z_owned_queryable_t queryable_null_2; z_owned_encoding_t encoding_null_2; @@ -88,16 +110,16 @@ int main(int argc, char **argv) { z_owned_reply_channel_closure_t reply_channel_closure_null_2; z_owned_reply_channel_t reply_channel_null_2; z_owned_str_t str_null_2; - z_owned_bytes_t payload_null_2; - zc_owned_shmbuf_t shmbuf_null_2; - zc_owned_shm_manager_t shm_manager_null_2; + z_owned_slice_t slice_null_2; + z_owned_slice_map_t slice_map_null_2; + z_owned_bytes_t bytes_null_2; + z_owned_bytes_reader_t bytes_reader_null_2; z_null(&session_null_2); z_null(&publisher_null_2); z_null(&keyexpr_null_2); z_null(&config_null_2); z_null(&scouting_config_null_2); - z_null(&pull_subscriber_null_2); z_null(&subscriber_null_2); z_null(&queryable_null_2); z_null(&encoding_null_2); @@ -111,9 +133,10 @@ int main(int argc, char **argv) { z_null(&reply_channel_closure_null_2); z_null(&reply_channel_null_2); z_null(&str_null_2); - z_null(&payload_null_2); - z_null(&shmbuf_null_2); - z_null(&shm_manager_null_2); + z_null(&slice_null_2); + z_null(&slice_map_null_2); + z_null(&bytes_null_2); + z_null(&bytes_reader_null_2); // // Test that null macro works the same as direct call @@ -123,29 +146,28 @@ int main(int argc, char **argv) { assert(!z_check(keyexpr_null_2)); assert(!z_check(config_null_2)); assert(!z_check(scouting_config_null_2)); - assert(!z_check(pull_subscriber_null_2)); assert(!z_check(subscriber_null_2)); assert(!z_check(queryable_null_2)); assert(!z_check(encoding_null_2)); assert(!z_check(reply_null_2)); assert(!z_check(hello_null_2)); assert(!z_check(str_null_2)); - assert(!z_check(payload_null_2)); - assert(!z_check(shmbuf_null_2)); - assert(!z_check(shm_manager_null_2)); + assert(!z_check(slice_null_2)); + assert(!z_check(slice_map_null_2)); + assert(!z_check(bytes_null_2)); + assert(!z_check(bytes_reader_null_2)); // // Test drop null and double drop it // for (int i = 0; i < 2; ++i) { - z_drop(z_move(session_null_1)); - z_drop(z_move(publisher_null_1)); + z_close(z_move(session_null_1)); + z_undeclare_publisher(z_move(publisher_null_1)); z_drop(z_move(keyexpr_null_1)); z_drop(z_move(config_null_1)); z_drop(z_move(scouting_config_null_1)); - z_drop(z_move(pull_subscriber_null_1)); - z_drop(z_move(subscriber_null_1)); - z_drop(z_move(queryable_null_1)); + z_undeclare_subscriber(z_move(subscriber_null_1)); + z_undeclare_queryable(z_move(queryable_null_1)); z_drop(z_move(encoding_null_1)); z_drop(z_move(reply_null_1)); z_drop(z_move(hello_null_1)); @@ -157,18 +179,19 @@ int main(int argc, char **argv) { z_drop(z_move(reply_channel_closure_null_1)); z_drop(z_move(reply_channel_null_1)); z_drop(z_move(str_null_1)); - z_drop(z_move(payload_null_1)); - z_drop(z_move(shmbuf_null_1)); - z_drop(z_move(shm_manager_null_1)); + z_drop(z_move(slice_null_1)); + z_drop(z_move(slice_map_null_1)); + z_drop(z_move(bytes_null_1)); + z_drop(z_move(bytes_reader_null_1)); + - z_drop(z_move(session_null_2)); - z_drop(z_move(publisher_null_2)); + z_close(z_move(session_null_2)); + z_undeclare_publisher(z_move(publisher_null_2)); z_drop(z_move(keyexpr_null_2)); z_drop(z_move(config_null_2)); z_drop(z_move(scouting_config_null_2)); - z_drop(z_move(pull_subscriber_null_2)); - z_drop(z_move(subscriber_null_2)); - z_drop(z_move(queryable_null_2)); + z_undeclare_subscriber(z_move(subscriber_null_2)); + z_undeclare_queryable(z_move(queryable_null_2)); z_drop(z_move(encoding_null_2)); z_drop(z_move(reply_null_2)); z_drop(z_move(hello_null_2)); @@ -180,9 +203,10 @@ int main(int argc, char **argv) { z_drop(z_move(reply_channel_closure_null_2)); z_drop(z_move(reply_channel_null_2)); z_drop(z_move(str_null_2)); - z_drop(z_move(payload_null_2)); - z_drop(z_move(shmbuf_null_2)); - z_drop(z_move(shm_manager_null_2)); + z_drop(z_move(slice_null_2)); + z_drop(z_move(slice_map_null_2)); + z_drop(z_move(bytes_null_2)); + z_drop(z_move(bytes_reader_null_2)); } return 0; diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c index 3e2fed1b2..5734dbc69 100644 --- a/tests/z_api_payload_test.c +++ b/tests/z_api_payload_test.c @@ -24,17 +24,27 @@ void test_reader() { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; uint8_t data_out[10] = {0}; - z_loaned_slice_t bytes = {.start = data, .len = 10 }; + z_view_slice_t slice; + z_view_slice_wrap(&slice, data, 10); - z_owned_bytes_t payload = z_bytes_encode_from_bytes(bytes); - z_bytes_reader reader; - z_bytes_reader_init(z_loan(payload), &reader); - assert(z_bytes_reader_remaining(&reader) == 10); + z_owned_bytes_t payload; + z_bytes_encode_from_slice(&payload, z_loan(slice)); + z_owned_bytes_reader_t reader; + z_bytes_reader_new(&reader, z_loan(payload)); + assert(z_bytes_reader_tell(z_loan_mut(reader)) == 0); - z_bytes_reader_read(&reader, data_out, 5); - assert(z_bytes_reader_remaining(&reader) == 5); - z_bytes_reader_read(&reader, data_out, 5); - assert(z_bytes_reader_remaining(&reader) == 0); + z_bytes_reader_read(z_loan_mut(reader), data_out, 5); + assert(z_bytes_reader_tell(z_loan_mut(reader)) == 5); + z_bytes_reader_seek(z_loan_mut(reader), 2, SEEK_CUR); + assert(z_bytes_reader_tell(z_loan_mut(reader)) == 7); + z_bytes_reader_read(z_loan_mut(reader), data_out + 7, 2); + z_bytes_reader_seek(z_loan_mut(reader), 5, SEEK_SET); + assert(z_bytes_reader_tell(z_loan_mut(reader)) == 7); + z_bytes_reader_read(z_loan_mut(reader), data_out + 5, 2); + + z_bytes_reader_seek(z_loan_mut(reader), -1, SEEK_END); + assert(z_bytes_reader_tell(z_loan_mut(reader)) == 9); + z_bytes_reader_read(z_loan_mut(reader), data_out + 9, 1); assert(memcmp(data, data_out, 10)); } diff --git a/tests/z_api_unitinialized_check.c b/tests/z_api_unitinialized_check.c index 3b6f95da0..114bd5e1f 100644 --- a/tests/z_api_unitinialized_check.c +++ b/tests/z_api_unitinialized_check.c @@ -22,9 +22,11 @@ #include int main(int argc, char **argv) { - z_owned_keyexpr_t owned_keyexpr = z_keyexpr_new(NULL); + z_owned_keyexpr_t owned_keyexpr; + z_keyexpr_new(&owned_keyexpr, NULL); assert(!z_check(owned_keyexpr)); - z_loaned_keyexpr_t keyexpr = z_keyexpr(NULL); + z_view_keyexpr_t keyexpr; + z_view_keyexpr_new(&keyexpr, NULL); assert(!z_check(keyexpr)); } diff --git a/tests/z_int_helpers.h b/tests/z_int_helpers.h index fbbb2a2d2..0a620771a 100644 --- a/tests/z_int_helpers.h +++ b/tests/z_int_helpers.h @@ -155,10 +155,10 @@ int run_timeouted_test(func_ptr_t functions[], int num_functions, int timeout_se #endif // def windows -#define ASSERT_STR_BYTES_EQUAL(str, bytes) \ +#define ASSERT_STR_SLICE_EQUAL(str, slice) \ do { \ - if (strlen(str) != bytes.len || strncmp(str, (const char *)bytes.start, (int)bytes.len)) { \ - fprintf(stderr, "Check failed: '%s' != '%.*s'\n", str, (int)bytes.len, bytes.start); \ + if (strlen(str) != z_slice_len(slice) || strncmp(str, (const char *)z_slice_data(slice), (int)z_slice_len(slice))) { \ + fprintf(stderr, "Check failed: '%s' != '%.*s'\n", str, (int)z_slice_len(slice), z_slice_data(slice)); \ exit(-1); \ } \ } while (0) diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index aba2262c9..f938b95d9 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -31,38 +31,45 @@ const char *const values[] = {"test_value_1", "test_value_2", "test_value_3", const size_t values_count = sizeof(values) / sizeof(values[0]); int run_publisher() { - z_owned_config_t config = z_config_default(); - if (zc_config_insert_json(z_loan(config), Z_CONFIG_ADD_TIMESTAMP_KEY, "true") < 0) { + z_owned_config_t config; + z_config_default(&config); + if (zc_config_insert_json(z_loan_mut(config), Z_CONFIG_ADD_TIMESTAMP_KEY, "true") < 0) { perror("Unable to configure timestamps!"); return -1; } - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) , 0) { perror("Unable to open session!"); return -1; } - ze_publication_cache_options_t pub_cache_opts = ze_publication_cache_options_default(); + ze_publication_cache_options_t pub_cache_opts; + ze_publication_cache_options_default(&pub_cache_opts); pub_cache_opts.history = 42; - ze_owned_publication_cache_t pub_cache = - ze_declare_publication_cache(z_loan(s), z_keyexpr(keyexpr), &pub_cache_opts); - if (!z_check(pub_cache)) { + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + ze_owned_publication_cache_t pub_cache; + ; + if (ze_declare_publication_cache(&pub_cache, z_loan(s), z_loan(ke), &pub_cache_opts) < 0) { perror("Unable to declare publication cache for key expression!\n"); return -1; } - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); - if (!z_check(pub)) { + z_owned_publisher_t pub; + if (z_declare_publisher(&pub, z_loan(s), z_loan(ke), NULL) < 0) { perror("Unable to declare Publisher for key expression!"); return -1; } // values for cache for (int i = 0; i < values_count / 2; ++i) { - z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); - z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); + z_owned_bytes_t payload; + z_view_str_t value_str; + z_view_str_wrap(&value_str, values[i]); + z_bytes_encode_from_string(&payload, z_loan(value_str)); + z_put(z_loan(s), z_loan(ke), z_move(payload), NULL); } SEM_POST(sem_pub); @@ -71,15 +78,18 @@ int run_publisher() { // values for subscribe for (int i = values_count / 2; i < values_count; ++i) { - z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); - z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); + z_owned_bytes_t payload; + z_view_str_t value_str; + z_view_str_wrap(&value_str, values[i]); + z_bytes_encode_from_string(&payload, z_loan(value_str)); + z_put(z_loan(s), z_loan(ke), z_move(payload), NULL); } printf("wait: sem_sub\n"); SEM_WAIT(sem_sub); - z_drop(z_move(pub_cache)); - z_drop(z_move(pub)); + ze_undeclare_publication_cache(z_move(pub_cache)); + z_undeclare_publisher(z_move(pub)); z_close(z_move(s)); return 0; @@ -87,20 +97,21 @@ int run_publisher() { void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - if (strcmp(keyexpr, z_loan(keystr))) { + z_owned_str_t keystr; + z_keyexpr_to_string(z_sample_keyexpr(sample), &keystr); + if (strcmp(keyexpr, z_str_data(z_loan(keystr)))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); - if (strcmp(values[val_num], z_loan(payload_value))) { + z_owned_str_t payload_str; + z_bytes_decode_into_string(z_sample_payload(sample), &payload_str); + if (strcmp(values[val_num], z_str_data(z_loan(payload_str)))) { perror("Unexpected value received"); - z_drop(z_move(payload_value)); + z_drop(z_move(payload_str)); exit(-1); } - z_drop(z_move(payload_value)); + z_drop(z_move(payload_str)); printf("data_handler: %i\n", val_num); if (++val_num == values_count) { @@ -113,17 +124,22 @@ int run_subscriber() { printf("wait: sem_pub\n"); SEM_WAIT(sem_pub); - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { perror("Unable to open session!"); return -1; } - z_owned_closure_sample_t callback = z_closure(data_handler); - ze_owned_querying_subscriber_t sub = - ze_declare_querying_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); + ze_owned_querying_subscriber_t sub ; + ze_declare_querying_subscriber(&sub, z_loan(s), z_loan(ke), z_move(callback), NULL); if (!z_check(sub)) { perror("Unable to declare subscriber!"); return -1; @@ -132,7 +148,7 @@ int run_subscriber() { SEM_POST(sem_sub); z_sleep_s(10); - z_drop(z_move(sub)); + ze_undeclare_querying_subscriber(z_move(sub)); z_close(z_move(s)); return -1; diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index 4ca671d46..0753dbf8a 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -34,28 +34,41 @@ const char *const V_CONST = "v const"; int run_publisher() { SEM_WAIT(sem); - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + if (z_open(&s, z_move(config))) { perror("Unable to open session!"); return -1; } - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); - if (!z_check(pub)) { + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + z_owned_publisher_t pub; + if (z_declare_publisher(&pub, z_loan(s), z_loan(ke), NULL) < 0) { perror("Unable to declare Publisher for key expression!"); return -1; } - z_owned_bytes_map_t map = z_slice_map_new(); - z_slice_map_insert_by_copy(&map, z_slice_from_str(K_CONST), z_slice_from_str(V_CONST)); - - z_publisher_put_options_t options = z_publisher_put_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - options.attachment = z_slice_map_as_attachment(&map); + z_owned_slice_map_t map; + z_slice_map_new(&map); + z_view_slice_t k_const, v_const; + z_view_slice_from_str(&k_const, K_CONST); + z_view_slice_from_str(&v_const, V_CONST); + z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_const), z_loan(v_const)); + + z_publisher_put_options_t options; + z_publisher_put_options_default(&options); + z_owned_bytes_t attachment; + z_bytes_encode_from_slice_map(&attachment, z_loan(map)); + options.attachment = &attachment; for (int i = 0; i < values_count; ++i) { - z_slice_map_insert_by_copy(&map, z_slice_from_str(K_VAR), z_slice_from_str(values[i])); - z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); + z_view_slice_t k_var, v_var; + z_view_slice_from_str(&k_var, K_VAR); + z_view_slice_from_str(&v_var, values[i]); + z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_var), z_loan(v_var)); + z_owned_bytes_t payload; + z_bytes_encode_from_slice(&payload, z_loan(v_var)); z_publisher_put(z_loan(pub), z_move(payload), &options); } @@ -67,45 +80,66 @@ int run_publisher() { void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - if (strcmp(keyexpr, z_loan(keystr))) { + z_owned_str_t keystr; + z_keyexpr_to_string(z_sample_keyexpr(sample), &keystr); + if (strcmp(keyexpr, z_str_data(z_loan(keystr)))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); - if (strcmp(values[val_num], z_loan(payload_value))) { + z_owned_str_t payload_str; + z_bytes_decode_into_string(z_sample_payload(sample), &payload_str); + if (strcmp(values[val_num], z_str_data(z_loan(payload_str)))) { perror("Unexpected value received"); - z_drop(z_move(payload_value)); + z_drop(z_move(payload_str)); + exit(-1); + } + z_drop(z_move(payload_str)); + const z_loaned_bytes_t* attachment = z_sample_attachment(sample); + if (attachment == NULL) { + perror("Missing attachment!"); exit(-1); } - z_drop(z_move(payload_value)); + z_drop(z_move(keystr)); - z_loaned_slice_t v_const = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_CONST)); - ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); + z_owned_slice_map_t map; + z_bytes_decode_into_slice_map(attachment, &map); - z_loaned_slice_t v_var = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_VAR)); - ASSERT_STR_BYTES_EQUAL(values[val_num], v_var); + z_view_slice_t k_const, k_var; + z_view_slice_from_str(&k_const, K_CONST); + z_view_slice_from_str(&k_var, K_CONST); + const z_loaned_slice_t* v_const = z_slice_map_get(z_loan(map), z_loan(k_const)); + ASSERT_STR_SLICE_EQUAL(V_CONST, v_const); + + const z_loaned_slice_t* v_var = z_slice_map_get(z_loan(map), z_loan(k_var)); + ASSERT_STR_SLICE_EQUAL(values[val_num], v_var); + + z_drop(z_move(map)); if (++val_num == values_count) { exit(0); }; } int run_subscriber() { - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { perror("Unable to open session!"); return -1; } - z_owned_closure_sample_t callback = z_closure(data_handler); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); - if (!z_check(sub)) { + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); + z_owned_subscriber_t sub; + ; + if (z_declare_subscriber(&sub, z_loan(s), z_loan(ke), z_move(callback), NULL) < 0) { perror("Unable to declare subscriber!"); return -1; } diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index 1892095e7..d53b6bca3 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -30,26 +30,34 @@ const size_t values_count = sizeof(values) / sizeof(values[0]); int run_publisher() { SEM_WAIT(sem); - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { perror("Unable to open session!"); return -1; } - z_publisher_options_t publisher_options = z_publisher_options_default(); + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + z_publisher_options_t publisher_options; + z_publisher_options_default(&publisher_options); publisher_options.priority = Z_PRIORITY_DATA; publisher_options.congestion_control = Z_CONGESTION_CONTROL_BLOCK; - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), &publisher_options); + z_owned_publisher_t pub; + z_declare_publisher(&pub, z_loan(s), z_loan(ke), &publisher_options); if (!z_check(pub)) { perror("Unable to declare Publisher for key expression!"); return -1; } for (int i = 0; i < values_count; ++i) { - z_publisher_put_options_t options = z_publisher_put_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); + z_publisher_put_options_t options; + z_publisher_put_options_default(&options); + z_view_str_t value_str; + z_view_str_wrap(&value_str, values[i]); + z_owned_bytes_t payload; + z_bytes_encode_from_string(&payload, z_loan(value_str)); z_publisher_put(z_loan(pub), z_move(payload), &options); } @@ -60,24 +68,25 @@ int run_publisher() { void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - if (strcmp(keyexpr, z_loan(keystr))) { + z_owned_str_t keystr; + z_keyexpr_to_string(z_sample_keyexpr(sample), &keystr); + if (strcmp(keyexpr, z_str_data(z_loan(keystr)))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); - if (strcmp(values[val_num], z_loan(payload_value))) { + z_owned_str_t payload_str; + z_bytes_decode_into_string(z_sample_payload(sample), &payload_str); + if (strcmp(values[val_num], z_str_data(z_loan(payload_str)))) { perror("Unexpected value received"); - z_drop(z_move(payload_value)); + z_drop(z_move(payload_str)); exit(-1); } - z_drop(z_move(payload_value)); + z_drop(z_move(payload_str)); - if (z_qos_get_congestion_control(z_sample_qos(sample)) != Z_CONGESTION_CONTROL_BLOCK || - z_qos_get_priority(z_sample_qos(sample)) != Z_PRIORITY_DATA) { + if (z_sample_congestion_control(sample) != Z_CONGESTION_CONTROL_BLOCK || + z_sample_priority(sample) != Z_PRIORITY_DATA) { perror("Unexpected QoS values"); exit(-1); } @@ -88,17 +97,22 @@ void data_handler(const z_loaned_sample_t *sample, void *arg) { } int run_subscriber() { - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { perror("Unable to open session!"); return -1; } - z_owned_closure_sample_t callback = z_closure(data_handler); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); - if (!z_check(sub)) { + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); + z_owned_subscriber_t sub; + if (z_declare_subscriber(&sub, z_loan(s), z_loan(ke), z_move(callback), NULL) < 0) { perror("Unable to declare subscriber!"); return -1; } diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 1c3e203d1..c141bb068 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -32,28 +32,54 @@ const char *const V_CONST = "v const"; void query_handler(const z_loaned_query_t *query, void *context) { static int value_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_loaned_slice_t pred = z_query_parameters(query); - z_loaned_value_t payload_value = z_query_value(query); + z_owned_str_t keystr; + z_keyexpr_to_string(z_query_keyexpr(query), &keystr); + z_view_slice_t params; + z_query_parameters(query, ¶ms); + const z_loaned_value_t* payload_value = z_query_value(query); + + const z_loaned_bytes_t* attachment = z_query_attachment(query); + if (attachment == NULL) { + perror("Missing attachment!"); + exit(-1); + } + + z_view_slice_t k_const, k_var; + z_view_slice_from_str(&k_const, K_CONST); + z_view_slice_from_str(&k_var, K_VAR); + + z_owned_slice_map_t map; + z_bytes_decode_into_slice_map(attachment, &map); + + const z_loaned_slice_t* v_const = z_slice_map_get(z_loan(map), z_loan(k_const)); + ASSERT_STR_SLICE_EQUAL(V_CONST, v_const); - z_loaned_bytes_t attachment = z_query_attachment(query); + const z_loaned_slice_t* v_var = z_slice_map_get(z_loan(map), z_loan(k_var)); + ASSERT_STR_SLICE_EQUAL(values[value_num], v_var); - z_loaned_slice_t v_const = z_attachment_get(attachment, z_slice_from_str(K_CONST)); - ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); + z_owned_slice_map_t reply_map; + z_slice_map_new(&reply_map); + z_slice_map_insert_by_copy(z_loan_mut(reply_map), z_loan(k_const), v_const); - z_loaned_slice_t v_var = z_attachment_get(attachment, z_slice_from_str(K_VAR)); - ASSERT_STR_BYTES_EQUAL(values[value_num], v_var); + z_query_reply_options_t options; + z_query_reply_options_default(&options); - z_owned_bytes_map_t map = z_slice_map_new(); - z_slice_map_insert_by_copy(&map, z_slice_from_str(K_CONST), z_slice_from_str(V_CONST)); + z_owned_bytes_t reply_attachment; + z_bytes_encode_from_slice_map(&reply_attachment, z_loan(reply_map)); + options.attachment = &reply_attachment; - z_query_reply_options_t options = z_query_reply_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - options.attachment = z_slice_map_as_attachment(&map); - z_owned_bytes_t payload = z_bytes_encode_from_string(values[value_num]); - z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); + z_view_str_t value_str; + z_view_str_wrap(&value_str, values[value_num]); + + z_owned_bytes_t payload; + z_bytes_encode_from_string(&payload, z_loan(value_str)); + + z_view_keyexpr_t reply_ke; + z_view_keyexpr_new(&reply_ke, (const char *)context); + z_query_reply(query, z_loan(reply_ke), z_move(payload), &options); z_drop(z_move(keystr)); z_drop(z_move(map)); + z_drop(z_move(reply_map)); if (++value_num == values_count) { exit(0); @@ -61,16 +87,22 @@ void query_handler(const z_loaned_query_t *query, void *context) { } int run_queryable() { - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { perror("Unable to open session!"); return -1; } - z_owned_closure_query_t callback = z_closure(query_handler, NULL, keyexpr); - z_owned_queryable_t qable = z_declare_queryable(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); - if (!z_check(qable)) { + z_owned_closure_query_t callback; + z_closure(&callback, query_handler, NULL, keyexpr); + + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + + z_owned_queryable_t qable; + if (z_declare_queryable(&qable, z_loan(s), z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to create queryable.\n"); return -1; } @@ -78,7 +110,7 @@ int run_queryable() { SEM_POST(sem); z_sleep_s(10); - z_drop(z_move(qable)); + z_undeclare_queryable(z_move(qable)); z_close(z_move(s)); return 0; } @@ -86,43 +118,70 @@ int run_queryable() { int run_get() { SEM_WAIT(sem); - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { perror("Unable to open session!"); return -1; } - z_owned_bytes_map_t map = z_slice_map_new(); - z_slice_map_insert_by_copy(&map, z_slice_from_str(K_CONST), z_slice_from_str(V_CONST)); + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); - z_get_options_t opts = z_get_options_default(); - opts.attachment = z_slice_map_as_attachment(&map); + z_owned_slice_map_t map; + z_slice_map_new(&map); - for (int val_num = 0; val_num < values_count; ++val_num) { - z_slice_map_insert_by_copy(&map, z_slice_from_str(K_VAR), z_slice_from_str(values[val_num])); + z_view_slice_t k_const, k_var, v_const; + z_view_slice_from_str(&k_const, K_CONST); + z_view_slice_from_str(&k_var, K_VAR); + z_view_slice_from_str(&v_const, V_CONST); - z_owned_reply_channel_t channel = zc_reply_fifo_new(16); - z_get(z_loan(s), z_keyexpr(keyexpr), "", z_move(channel.send), &opts); - z_owned_reply_t reply = z_reply_null(); - for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { - assert(z_reply_is_ok(&reply)); + z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_const), z_loan(v_const)); + + z_get_options_t opts; + z_get_options_default(&opts); + + z_owned_bytes_t attachment; + z_bytes_encode_from_slice_map(&attachment, z_loan(map)); + opts.attachment = &attachment; - z_loaned_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); - if (strcmp(values[val_num], z_loan(payload_value))) { + for (int val_num = 0; val_num < values_count; ++val_num) { + z_view_slice_t v_var; + z_view_slice_from_str(&v_var, values[val_num]); + z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_var), z_loan(v_var)); + + z_owned_reply_channel_t channel; + zc_reply_fifo_new(&channel, 16); + z_get(z_loan(s), z_loan(ke), "", z_move(channel.send), &opts); + z_owned_reply_t reply; + for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { + assert(z_reply_is_ok(z_loan(reply))); + + const z_loaned_sample_t* sample = z_reply_ok(z_loan(reply)); + z_owned_str_t keystr; + z_keyexpr_to_string(z_sample_keyexpr(sample), &keystr); + z_owned_str_t payload_str; + z_bytes_decode_into_string(z_sample_payload(sample), &payload_str); + if (strcmp(values[val_num], z_str_data(z_loan(payload_str)))) { perror("Unexpected value received"); - z_drop(z_move(payload_value)); + z_drop(z_move(payload_str)); exit(-1); } - z_loaned_slice_t v_const = z_attachment_get(z_sample_attachment(&sample), z_slice_from_str(K_CONST)); - ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); + const z_loaned_bytes_t* received_attachment = z_sample_attachment(sample); + if (received_attachment == NULL) { + perror("Missing attachment!"); + exit(-1); + } + z_owned_slice_map_t received_map; + z_bytes_decode_into_slice_map(received_attachment, &received_map); + const z_loaned_slice_t* v_const_get = z_slice_map_get(z_loan(received_map), z_loan(k_const)); + ASSERT_STR_SLICE_EQUAL(V_CONST, v_const_get); z_drop(z_move(keystr)); - z_drop(z_move(payload_value)); + z_drop(z_move(payload_str)); + z_drop(z_move(received_map)); } z_drop(z_move(reply)); z_drop(z_move(channel)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 025e35746..874d57f35 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -28,15 +28,23 @@ const size_t values_count = sizeof(values) / sizeof(values[0]); void query_handler(const z_loaned_query_t *query, void *context) { static int value_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_loaned_slice_t pred = z_query_parameters(query); - z_loaned_value_t payload_value = z_query_value(query); - - z_query_reply_options_t options = z_query_reply_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_owned_bytes_t payload = z_bytes_encode_from_string(values[value_num]); - z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); - z_drop(z_move(keystr)); + z_owned_str_t key_string; + z_keyexpr_to_string(z_query_keyexpr(query), &key_string); + z_view_slice_t params; + z_query_parameters(query, ¶ms); + const z_loaned_value_t* payload_value = z_query_value(query); + + z_query_reply_options_t options; + z_query_reply_options_default(&options); + z_view_str_t value_str; + z_view_str_wrap(&value_str, values[value_num]); + z_owned_bytes_t payload; + z_bytes_encode_from_string(&payload, z_loan(value_str)); + + z_view_keyexpr_t reply_ke; + z_view_keyexpr_new(&reply_ke, (const char*)context); + z_query_reply(query, z_loan(reply_ke), z_move(payload), &options); + z_drop(z_move(key_string)); if (++value_num == values_count) { exit(0); @@ -44,15 +52,20 @@ void query_handler(const z_loaned_query_t *query, void *context) { } int run_queryable() { - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { perror("Unable to open session!"); return -1; } - z_owned_closure_query_t callback = z_closure(query_handler, NULL, keyexpr); - z_owned_queryable_t qable = z_declare_queryable(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + z_owned_closure_query_t callback; + z_closure(&callback, query_handler, NULL, keyexpr); + z_owned_queryable_t qable; + z_declare_queryable(&qable, z_loan(s), z_loan(ke), z_move(callback), NULL); if (!z_check(qable)) { printf("Unable to create queryable.\n"); return -1; @@ -61,7 +74,7 @@ int run_queryable() { SEM_POST(sem); z_sleep_s(10); - z_drop(z_move(qable)); + z_undeclare_queryable(z_move(qable)); z_close(z_move(s)); return 0; } @@ -69,35 +82,42 @@ int run_queryable() { int run_get() { SEM_WAIT(sem); - z_owned_config_t config = z_config_default(); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_config_t config; + z_config_default(&config); + z_owned_session_t s; + if (z_open(&s, z_move(config))) { perror("Unable to open session!"); return -1; } + z_view_keyexpr_t ke; + z_view_keyexpr_new(&ke, keyexpr); + for (int val_num = 0; val_num < values_count; ++val_num) { - z_owned_reply_channel_t channel = zc_reply_fifo_new(16); - z_get_options_t opts = z_get_options_default(); - z_get(z_loan(s), z_keyexpr(keyexpr), "", z_move(channel.send), &opts); - z_owned_reply_t reply = z_reply_null(); + z_owned_reply_channel_t channel; + zc_reply_fifo_new(&channel, 16); + z_get_options_t opts; + z_get_options_default(&opts); + z_get(z_loan(s), z_loan(ke), "", z_move(channel.send), &opts); + z_owned_reply_t reply; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { - assert(z_reply_is_ok(&reply)); - - z_loaned_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); - if (strcmp(values[val_num], z_loan(payload_value))) { + assert(z_reply_is_ok(z_loan(reply))); + + const z_loaned_sample_t* sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_string; + z_keyexpr_to_string(z_sample_keyexpr(sample), &key_string); + z_owned_str_t payload_string; + z_bytes_decode_into_string(z_sample_payload(sample), &payload_string); + if (strcmp(values[val_num], z_str_data(z_loan(payload_string)))) { perror("Unexpected value received"); - z_drop(z_move(payload_value)); + z_drop(z_move(payload_string)); exit(-1); } - z_drop(z_move(keystr)); - z_drop(z_move(payload_value)); + z_drop(z_move(key_string)); + z_drop(z_move(payload_string)); + z_drop(z_move(reply)); } - z_drop(z_move(reply)); z_drop(z_move(channel)); } z_close(z_move(s)); From e748a6fd11bf8fc39ca43b9fa58b04c210e5a6f2 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 2 May 2024 18:34:27 +0200 Subject: [PATCH 067/377] most tests pass --- build-resources/opaque-types/src/lib.rs | 22 +- build.rs | 43 ++-- include/zenoh_commons.h | 18 +- include/zenoh_macros.h | 6 +- src/closures/hello_closure.rs | 1 + src/closures/matching_status_closure.rs | 5 +- src/closures/query_channel.rs | 15 +- src/closures/query_closure.rs | 1 + src/closures/reply_closure.rs | 1 + src/closures/response_channel.rs | 16 +- src/closures/sample_closure.rs | 1 + src/closures/zenohid_closure.rs | 1 + src/collections.rs | 280 +++++++++++++++--------- src/commons.rs | 1 - src/get.rs | 16 +- src/keyexpr.rs | 2 +- src/payload.rs | 23 +- src/queryable.rs | 29 +-- src/scouting.rs | 28 ++- src/transmute.rs | 12 +- tests/z_api_alignment_test.c | 14 +- tests/z_api_keyexpr_test.c | 4 +- tests/z_api_map_test.c | 2 +- tests/z_api_null_drop_test.c | 8 - tests/z_api_payload_test.c | 58 ++++- tests/z_int_pub_sub_attachment_test.c | 13 +- tests/z_int_queryable_attachment_test.c | 13 +- 27 files changed, 377 insertions(+), 256 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 90e744dbf..ad328a522 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -47,31 +47,33 @@ get_opaque_type_data!(Option, z_owned_bytes_t); /// A loaned payload. get_opaque_type_data!(ZBytes, z_loaned_bytes_t); + +type CSlice = (usize, isize); /// A contiguous view of bytes owned by some other entity. /// /// `start` being `null` is considered a gravestone value, /// and empty slices are represented using a possibly dangling pointer for `start`. -get_opaque_type_data!(Option>, z_owned_slice_t); -get_opaque_type_data!(Option<&'static [u8]>, z_view_slice_t); -get_opaque_type_data!(&'static [u8], z_loaned_slice_t); +get_opaque_type_data!(CSlice, z_owned_slice_t); +get_opaque_type_data!(CSlice, z_view_slice_t); +get_opaque_type_data!(CSlice, z_loaned_slice_t); /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` /// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with /// `z_check` and `z_str_check` correspondently -get_opaque_type_data!(Option>, z_owned_str_t); -get_opaque_type_data!(Option<&'static [u8]>, z_view_str_t); -get_opaque_type_data!(&'static [u8], z_loaned_str_t); +get_opaque_type_data!(CSlice, z_owned_str_t); +get_opaque_type_data!(CSlice, z_view_str_t); +get_opaque_type_data!(CSlice, z_loaned_str_t); /// A map of maybe-owned slices to maybe-owned slices. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher -get_opaque_type_data!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); -get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_loaned_slice_map_t); +get_opaque_type_data!(Option>, z_owned_slice_map_t); +get_opaque_type_data!(HashMap, z_loaned_slice_map_t); /// An array of maybe-owned slices /// -get_opaque_type_data!(Option>>, z_owned_slice_array_t); -get_opaque_type_data!(Vec>, z_loaned_slice_array_t); +get_opaque_type_data!(Option>, z_owned_slice_array_t); +get_opaque_type_data!(Vec, z_loaned_slice_array_t); /// An owned sample. /// diff --git a/build.rs b/build.rs index e059fabd6..d9610c7b4 100644 --- a/build.rs +++ b/build.rs @@ -955,7 +955,7 @@ pub fn find_call_functions(path_in: &str) -> Vec { res } -pub fn generate_generic_loan_c(macro_func: &Vec) -> String { +pub fn generate_generic_loan_c(macro_func: &[FunctionSignature]) -> String { let mut out = "#define z_loan(x) \\ _Generic((x)" .to_owned(); @@ -971,9 +971,7 @@ pub fn generate_generic_loan_c(macro_func: &Vec) -> String { out } -pub fn generate_generic_loan_mut_c( - macro_func: &Vec -) -> String { +pub fn generate_generic_loan_mut_c(macro_func: &[FunctionSignature]) -> String { let mut out = "#define z_loan_mut(x) \\ _Generic((x)" .to_owned(); @@ -989,7 +987,7 @@ pub fn generate_generic_loan_mut_c( out } -pub fn generate_generic_drop_c(macro_func: &Vec) -> String { +pub fn generate_generic_drop_c(macro_func: &[FunctionSignature]) -> String { let mut out = "#define z_drop(x) \\ _Generic((x)" .to_owned(); @@ -1005,7 +1003,7 @@ pub fn generate_generic_drop_c(macro_func: &Vec) -> String { out } -pub fn generate_generic_null_c(macro_func: &Vec) -> String { +pub fn generate_generic_null_c(macro_func: &[FunctionSignature]) -> String { let mut out = "#define z_null(x) \\ _Generic((x)" .to_owned(); @@ -1021,7 +1019,7 @@ pub fn generate_generic_null_c(macro_func: &Vec) -> String { out } -pub fn generate_generic_check_c(macro_func: &Vec) -> String { +pub fn generate_generic_check_c(macro_func: &[FunctionSignature]) -> String { let mut out = "#define z_check(x) \\ _Generic((x)" .to_owned(); @@ -1037,7 +1035,7 @@ pub fn generate_generic_check_c(macro_func: &Vec) -> String { out } -pub fn generate_generic_call_c(macro_func: &Vec) -> String { +pub fn generate_generic_call_c(macro_func: &[FunctionSignature]) -> String { let mut out = "#define z_call(x, ...) \\ _Generic((x)" .to_owned(); @@ -1054,16 +1052,13 @@ pub fn generate_generic_call_c(macro_func: &Vec) -> String { out } -pub fn generate_generic_closure_c( - _macro_func: &Vec -) -> String { - let out = "#define z_closure(x, callback, dropper, ctx) \\ +pub fn generate_generic_closure_c(_macro_func: &[FunctionSignature]) -> String { + "#define z_closure(x, callback, dropper, ctx) \\ {{(x)->context = (void*)(ctx); (x)->call = (callback); (x)->drop = (dropper);}}" - .to_owned(); - out + .to_owned() } -pub fn generate_generic_loan_cpp(macro_func: &Vec) -> String { +pub fn generate_generic_loan_cpp(macro_func: &[FunctionSignature]) -> String { let mut out = "".to_owned(); for func in macro_func { @@ -1078,9 +1073,7 @@ pub fn generate_generic_loan_cpp(macro_func: &Vec) -> String out } -pub fn generate_generic_loan_mut_cpp( - macro_func: &Vec -) -> String { +pub fn generate_generic_loan_mut_cpp(macro_func: &[FunctionSignature]) -> String { let mut out = "".to_owned(); for func in macro_func { @@ -1095,7 +1088,7 @@ pub fn generate_generic_loan_mut_cpp( out } -pub fn generate_generic_drop_cpp(macro_func: &Vec) -> String { +pub fn generate_generic_drop_cpp(macro_func: &[FunctionSignature]) -> String { let mut out = "".to_owned(); for func in macro_func { @@ -1110,7 +1103,7 @@ pub fn generate_generic_drop_cpp(macro_func: &Vec) -> String out } -pub fn generate_generic_null_cpp(macro_func: &Vec) -> String { +pub fn generate_generic_null_cpp(macro_func: &[FunctionSignature]) -> String { let mut out = "".to_owned(); for func in macro_func { @@ -1125,9 +1118,7 @@ pub fn generate_generic_null_cpp(macro_func: &Vec) -> String out } -pub fn generate_generic_check_cpp( - macro_func: &Vec -) -> String { +pub fn generate_generic_check_cpp(macro_func: &[FunctionSignature]) -> String { let mut out = "".to_owned(); for func in macro_func { @@ -1142,7 +1133,7 @@ pub fn generate_generic_check_cpp( out } -pub fn generate_generic_call_cpp(macro_func: &Vec) -> String { +pub fn generate_generic_call_cpp(macro_func: &[FunctionSignature]) -> String { let mut out = "".to_owned(); for func in macro_func { @@ -1162,9 +1153,7 @@ pub fn generate_generic_call_cpp(macro_func: &Vec) -> String out } -pub fn generate_generic_closure_cpp( - macro_func: &Vec -) -> String { +pub fn generate_generic_closure_cpp(macro_func: &[FunctionSignature]) -> String { let mut out = "".to_owned(); for func in macro_func { diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index c010593d1..c581a9bde 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -479,8 +479,9 @@ typedef struct z_query_consolidation_t { * Members: * z_loaned_query_target_t target: The Queryables that should be target of the query. * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. - * z_loaned_value_t value: An optional value to attach to the query. - * z_loaned_bytes_t attachment: The attachment to attach to the query. + * z_owned_payload_t* payload: An optional payload to attach to the query. + * z_owned_encdoing_t* encdoing: An optional encoding of the query payload and or attachment. + * z_owned_bytes_t attachment: The attachment to attach to the query. * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. */ typedef struct z_get_options_t { @@ -1628,10 +1629,6 @@ ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); */ ZENOHC_API void z_query_drop(struct z_owned_query_t *this_); -/** - * Checks if query contains a payload value. - */ -ZENOHC_API bool z_query_has_value(const struct z_loaned_query_t *query); /** * Get a query's key by aliasing it. */ @@ -1681,8 +1678,7 @@ ZENOHC_API void z_query_reply_options_default(struct z_query_reply_options_t *th /** * Gets a query's `payload value `_ by aliasing it. * - * **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** - * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. + * Returns NULL if query does not contain a value. */ ZENOHC_API const struct z_loaned_value_t *z_query_value(const struct z_loaned_query_t *query); @@ -1998,7 +1994,6 @@ ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); * Constructs the gravestone value for `z_owned_slice_map_t` */ ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); -ZENOHC_API void z_slice_null(struct z_owned_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. */ @@ -2190,11 +2185,14 @@ ZENOHC_API void z_view_slice_empty(struct z_view_slice_t *this_); */ ZENOHC_API void z_view_slice_from_str(struct z_view_slice_t *this_, const char *str); ZENOHC_API const struct z_loaned_slice_t *z_view_slice_loan(const struct z_view_slice_t *this_); -ZENOHC_API void z_view_slice_null(struct z_view_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. */ ZENOHC_API void z_view_slice_wrap(struct z_view_slice_t *this_, const uint8_t *start, size_t len); +/** + * Returns ``true`` if `s` is a valid string + */ +ZENOHC_API bool z_view_str_check(const struct z_view_str_t *this_); ZENOHC_API void z_view_str_empty(struct z_view_str_t *this_); ZENOHC_API size_t z_view_str_len(const struct z_loaned_str_t *this_); /** diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index f3d9a5315..fe305cebc 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -99,12 +99,10 @@ z_owned_session_t * : z_session_null, \ z_owned_slice_array_t * : z_slice_array_null, \ z_owned_slice_map_t * : z_slice_map_null, \ - z_owned_slice_t * : z_slice_null, \ z_owned_str_t * : z_str_null, \ z_owned_subscriber_t * : z_subscriber_null, \ z_owned_task_t * : z_task_null, \ z_view_keyexpr_t * : z_view_keyexpr_null, \ - z_view_slice_t * : z_view_slice_null, \ z_view_str_t * : z_view_str_null, \ zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ @@ -137,6 +135,7 @@ z_owned_task_t : z_task_check, \ z_view_keyexpr_t : z_view_keyexpr_check, \ z_view_slice_t : z_view_slice_check, \ + z_view_str_t : z_view_str_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ ze_owned_publication_cache_t : ze_publication_cache_check, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_check \ @@ -247,12 +246,10 @@ inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config inline void z_null( z_owned_session_t* this_) { return z_session_null(this_); }; inline void z_null( z_owned_slice_array_t* this_) { return z_slice_array_null(this_); }; inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; -inline void z_null( z_owned_slice_t* this_) { return z_slice_null(this_); }; inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; inline void z_null( z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; inline void z_null( z_owned_task_t* this_) { return z_task_null(this_); }; inline void z_null( z_view_keyexpr_t* this_) { return z_view_keyexpr_null(this_); }; -inline void z_null( z_view_slice_t* this_) { return z_view_slice_null(this_); }; inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; inline void z_null( zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_null(this_); }; inline void z_null( zcu_owned_closure_matching_status_t* this_) { return zcu_closure_matching_status_null(this_); }; @@ -283,6 +280,7 @@ inline bool z_check(const z_owned_subscriber_t& subscriber) { return z_subscribe inline bool z_check(const z_owned_task_t& this_) { return z_task_check(&this_); }; inline bool z_check(const z_view_keyexpr_t& keyexpr) { return z_view_keyexpr_check(&keyexpr); }; inline bool z_check(const z_view_slice_t& this_) { return z_view_slice_check(&this_); }; +inline bool z_check(const z_view_str_t& this_) { return z_view_str_check(&this_); }; inline bool z_check(const zc_owned_liveliness_token_t& this_) { return zc_liveliness_token_check(&this_); }; inline bool z_check(const ze_owned_publication_cache_t& this_) { return ze_publication_cache_check(&this_); }; inline bool z_check(const ze_owned_querying_subscriber_t& this_) { return ze_querying_subscriber_check(&this_); }; diff --git a/src/closures/hello_closure.rs b/src/closures/hello_closure.rs index b0a7f8d54..58233831d 100644 --- a/src/closures/hello_closure.rs +++ b/src/closures/hello_closure.rs @@ -44,6 +44,7 @@ impl Drop for z_owned_closure_hello_t { } /// Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_closure_hello_null(this: *mut MaybeUninit) { (*this).write(z_owned_closure_hello_t::empty()); } diff --git a/src/closures/matching_status_closure.rs b/src/closures/matching_status_closure.rs index e07285593..bd93d46b0 100644 --- a/src/closures/matching_status_closure.rs +++ b/src/closures/matching_status_closure.rs @@ -44,7 +44,10 @@ impl Drop for zcu_owned_closure_matching_status_t { } /// Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type #[no_mangle] -pub unsafe extern "C" fn zcu_closure_matching_status_null(this: *mut MaybeUninit) { +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zcu_closure_matching_status_null( + this: *mut MaybeUninit, +) { (*this).write(zcu_owned_closure_matching_status_t::empty()); } /// Calls the closure. Calling an uninitialized closure is a no-op. diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index 88e1a1f4b..5e45dc3ab 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -87,7 +87,10 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver /// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_query_fifo_new(this: *mut MaybeUninit, bound: usize) { +pub unsafe extern "C" fn zc_query_fifo_new( + this: *mut MaybeUninit, + bound: usize, +) { let (send, rx) = get_send_recv_ends(bound); let c = z_owned_query_channel_t { send, @@ -114,7 +117,10 @@ pub unsafe extern "C" fn zc_query_fifo_new(this: *mut MaybeUninit, bound: usize) { +pub unsafe extern "C" fn zc_query_non_blocking_fifo_new( + this: *mut MaybeUninit, + bound: usize, +) { let (send, rx) = get_send_recv_ends(bound); let c = z_owned_query_channel_t { send, @@ -159,7 +165,10 @@ impl Drop for z_owned_query_channel_closure_t { /// Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type #[no_mangle] -pub unsafe extern "C" fn z_query_channel_closure_null(this: *mut MaybeUninit) { +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_query_channel_closure_null( + this: *mut MaybeUninit, +) { (*this).write(z_owned_query_channel_closure_t::empty()); } diff --git a/src/closures/query_closure.rs b/src/closures/query_closure.rs index bc641470c..2a9ed176a 100644 --- a/src/closures/query_closure.rs +++ b/src/closures/query_closure.rs @@ -42,6 +42,7 @@ impl Drop for z_owned_closure_query_t { } /// Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_closure_query_null(this: *mut MaybeUninit) { (*this).write(z_owned_closure_query_t::empty()); } diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index 7a9f3aeaa..fea8435ce 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -43,6 +43,7 @@ impl Drop for z_owned_closure_reply_t { } /// Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_closure_reply_null(this: *mut MaybeUninit) { (*this).write(z_owned_closure_reply_t::empty()); } diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 8f67163d9..3ee803f9c 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -38,6 +38,7 @@ pub extern "C" fn z_reply_channel_drop(channel: &mut z_owned_reply_channel_t) { } /// Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_channel_null(this: *mut MaybeUninit) { let c = z_owned_reply_channel_t { send: z_owned_closure_reply_t::empty(), @@ -86,7 +87,10 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver /// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_reply_fifo_new(this: *mut MaybeUninit ,bound: usize) { +pub unsafe extern "C" fn zc_reply_fifo_new( + this: *mut MaybeUninit, + bound: usize, +) { let (send, rx) = get_send_recv_ends(bound); let c = z_owned_reply_channel_t { send, @@ -113,7 +117,10 @@ pub unsafe extern "C" fn zc_reply_fifo_new(this: *mut MaybeUninit, bound: usize) { +pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new( + this: *mut MaybeUninit, + bound: usize, +) { let (send, rx) = get_send_recv_ends(bound); let c = z_owned_reply_channel_t { send, @@ -158,7 +165,10 @@ impl Drop for z_owned_reply_channel_closure_t { /// Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type #[no_mangle] -pub unsafe extern "C" fn z_reply_channel_closure_null(this: *mut MaybeUninit) { +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_reply_channel_closure_null( + this: *mut MaybeUninit, +) { (*this).write(z_owned_reply_channel_closure_t::empty()); } diff --git a/src/closures/sample_closure.rs b/src/closures/sample_closure.rs index 9416d956f..d69e8285a 100644 --- a/src/closures/sample_closure.rs +++ b/src/closures/sample_closure.rs @@ -43,6 +43,7 @@ impl Drop for z_owned_closure_sample_t { /// Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_closure_sample_null(this: *mut MaybeUninit) { (*this).write(z_owned_closure_sample_t::empty()); } diff --git a/src/closures/zenohid_closure.rs b/src/closures/zenohid_closure.rs index 5c6d8c03d..3c4ffbf89 100644 --- a/src/closures/zenohid_closure.rs +++ b/src/closures/zenohid_closure.rs @@ -44,6 +44,7 @@ impl Drop for z_owned_closure_zid_t { } /// Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_closure_zid_null(this: *mut MaybeUninit) { (*this).write(z_owned_closure_zid_t::empty()); } diff --git a/src/collections.rs b/src/collections.rs index 95345255e..fa82b309c 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -12,10 +12,10 @@ // ZettaScale Zenoh team, // -use std::borrow::Cow; use std::collections::HashMap; +use std::hash::Hash; use std::mem::MaybeUninit; -use std::ptr::null; +use std::ptr::{null, slice_from_raw_parts}; use std::slice::from_raw_parts; use libc::{c_char, c_void, strlen}; @@ -26,24 +26,111 @@ use crate::transmute::{ TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; +pub struct CSlice(*const u8, isize); + +impl CSlice { + pub fn new_borrowed(data: *const u8, len: usize) -> Self { + let len: isize = len as isize; + CSlice(data, -len) + } + + pub fn new_borrowed_from_slice(slice: &[u8]) -> Self { + Self::new_borrowed(slice.as_ptr(), slice.len()) + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn new_owned(data: *const u8, len: usize) -> Self { + if len == 0 { + return CSlice::default(); + } + let b = unsafe { from_raw_parts(data, len).to_vec().into_boxed_slice() }; + let slice = Box::leak(b); + CSlice(slice.as_ptr(), slice.len() as isize) + } + + pub fn slice(&self) -> &'static [u8] { + if self.1 == 0 { + return &[0u8; 0]; + } + unsafe { from_raw_parts(self.0, self.1.unsigned_abs()) } + } + + pub fn data(&self) -> *const u8 { + self.0 + } + + pub fn len(&self) -> usize { + self.1.unsigned_abs() + } + + pub fn is_empty(&self) -> bool { + self.1 == 0 + } + + pub fn is_owned(&self) -> bool { + self.1 > 0 + } + + pub fn shallow_copy(&self) -> Self { + Self(self.0, self.1) + } +} + +impl Default for CSlice { + fn default() -> Self { + Self(null(), 0) + } +} + +impl Drop for CSlice { + fn drop(&mut self) { + if !self.is_owned() { + return; + } + let b = unsafe { Box::from_raw(slice_from_raw_parts(self.data(), self.len()).cast_mut()) }; + std::mem::drop(b); + } +} + +impl Hash for CSlice { + fn hash(&self, state: &mut H) { + self.slice().hash(state); + } +} + +impl PartialEq for CSlice { + fn eq(&self, other: &Self) -> bool { + self.slice() == other.slice() + } +} + +impl Clone for CSlice { + fn clone(&self) -> Self { + unsafe { Self::new_owned(self.data(), self.len()) } + } +} + +impl From> for CSlice { + fn from(value: Vec) -> Self { + let slice = Box::leak(value.into_boxed_slice()); + CSlice(slice.as_ptr(), slice.len() as isize) + } +} + +impl std::cmp::Eq for CSlice {} + pub use crate::opaque_types::z_loaned_slice_t; pub use crate::opaque_types::z_owned_slice_t; pub use crate::opaque_types::z_view_slice_t; -decl_transmute_owned!(Option>, z_owned_slice_t); -decl_transmute_owned!(Option<&'static [u8]>, z_view_slice_t); -decl_transmute_handle!(&'static [u8], z_loaned_slice_t); +decl_transmute_owned!(CSlice, z_owned_slice_t); +decl_transmute_owned!(custom_inplace_init CSlice, z_view_slice_t); +decl_transmute_handle!(CSlice, z_loaned_slice_t); /// Returns an empty `z_view_slice_t` #[no_mangle] pub extern "C" fn z_view_slice_empty(this: *mut MaybeUninit) { - let slice: &'static [u8] = &[]; - Inplace::init(this.transmute_uninit_ptr(), Some(slice)) -} - -#[no_mangle] -pub extern "C" fn z_view_slice_null(this: *mut MaybeUninit) { - Inplace::empty(this.transmute_uninit_ptr()); + Inplace::init(this.transmute_uninit_ptr(), CSlice::default()) } /// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). @@ -56,7 +143,7 @@ pub unsafe extern "C" fn z_view_slice_from_str( str: *const c_char, ) { if str.is_null() { - z_view_slice_null(this) + z_view_slice_empty(this) } else { z_view_slice_wrap(this, str as *const u8, libc::strlen(str)) } @@ -70,34 +157,31 @@ pub unsafe extern "C" fn z_view_slice_wrap( start: *const u8, len: usize, ) { - if len == 0 { + if len == 0 || start.is_null() { z_view_slice_empty(this) - } else if start.is_null() { - z_view_slice_null(this) } else { - let slice: &'static [u8] = from_raw_parts(start, len); - Inplace::init(this.transmute_uninit_ptr(), Some(slice)) + Inplace::init( + this.transmute_uninit_ptr(), + CSlice::new_borrowed(start, len), + ) } } #[no_mangle] -pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_loaned_slice_t { - match this.transmute_ref() { - Some(s) => s.transmute_handle(), - None => null(), - } +pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> &z_loaned_slice_t { + this.transmute_ref().transmute_handle() } -/// Returns an empty `z_owned_slice_t` +/// Returns ``true`` if `this` is initialized. #[no_mangle] -pub extern "C" fn z_slice_empty(this: *mut MaybeUninit) { - let slice = Box::new([]); - Inplace::init(this.transmute_uninit_ptr(), Some(slice)) +pub extern "C" fn z_view_slice_check(this: &z_view_slice_t) -> bool { + !this.transmute_ref().is_empty() } +/// Returns an empty `z_owned_slice_t` #[no_mangle] -pub extern "C" fn z_slice_null(this: *mut MaybeUninit) { - Inplace::empty(this.transmute_uninit_ptr()); +pub extern "C" fn z_slice_empty(this: *mut MaybeUninit) { + Inplace::init(this.transmute_uninit_ptr(), CSlice::default()) } /// Copies a string into `z_owned_slice_t` using `strlen` (this should therefore not be used with untrusted inputs). @@ -110,7 +194,7 @@ pub unsafe extern "C" fn z_slice_from_str( str: *const c_char, ) { if str.is_null() { - z_slice_null(this) + z_slice_empty(this) } else { z_slice_wrap(this, str as *const u8, libc::strlen(str)) } @@ -124,13 +208,10 @@ pub unsafe extern "C" fn z_slice_wrap( start: *const u8, len: usize, ) { - if len == 0 { + if len == 0 || start.is_null() { z_slice_empty(this) - } else if start.is_null() { - z_slice_null(this) } else { - let slice = from_raw_parts(start, len).to_owned().into_boxed_slice(); - Inplace::init(this.transmute_uninit_ptr(), Some(slice)) + Inplace::init(this.transmute_uninit_ptr(), CSlice::new_owned(start, len)) } } @@ -143,29 +224,19 @@ pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { } #[no_mangle] -pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_loaned_slice_t { - match this.transmute_ref() { - Some(s) => (&s.as_ref()) as *const &[u8] as *const z_loaned_slice_t, - None => null(), - } +pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> &z_loaned_slice_t { + this.transmute_ref().transmute_handle() } #[no_mangle] pub extern "C" fn z_slice_clone(this: &z_loaned_slice_t, dst: *mut MaybeUninit) { - let slice = this.transmute_ref().to_vec().into_boxed_slice(); - Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); + Inplace::init(dst.transmute_uninit_ptr(), this.transmute_ref().clone()); } /// Returns ``true`` if `this` is initialized. #[no_mangle] pub extern "C" fn z_owned_slice_check(this: &z_owned_slice_t) -> bool { - this.transmute_ref().is_some() -} - -/// Returns ``true`` if `this` is initialized. -#[no_mangle] -pub extern "C" fn z_view_slice_check(this: &z_view_slice_t) -> bool { - this.transmute_ref().is_some() + !this.transmute_ref().is_empty() } #[no_mangle] @@ -175,16 +246,16 @@ pub extern "C" fn z_slice_len(this: &z_loaned_slice_t) -> usize { #[no_mangle] pub extern "C" fn z_slice_data(this: &z_loaned_slice_t) -> *const u8 { - this.transmute_ref().as_ptr() + this.transmute_ref().data() } pub use crate::opaque_types::z_loaned_str_t; pub use crate::opaque_types::z_owned_str_t; pub use crate::opaque_types::z_view_str_t; -decl_transmute_owned!(custom_inplace_init Option>, z_owned_str_t); -decl_transmute_owned!(custom_inplace_init Option<&'static [u8]>, z_view_str_t); -decl_transmute_handle!(&'static [u8], z_loaned_str_t); +decl_transmute_owned!(custom_inplace_init CSlice, z_owned_str_t); +decl_transmute_owned!(custom_inplace_init CSlice, z_view_str_t); +decl_transmute_handle!(CSlice, z_loaned_str_t); /// Frees `z_owned_str_t`, invalidating it for double-drop safety. #[no_mangle] @@ -202,13 +273,19 @@ pub extern "C" fn z_str_check(this: &z_owned_str_t) -> bool { /// Returns undefined `z_owned_str_t` #[no_mangle] pub extern "C" fn z_str_null(this: *mut MaybeUninit) { - z_slice_null(this as *mut _) + z_slice_empty(this as *mut _) +} + +/// Returns ``true`` if `s` is a valid string +#[no_mangle] +pub extern "C" fn z_view_str_check(this: &z_view_str_t) -> bool { + z_view_slice_check(this.transmute_ref().transmute_ref()) } /// Returns undefined `z_owned_str_t` #[no_mangle] pub extern "C" fn z_view_str_null(this: *mut MaybeUninit) { - z_slice_null(this as *mut _) + z_view_slice_empty(this as *mut _) } #[no_mangle] @@ -225,14 +302,28 @@ pub unsafe extern "C" fn z_view_str_empty(this: *mut MaybeUninit) /// Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_owned_str_t`. #[no_mangle] -pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> *const z_loaned_str_t { - z_slice_loan(this.transmute_ref().transmute_ref()) as _ +pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> Option<&z_loaned_str_t> { + if !z_str_check(this) { + return None; + } + Some( + z_slice_loan(this.transmute_ref().transmute_ref()) + .transmute_ref() + .transmute_handle(), + ) } /// Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_view_str_t`. #[no_mangle] -pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_loaned_str_t { - z_view_slice_loan(this.transmute_ref().transmute_ref()) as _ +pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> Option<&z_loaned_str_t> { + if !z_view_str_check(this) { + return None; + } + Some( + z_view_slice_loan(this.transmute_ref().transmute_ref()) + .transmute_ref() + .transmute_handle(), + ) } /// Copies a string into `z_owned_str_t` using `strlen` (this should therefore not be used with untrusted inputs). @@ -259,8 +350,7 @@ pub unsafe extern "C" fn z_str_from_substring( ) { let mut v = vec![0u8; len + 1]; v[0..len].copy_from_slice(from_raw_parts(str as *const u8, len)); - let b = v.into_boxed_slice(); - Inplace::init(this.transmute_uninit_ptr(), Some(b)); + Inplace::init(this.transmute_uninit_ptr(), v.into()); } /// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). @@ -287,8 +377,7 @@ pub extern "C" fn z_str_data(this: &z_loaned_str_t) -> *const libc::c_char { #[no_mangle] pub extern "C" fn z_str_clone(this: &z_loaned_str_t, dst: *mut MaybeUninit) { - let slice = this.transmute_ref().to_vec().into_boxed_slice(); - Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); + z_slice_clone(this.transmute_ref().transmute_handle(), dst as *mut _); } // returns string as slice (with null-terminating character) @@ -300,16 +389,13 @@ pub extern "C" fn z_str_as_slice(this: &z_loaned_str_t) -> &z_loaned_slice_t { pub use crate::opaque_types::z_loaned_slice_map_t; pub use crate::opaque_types::z_owned_slice_map_t; -pub type ZHashMap = HashMap, Cow<'static, [u8]>>; +pub type ZHashMap = HashMap; decl_transmute_handle!( - HashMap, Cow<'static, [u8]>>, + HashMap, z_loaned_slice_map_t ); -decl_transmute_owned!( - Option, Cow<'static, [u8]>>>, - z_owned_slice_map_t -); +decl_transmute_owned!(Option>, z_owned_slice_map_t); /// Constructs a new empty map. #[no_mangle] @@ -388,13 +474,7 @@ pub extern "C" fn z_slice_map_iterate( ) { let this = this.transmute_ref(); for (key, value) in this { - let key_slice = key.as_ref(); - let value_slice = value.as_ref(); - if body( - key_slice.transmute_handle(), - value_slice.transmute_handle(), - context, - ) { + if body(key.transmute_handle(), value.transmute_handle(), context) { break; } } @@ -407,13 +487,10 @@ pub extern "C" fn z_slice_map_iterate( pub extern "C" fn z_slice_map_get( this: &z_loaned_slice_map_t, key: &z_loaned_slice_t, -) -> *const z_loaned_slice_t { +) -> Option<&'static z_loaned_slice_t> { let m = this.transmute_ref(); - let key = *key.transmute_ref(); - let k = Cow::Borrowed(key); - m.get(&k) - .map(|s| s.as_ref().transmute_handle() as *const _) - .unwrap_or(null()) + let key = key.transmute_ref(); + m.get(key).map(|s| s.transmute_handle()) } /// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. @@ -426,9 +503,9 @@ pub extern "C" fn z_slice_map_insert_by_copy( value: &z_loaned_slice_t, ) -> u8 { let this = this.transmute_mut(); - let key = *key.transmute_ref(); - let value = *value.transmute_ref(); - match this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())) { + let key = key.transmute_ref(); + let value = value.transmute_ref(); + match this.insert(key.clone(), value.clone()) { Some(_) => 1, None => 0, } @@ -448,26 +525,19 @@ pub extern "C" fn z_slice_map_insert_by_alias( let this = this.transmute_mut(); let key = key.transmute_ref(); let value = value.transmute_ref(); - match this.insert(Cow::Borrowed(key), Cow::Borrowed(value)) { + match this.insert(key.shallow_copy(), value.shallow_copy()) { Some(_) => 1, None => 0, } } - -pub use crate::opaque_types::z_owned_slice_array_t; pub use crate::opaque_types::z_loaned_slice_array_t; +pub use crate::opaque_types::z_owned_slice_array_t; -pub type ZVector = Vec>; -decl_transmute_handle!( - Vec>, - z_loaned_slice_array_t -); +pub type ZVector = Vec; +decl_transmute_handle!(Vec, z_loaned_slice_array_t); -decl_transmute_owned!( - Option>>, - z_owned_slice_array_t -); +decl_transmute_owned!(Option>, z_owned_slice_array_t); /// Constructs a new empty array. #[no_mangle] @@ -528,7 +598,6 @@ pub extern "C" fn z_slice_array_is_empty(this: &z_loaned_slice_array_t) -> bool z_slice_array_len(this) == 0 } - /// Returns the value at the position of index in the array. /// /// Will return NULL if the index is out of bounds. @@ -536,13 +605,13 @@ pub extern "C" fn z_slice_array_is_empty(this: &z_loaned_slice_array_t) -> bool pub extern "C" fn z_slice_array_get( this: &z_loaned_slice_array_t, index: usize, -) -> *const z_loaned_slice_t { +) -> Option<&z_loaned_slice_t> { let a = this.transmute_ref(); if index >= a.len() { - return null(); + return None; } - a[index].as_ref().transmute_handle() as *const _ + Some(a[index].transmute_handle()) } /// Appends specified value to the end of the array by copying. @@ -554,8 +623,8 @@ pub extern "C" fn z_slice_array_push_by_copy( value: &z_loaned_slice_t, ) -> usize { let this = this.transmute_mut(); - let v = (*value.transmute_ref()).to_owned(); - this.push(Cow::Owned(v)); + let v = value.transmute_ref(); + this.push(v.clone()); this.len() } @@ -569,7 +638,8 @@ pub extern "C" fn z_slice_array_push_by_alias( value: &z_loaned_slice_t, ) -> usize { let this = this.transmute_mut(); - this.push(Cow::Borrowed(value.transmute_ref())); + let v = value.transmute_ref(); + this.push(v.shallow_copy()); this.len() -} \ No newline at end of file +} diff --git a/src/commons.rs b/src/commons.rs index d13b5b4d4..25311c0a9 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -281,7 +281,6 @@ decl_transmute_owned!(Value, z_owned_value_t); pub use crate::opaque_types::z_loaned_value_t; decl_transmute_handle!(Value, z_loaned_value_t); - #[no_mangle] pub extern "C" fn z_value_payload(this: &z_loaned_value_t) -> &z_loaned_bytes_t { this.transmute_ref().payload().transmute_handle() diff --git a/src/get.rs b/src/get.rs index 78f2d184e..e57a09a36 100644 --- a/src/get.rs +++ b/src/get.rs @@ -13,13 +13,13 @@ // use libc::c_char; -use zenoh::selector::Selector; use std::ffi::CStr; use std::mem::MaybeUninit; use std::ptr::null; use std::ptr::null_mut; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; +use zenoh::selector::Selector; use zenoh::prelude::{ConsolidationMode, QueryConsolidation, QueryTarget, Reply}; @@ -107,8 +107,9 @@ pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: /// Members: /// z_loaned_query_target_t target: The Queryables that should be target of the query. /// z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. -/// z_loaned_value_t value: An optional value to attach to the query. -/// z_loaned_bytes_t attachment: The attachment to attach to the query. +/// z_owned_payload_t* payload: An optional payload to attach to the query. +/// z_owned_encdoing_t* encdoing: An optional encoding of the query payload and or attachment. +/// z_owned_bytes_t attachment: The attachment to attach to the query. /// uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. #[repr(C)] pub struct z_get_options_t { @@ -175,14 +176,17 @@ pub unsafe extern "C" fn z_get( get = get.encoding(encoding); } if !options.attachment.is_null() { - let attachment = unsafe { *options.payload }.transmute_mut().extract(); + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); get = get.attachment(attachment); } get = get .consolidation(options.consolidation) - .timeout(std::time::Duration::from_millis(options.timeout_ms)) .target(options.target.into()); + + if options.timeout_ms != 0 { + get = get.timeout(std::time::Duration::from_millis(options.timeout_ms)); + } } match get .callback(move |response| z_closure_reply_call(&closure, response.transmute_handle())) @@ -209,7 +213,7 @@ pub extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { } #[no_mangle] -pub extern "C" fn z_reply_loan(this: & z_owned_reply_t) -> &z_loaned_reply_t { +pub extern "C" fn z_reply_loan(this: &z_owned_reply_t) -> &z_loaned_reply_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 75d25f977..30d516b77 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -367,7 +367,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice_unchecked( #[no_mangle] pub unsafe extern "C" fn z_view_keyexpr_unchecked( this: *mut MaybeUninit, - s: *const c_char + s: *const c_char, ) { z_view_keyexpr_from_slice_unchecked(this, s, libc::strlen(s)) } diff --git a/src/payload.rs b/src/payload.rs index d6d5920f2..31ee52779 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -4,7 +4,8 @@ use crate::transmute::{ TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{ - z_loaned_slice_map_t, z_loaned_slice_t, z_loaned_str_t, z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, ZHashMap + z_loaned_slice_map_t, z_loaned_slice_t, z_loaned_str_t, z_owned_slice_map_t, z_owned_slice_t, + z_owned_str_t, CSlice, ZHashMap, }; use core::fmt; use std::any::Any; @@ -84,8 +85,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( Inplace::empty(dst.transmute_uninit_ptr()); errors::Z_EPARSE } else { - let b = out.into_boxed_slice(); - Inplace::init(dst.transmute_uninit_ptr(), Some(b)); + Inplace::init(dst.transmute_uninit_ptr(), out.into()); errors::Z_OK } } @@ -118,8 +118,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes( let payload = payload.transmute_ref(); match payload.deserialize::>() { Ok(v) => { - let b = v.into_boxed_slice(); - Inplace::init(dst.transmute_uninit_ptr(), Some(b)); + Inplace::init(dst.transmute_uninit_ptr(), v.into()); errors::Z_OK } Err(e) => { @@ -136,13 +135,15 @@ unsafe impl Sync for z_loaned_slice_t {} impl fmt::Debug for z_loaned_slice_t { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = self.transmute_ref(); - f.debug_struct("z_loaned_slice_t").field("_0", s).finish() + f.debug_struct("z_loaned_slice_t") + .field("_0", &s.slice()) + .finish() } } impl ZSliceBuffer for z_loaned_slice_t { fn as_slice(&self) -> &[u8] { - self.transmute_ref() + self.transmute_ref().slice() } fn as_any(&self) -> &dyn Any { self @@ -174,7 +175,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_slice_map( ) { let dst = this.transmute_uninit_ptr(); let hm = bytes_map.transmute_ref(); - let payload = ZBytes::from_iter(hm.iter()); + let payload = ZBytes::from_iter(hm.iter().map(|(k, v)| (k.slice(), v.slice()))); Inplace::init(dst, Some(payload)); } @@ -186,9 +187,9 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( s: &z_loaned_str_t, ) { let s = s.transmute_ref(); - let ss = &s[0..s.len() - 1]; - let b = ss.transmute_handle(); - z_bytes_encode_from_slice(this, b); + let s_without_terminating_0 = &s.slice()[0..s.len() - 1]; + let s_without_terminating_0 = CSlice::new_borrowed_from_slice(s_without_terminating_0); + z_bytes_encode_from_slice(this, s_without_terminating_0.transmute_handle()); } pub use crate::opaque_types::z_owned_bytes_reader_t; diff --git a/src/queryable.rs b/src/queryable.rs index fd2589d3d..853743396 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -21,7 +21,7 @@ use crate::{ z_view_slice_wrap, }; use std::mem::MaybeUninit; -use std::ptr::{null, null_mut}; +use std::ptr::null_mut; use zenoh::prelude::SessionDeclarations; use zenoh::prelude::SyncResolve; use zenoh::prelude::{Query, Queryable}; @@ -265,32 +265,21 @@ pub unsafe extern "C" fn z_query_parameters( unsafe { z_view_slice_wrap(parameters, params.as_ptr(), params.len()) }; } -/// Checks if query contains a payload value. -#[no_mangle] -pub extern "C" fn z_query_has_value(query: &z_loaned_query_t) -> bool { - query.transmute_ref().value().is_some() -} - /// Gets a query's `payload value `_ by aliasing it. /// -/// **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** -/// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. +/// Returns NULL if query does not contain a value. #[no_mangle] -pub extern "C" fn z_query_value(query: &z_loaned_query_t) -> &z_loaned_value_t { - query - .transmute_ref() - .value() - .expect("Query does not contain a value") - .transmute_handle() +pub extern "C" fn z_query_value(query: &z_loaned_query_t) -> Option<&z_loaned_value_t> { + query.transmute_ref().value().map(|v| v.transmute_handle()) } /// Gets the attachment to the query by aliasing. /// /// Returns NULL if query does not contain an attachment. #[no_mangle] -pub extern "C" fn z_query_attachment(query: &z_loaned_query_t) -> *const z_loaned_bytes_t { - match query.transmute_ref().attachment() { - Some(attachment) => attachment.transmute_handle() as *const _, - None => null(), - } +pub extern "C" fn z_query_attachment(query: &z_loaned_query_t) -> Option<&z_loaned_bytes_t> { + query + .transmute_ref() + .attachment() + .map(|a| a.transmute_handle()) } diff --git a/src/scouting.rs b/src/scouting.rs index b13a4bd2f..52b4e2ae3 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -12,22 +12,28 @@ // ZettaScale Zenoh team, // use crate::{ - errors::{self, Z_OK}, transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}, z_closure_hello_call, z_config_check, z_config_clone, z_config_default, z_config_drop, z_config_null, z_id_t, z_loaned_config_t, z_owned_closure_hello_t, z_owned_config_t, z_owned_slice_array_t, zc_init_logger, CopyableToCArray, ZVector + errors::{self, Z_OK}, + transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, + TransmuteRef, TransmuteUninitPtr, + }, + z_closure_hello_call, z_config_check, z_config_clone, z_config_default, z_config_drop, + z_config_null, z_id_t, z_loaned_config_t, z_owned_closure_hello_t, z_owned_config_t, + z_owned_slice_array_t, zc_init_logger, CSlice, CopyableToCArray, ZVector, }; use async_std::task; use libc::{c_char, c_ulong}; -use std::{borrow::Cow, mem::MaybeUninit, os::raw::c_void}; +use std::{mem::MaybeUninit, os::raw::c_void}; use zenoh::scouting::Hello; use zenoh_protocol::core::{whatami::WhatAmIMatcher, WhatAmI}; use zenoh_util::core::AsyncResolve; -pub use crate::opaque_types::z_owned_hello_t; pub use crate::opaque_types::z_loaned_hello_t; +pub use crate::opaque_types::z_owned_hello_t; decl_transmute_owned!(Option, z_owned_hello_t); decl_transmute_handle!(Hello, z_loaned_hello_t); - /// Frees `hello`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -54,7 +60,6 @@ pub extern "C" fn z_hello_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } - #[no_mangle] pub extern "C" fn z_hello_zid(this: &z_loaned_hello_t) -> z_id_t { this.transmute_ref().zid.transmute_copy() @@ -66,14 +71,17 @@ pub extern "C" fn z_hello_whatami(this: &z_loaned_hello_t) -> u8 { } /// Returns an array of non-owned locators as an array of non-null terminated strings. -/// +/// /// The lifetime of locator strings is bound to `this`. #[no_mangle] -pub extern "C" fn z_hello_locators(this: &z_loaned_hello_t, locators_out: *mut MaybeUninit) { +pub extern "C" fn z_hello_locators( + this: &z_loaned_hello_t, + locators_out: *mut MaybeUninit, +) { let this = this.transmute_ref(); let mut locators = ZVector::with_capacity(this.locators.len()); for l in this.locators.iter() { - locators.push(Cow::Borrowed(l.as_str().as_bytes())); + locators.push(CSlice::new_borrowed_from_slice(l.as_str().as_bytes())); } Inplace::init(locators_out.transmute_uninit_ptr(), Some(locators)); } @@ -181,9 +189,7 @@ pub extern "C" fn z_scout( task::block_on(async move { let scout = zenoh::scout(what, config) - .callback(move |h| { - z_closure_hello_call(&closure, h.transmute_handle()) - }) + .callback(move |h| z_closure_hello_call(&closure, h.transmute_handle())) .res_async() .await .unwrap(); diff --git a/src/transmute.rs b/src/transmute.rs index 136069535..181b17e36 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -207,18 +207,22 @@ macro_rules! impl_transmute_handle { ($c_type:ty, $zenoh_type:ty) => { impl $crate::transmute::TransmuteFromHandle<$zenoh_type> for $c_type { fn transmute_ref(&self) -> &'static $zenoh_type { - unsafe { std::mem::transmute::<&$c_type, &'static $zenoh_type>(self) } + unsafe { + (self as *const Self as *const $zenoh_type) + .as_ref() + .unwrap() + } } fn transmute_mut(&mut self) -> &'static mut $zenoh_type { - unsafe { std::mem::transmute::<&mut $c_type, &'static mut $zenoh_type>(self) } + unsafe { (self as *mut Self as *mut $zenoh_type).as_mut().unwrap() } } } impl $crate::transmute::TransmuteIntoHandle<$c_type> for $zenoh_type { fn transmute_handle(&self) -> &'static $c_type { - unsafe { std::mem::transmute::<&$zenoh_type, &'static $c_type>(self) } + unsafe { (self as *const Self as *const $c_type).as_ref().unwrap() } } fn transmute_handle_mut(&mut self) -> &'static mut $c_type { - unsafe { std::mem::transmute::<&mut $zenoh_type, &'static mut $c_type>(self) } + unsafe { (self as *mut Self as *mut $c_type).as_mut().unwrap() } } } }; diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 7b18d7bd6..071718a37 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -118,21 +118,20 @@ int main(int argc, char **argv) { _Bool _ret_bool = z_view_keyexpr_check(&key_demo_example); assert(_ret_bool == true); - int8_t _ret_int; - _ret_int = z_keyexpr_includes(z_loan(key_demo_example_starstar), z_loan(key_demo_example_a)); - assert(_ret_int == 0); + _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_int == 0); #endif - _ret_int = z_keyexpr_intersects(z_loan(key_demo_example_starstar), z_loan(key_demo_example_a)); - assert(_ret_int == 0); + _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_int == 0); #endif - _ret_int = z_keyexpr_equals(z_loan(key_demo_example_starstar), z_loan(key_demo_example)); - assert(_ret_int == -1); + _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_int == -1); @@ -154,6 +153,7 @@ int main(int argc, char **argv) { _ret_int8 = z_keyexpr_canonize(keyexpr_str, &keyexpr_len); assert(_ret_int8 == 0); assert(strlen(URI) == keyexpr_len); + printf("keyexpr: %s", keyexpr_str); #ifdef ZENOH_PICO _ret_int8 = zp_keyexpr_canonize_null_terminated(keyexpr_str); assert(_ret_int8 == 0); diff --git a/tests/z_api_keyexpr_test.c b/tests/z_api_keyexpr_test.c index 02a6a886e..7cca679a7 100644 --- a/tests/z_api_keyexpr_test.c +++ b/tests/z_api_keyexpr_test.c @@ -68,8 +68,8 @@ void includes() { z_view_keyexpr_new(&foobar, "foo/bar"); z_view_keyexpr_new(&foostar, "foo/*"); - assert(z_keyexpr_includes(z_loan(foostar), z_loan(foobar)) == false); - assert(z_keyexpr_includes(z_loan(foobar), z_loan(foostar)) == true); + assert(z_keyexpr_includes(z_loan(foostar), z_loan(foobar)) == true); + assert(z_keyexpr_includes(z_loan(foobar), z_loan(foostar)) == false); } void intersects() { diff --git a/tests/z_api_map_test.c b/tests/z_api_map_test.c index c6e2f1545..079d848e5 100644 --- a/tests/z_api_map_test.c +++ b/tests/z_api_map_test.c @@ -44,7 +44,7 @@ void writting_by_alias_read_by_get() { const z_loaned_slice_t* a1 = z_slice_map_get(z_loan(map), z_loan(k1)); ASSERT_STR_SLICE_EQUAL("v1", a1); - const z_loaned_slice_t* a2 = z_slice_map_get(z_loan(map), z_loan(k1)); + const z_loaned_slice_t* a2 = z_slice_map_get(z_loan(map), z_loan(k2)); ASSERT_STR_SLICE_EQUAL("v2", a2); const z_loaned_slice_t* a_null = z_slice_map_get(z_loan(map), z_loan(k0)); diff --git a/tests/z_api_null_drop_test.c b/tests/z_api_null_drop_test.c index 47a65e3f8..2e65047de 100644 --- a/tests/z_api_null_drop_test.c +++ b/tests/z_api_null_drop_test.c @@ -60,8 +60,6 @@ int main(int argc, char **argv) { z_reply_channel_null(&reply_channel_null_1); z_owned_str_t str_null_1; z_str_null(&str_null_1); - z_owned_slice_t slice_null_1; - z_slice_null(&slice_null_1); z_owned_slice_map_t slice_map_null_1; z_slice_map_null(&slice_map_null_1); z_owned_bytes_t bytes_null_1; @@ -83,7 +81,6 @@ int main(int argc, char **argv) { assert(!z_check(reply_null_1)); assert(!z_check(hello_null_1)); assert(!z_check(str_null_1)); - assert(!z_check(slice_null_1)); assert(!z_check(slice_map_null_1)); assert(!z_check(bytes_null_1)); assert(!z_check(bytes_reader_null_1)); @@ -110,7 +107,6 @@ int main(int argc, char **argv) { z_owned_reply_channel_closure_t reply_channel_closure_null_2; z_owned_reply_channel_t reply_channel_null_2; z_owned_str_t str_null_2; - z_owned_slice_t slice_null_2; z_owned_slice_map_t slice_map_null_2; z_owned_bytes_t bytes_null_2; z_owned_bytes_reader_t bytes_reader_null_2; @@ -133,7 +129,6 @@ int main(int argc, char **argv) { z_null(&reply_channel_closure_null_2); z_null(&reply_channel_null_2); z_null(&str_null_2); - z_null(&slice_null_2); z_null(&slice_map_null_2); z_null(&bytes_null_2); z_null(&bytes_reader_null_2); @@ -152,7 +147,6 @@ int main(int argc, char **argv) { assert(!z_check(reply_null_2)); assert(!z_check(hello_null_2)); assert(!z_check(str_null_2)); - assert(!z_check(slice_null_2)); assert(!z_check(slice_map_null_2)); assert(!z_check(bytes_null_2)); assert(!z_check(bytes_reader_null_2)); @@ -179,7 +173,6 @@ int main(int argc, char **argv) { z_drop(z_move(reply_channel_closure_null_1)); z_drop(z_move(reply_channel_null_1)); z_drop(z_move(str_null_1)); - z_drop(z_move(slice_null_1)); z_drop(z_move(slice_map_null_1)); z_drop(z_move(bytes_null_1)); z_drop(z_move(bytes_reader_null_1)); @@ -203,7 +196,6 @@ int main(int argc, char **argv) { z_drop(z_move(reply_channel_closure_null_2)); z_drop(z_move(reply_channel_null_2)); z_drop(z_move(str_null_2)); - z_drop(z_move(slice_null_2)); z_drop(z_move(slice_map_null_2)); z_drop(z_move(bytes_null_2)); z_drop(z_move(bytes_reader_null_2)); diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c index 5734dbc69..90e17a92c 100644 --- a/tests/z_api_payload_test.c +++ b/tests/z_api_payload_test.c @@ -21,7 +21,7 @@ #undef NDEBUG #include -void test_reader() { +void test_reader_seek() { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; uint8_t data_out[10] = {0}; z_view_slice_t slice; @@ -29,25 +29,63 @@ void test_reader() { z_owned_bytes_t payload; z_bytes_encode_from_slice(&payload, z_loan(slice)); + z_owned_bytes_reader_t reader; z_bytes_reader_new(&reader, z_loan(payload)); assert(z_bytes_reader_tell(z_loan_mut(reader)) == 0); - z_bytes_reader_read(z_loan_mut(reader), data_out, 5); + assert(0 == z_bytes_reader_seek(z_loan_mut(reader), 5, SEEK_CUR)); assert(z_bytes_reader_tell(z_loan_mut(reader)) == 5); - z_bytes_reader_seek(z_loan_mut(reader), 2, SEEK_CUR); + + assert(0 == z_bytes_reader_seek(z_loan_mut(reader), 7, SEEK_SET)); assert(z_bytes_reader_tell(z_loan_mut(reader)) == 7); - z_bytes_reader_read(z_loan_mut(reader), data_out + 7, 2); + + assert(0 == z_bytes_reader_seek(z_loan_mut(reader), -1, SEEK_END)); + assert(z_bytes_reader_tell(z_loan_mut(reader)) == 9); + + assert(z_bytes_reader_seek(z_loan_mut(reader), 20, SEEK_SET) < 0); + + assert(0 == z_bytes_reader_seek(z_loan_mut(reader), 5, SEEK_SET)); + assert(z_bytes_reader_tell(z_loan_mut(reader)) == 5); + + assert(z_bytes_reader_seek(z_loan_mut(reader), 10, SEEK_CUR) < 0); + assert(z_bytes_reader_seek(z_loan_mut(reader), 10, SEEK_END) < 0); + assert(z_bytes_reader_seek(z_loan_mut(reader), -20, SEEK_END) < 0); + + z_drop(z_move(reader)); + z_drop(z_move(payload)); +} + +void test_reader_read() { + uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + uint8_t data_out[10] = {0}; + z_view_slice_t slice; + z_view_slice_wrap(&slice, data, 10); + + z_owned_bytes_t payload; + z_bytes_encode_from_slice(&payload, z_loan(slice)); + z_owned_bytes_reader_t reader; + z_bytes_reader_new(&reader, z_loan(payload)); + + assert(5 == z_bytes_reader_read(z_loan_mut(reader), data_out, 5)); + + z_bytes_reader_seek(z_loan_mut(reader), 2, SEEK_CUR); + assert(2 == z_bytes_reader_read(z_loan_mut(reader), data_out + 7, 2)); + z_bytes_reader_seek(z_loan_mut(reader), 5, SEEK_SET); - assert(z_bytes_reader_tell(z_loan_mut(reader)) == 7); - z_bytes_reader_read(z_loan_mut(reader), data_out + 5, 2); + assert(2 == z_bytes_reader_read(z_loan_mut(reader), data_out + 5, 2)); z_bytes_reader_seek(z_loan_mut(reader), -1, SEEK_END); - assert(z_bytes_reader_tell(z_loan_mut(reader)) == 9); - z_bytes_reader_read(z_loan_mut(reader), data_out + 9, 1); - assert(memcmp(data, data_out, 10)); + assert(1 == z_bytes_reader_read(z_loan_mut(reader), data_out + 9, 10)); + + assert(0 == z_bytes_reader_read(z_loan_mut(reader), data_out, 10)); + + assert(!memcmp(data, data_out, 10)); + + z_drop(z_move(reader)); + z_drop(z_move(payload)); } int main(int argc, char **argv) { - test_reader(); + test_reader_read(); } diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index 0753dbf8a..0c3242b8a 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -59,14 +59,17 @@ int run_publisher() { z_publisher_put_options_t options; z_publisher_put_options_default(&options); - z_owned_bytes_t attachment; - z_bytes_encode_from_slice_map(&attachment, z_loan(map)); - options.attachment = &attachment; + for (int i = 0; i < values_count; ++i) { z_view_slice_t k_var, v_var; z_view_slice_from_str(&k_var, K_VAR); z_view_slice_from_str(&v_var, values[i]); - z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_var), z_loan(v_var)); + z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_var), z_loan(v_var)); //value with the same key will be ovewritten + + z_owned_bytes_t attachment; + z_bytes_encode_from_slice_map(&attachment, z_loan(map)); + options.attachment = &attachment; + z_owned_bytes_t payload; z_bytes_encode_from_slice(&payload, z_loan(v_var)); z_publisher_put(z_loan(pub), z_move(payload), &options); @@ -108,7 +111,7 @@ void data_handler(const z_loaned_sample_t *sample, void *arg) { z_view_slice_t k_const, k_var; z_view_slice_from_str(&k_const, K_CONST); - z_view_slice_from_str(&k_var, K_CONST); + z_view_slice_from_str(&k_var, K_VAR); const z_loaned_slice_t* v_const = z_slice_map_get(z_loan(map), z_loan(k_const)); ASSERT_STR_SLICE_EQUAL(V_CONST, v_const); diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index c141bb068..7f702a913 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -55,7 +55,7 @@ void query_handler(const z_loaned_query_t *query, void *context) { ASSERT_STR_SLICE_EQUAL(V_CONST, v_const); const z_loaned_slice_t* v_var = z_slice_map_get(z_loan(map), z_loan(k_var)); - ASSERT_STR_SLICE_EQUAL(values[value_num], v_var); + ASSERT_STR_SLICE_EQUAL(values[value_num], v_var); z_owned_slice_map_t reply_map; z_slice_map_new(&reply_map); @@ -79,7 +79,7 @@ void query_handler(const z_loaned_query_t *query, void *context) { z_query_reply(query, z_loan(reply_ke), z_move(payload), &options); z_drop(z_move(keystr)); z_drop(z_move(map)); - z_drop(z_move(reply_map)); + // z_drop(z_move(reply_map)); if (++value_num == values_count) { exit(0); @@ -142,17 +142,18 @@ int run_get() { z_get_options_t opts; z_get_options_default(&opts); - z_owned_bytes_t attachment; - z_bytes_encode_from_slice_map(&attachment, z_loan(map)); - opts.attachment = &attachment; for (int val_num = 0; val_num < values_count; ++val_num) { z_view_slice_t v_var; z_view_slice_from_str(&v_var, values[val_num]); - z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_var), z_loan(v_var)); + z_slice_map_insert_by_copy(z_loan_mut(map), z_loan(k_var), z_loan(v_var)); // will overwrite any previous value for the same key z_owned_reply_channel_t channel; zc_reply_fifo_new(&channel, 16); + + z_owned_bytes_t attachment; + z_bytes_encode_from_slice_map(&attachment, z_loan(map)); + opts.attachment = &attachment; z_get(z_loan(s), z_loan(ke), "", z_move(channel.send), &opts); z_owned_reply_t reply; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { From 80b1be23de1b7528f3f2bac1a5be6797ca43b908 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 2 May 2024 19:03:26 +0200 Subject: [PATCH 068/377] create zenoh_macros.h if it is missing --- build.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.rs b/build.rs index d9610c7b4..a29179adb 100644 --- a/build.rs +++ b/build.rs @@ -763,6 +763,8 @@ pub fn create_generics_header(path_in: &str, path_out: &str) { .create(false) .write(true) .truncate(true) + .append(false) + .create(true) .open(path_out) .unwrap(); From dc5c631382f34007fa21b1390c4c3dc1311703b7 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 2 May 2024 19:07:41 +0200 Subject: [PATCH 069/377] clippy --- build.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/build.rs b/build.rs index a29179adb..2b53b51e7 100644 --- a/build.rs +++ b/build.rs @@ -760,7 +760,6 @@ pub struct FunctionSignature { pub fn create_generics_header(path_in: &str, path_out: &str) { let mut file_out = std::fs::File::options() .read(false) - .create(false) .write(true) .truncate(true) .append(false) From a74ce3ae0a1124c42456cd5a4c534aa73d6edcd5 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 10:13:31 +0200 Subject: [PATCH 070/377] update docs/api.rst; rename z_loaned_query_target -> z_query_target --- docs/api.rst | 122 +++++++++++++++++++++++----------- examples/z_non_blocking_get.c | 2 +- include/zenoh_commons.h | 40 +++++------ src/commons.rs | 24 +++---- src/get.rs | 6 +- src/querying_subscriber.rs | 8 +-- tests/z_api_alignment_test.c | 2 +- 7 files changed, 123 insertions(+), 81 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 7cdae18fe..cabb6ca5d 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -16,35 +16,86 @@ API Reference ************* -Generic types +Containers ============= -Bytes +Slice ----- +.. autocstruct:: zenoh_commons.h::z_view_slice_t +.. autocstruct:: zenoh_commons.h::z_owned_slice_t .. autocstruct:: zenoh_commons.h::z_loaned_slice_t -.. autocfunction:: zenoh_commons.h::z_slice_new +.. autocfunction:: zenoh_commons.h::z_slice_empty +.. autocfunction:: zenoh_commons.h::z_view_slice_empty +.. autocfunction:: zenoh_commons.h::z_slice_wrap +.. autocfunction:: zenoh_commons.h::z_view_slice_wrap +.. autocfunction:: zenoh_commons.h::z_slice_from_string .. autocfunction:: zenoh_commons.h::z_slice_check -.. autocfunction:: zenoh_commons.h::z_slice_null +.. autocfunction:: zenoh_commons.h::z_view_slice_check +.. autocfunction:: zenoh_commons.h::z_slice_drop +.. autocfunction:: zenoh_commons.h::z_view_slice_drop +.. autocfunction:: zenoh_commons.h::z_slice_loan +.. autocfunction:: zenoh_commons.h::z_view_slice_loan +.. autocfunction:: zenoh_commons.h::z_slice_data +.. autocfunction:: zenoh_commons.h::z_slice_len -Bytes map + +String +----- + +.. autocstruct:: zenoh_commons.h::z_view_str_t +.. autocstruct:: zenoh_commons.h::z_owned_str_t +.. autocstruct:: zenoh_commons.h::z_loaned_str_t + +.. autocfunction:: zenoh_commons.h::z_str_empty +.. autocfunction:: zenoh_commons.h::z_view_str_empty +.. autocfunction:: zenoh_commons.h::z_str_check +.. autocfunction:: zenoh_commons.h::z_view_str_check +.. autocfunction:: zenoh_commons.h::z_view_str_null +.. autocfunction:: zenoh_commons.h::z_str_null +.. autocfunction:: zenoh_commons.h::z_str_wrap +.. autocfunction:: zenoh_commons.h::z_view_str_wrap +.. autocfunction:: zenoh_commons.h::z_str_from_substring +.. autocfunction:: zenoh_commons.h::z_str_drop +.. autocfunction:: zenoh_commons.h::z_view_str_drop +.. autocfunction:: zenoh_commons.h::z_str_loan +.. autocfunction:: zenoh_commons.h::z_view_str_loan +.. autocfunction:: zenoh_commons.h::z_str_data +.. autocfunction:: zenoh_commons.h::z_str_len + +Slice map --------- -.. autocstruct:: zenoh_commons.h::z_owned_bytes_map_t +.. autocstruct:: zenoh_commons.h::z_owned_slice_map_t .. autocfunction:: zenoh_commons.h::z_slice_map_new .. autocfunction:: zenoh_commons.h::z_slice_map_check .. autocfunction:: zenoh_commons.h::z_slice_map_null .. autocfunction:: zenoh_commons.h::z_slice_map_drop +.. autocfunction:: zenoh_commons.h::z_slice_map_loan +.. autocfunction:: zenoh_commons.h::z_slice_map_loan_mut .. autocfunction:: zenoh_commons.h::z_slice_map_get .. autocfunction:: zenoh_commons.h::z_slice_map_len .. autocfunction:: zenoh_commons.h::z_slice_map_is_empty .. autocfunction:: zenoh_commons.h::z_slice_map_insert_by_alias .. autocfunction:: zenoh_commons.h::z_slice_map_insert_by_copy -.. autocfunction:: zenoh_commons.h::z_slice_map_iter -.. autocfunction:: zenoh_commons.h::z_slice_map_from_attachment -.. autocfunction:: zenoh_commons.h::z_slice_map_from_attachment_aliasing +.. autocfunction:: zenoh_commons.h::z_slice_map_iterate + +Slice array +--------- + +.. autocstruct:: zenoh_commons.h::z_owned_slice_array_t + +.. autocfunction:: zenoh_commons.h::z_slice_array_new +.. autocfunction:: zenoh_commons.h::z_slice_array_check +.. autocfunction:: zenoh_commons.h::z_slice_array_null +.. autocfunction:: zenoh_commons.h::z_slice_array_drop +.. autocfunction:: zenoh_commons.h::z_slice_array_loan +.. autocfunction:: zenoh_commons.h::z_slice_array_loan_mut +.. autocfunction:: zenoh_commons.h::z_slice_array_get +.. autocfunction:: zenoh_commons.h::z_slice_array_len +.. autocfunction:: zenoh_commons.h::z_slice_array_is_empty .. Scouting .. ======== @@ -70,6 +121,7 @@ Session configuration .. autocfunction:: zenoh_commons.h::zc_config_get .. autocfunction:: zenoh_commons.h::zc_config_to_string .. autocfunction:: zenoh_commons.h::z_config_loan +.. autocfunction:: zenoh_commons.h::z_config_loan_mut .. autocfunction:: zenoh_commons.h::z_config_check .. autocfunction:: zenoh_commons.h::z_config_drop @@ -104,31 +156,36 @@ Functions Key expression ============== +.. autocstruct:: zenoh_commons.h::z_view_keyexpr_t .. autocstruct:: zenoh_commons.h::z_loaned_keyexpr_t .. 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_new +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_new +.. autocfunction:: zenoh_commons.h::z_keyexpr_new_autocanonize +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_new_autocanonize +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_unchecked +.. autocfunction:: zenoh_commons.h::z_keyexpr_loan +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_loan +.. autocfunction:: zenoh_commons.h::z_keyexpr_check +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_check +.. autocfunction:: zenoh_commons.h::z_keyexpr_drop .. autocfunction:: zenoh_commons.h::z_keyexpr_to_string .. autocfunction:: zenoh_commons.h::z_keyexpr_as_slice .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize_null_terminated .. autocfunction:: zenoh_commons.h::z_keyexpr_is_canon -.. autocfunction:: zenoh_commons.h::z_keyexpr_is_initialized .. autocfunction:: zenoh_commons.h::z_keyexpr_concat .. autocfunction:: zenoh_commons.h::z_keyexpr_join .. autocfunction:: zenoh_commons.h::z_keyexpr_equals .. autocfunction:: zenoh_commons.h::z_keyexpr_includes .. 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 + + .. autocfunction:: zenoh_commons.h::z_declare_keyexpr +.. autocfunction:: zenoh_commons.h::z_undeclare_declare_keyexpr Encoding ======== @@ -148,30 +205,20 @@ Value ===== .. autocstruct:: zenoh_commons.h::z_loaned_value_t +.. autocstruct:: zenoh_commons.h::z_owned_value_t Sample ====== .. autocstruct:: zenoh_commons.h::z_loaned_sample_t - -Attachment -========== - -.. autocstruct:: zenoh_commons.h::z_attachment_t - -.. autocfunction:: zenoh_commons.h::z_attachment_null -.. autocfunction:: zenoh_commons.h::z_attachment_get -.. autocfunction:: zenoh_commons.h::z_attachment_len -.. autocfunction:: zenoh_commons.h::z_attachment_is_empty -.. autocfunction:: zenoh_commons.h::z_attachment_check -.. autocfunction:: zenoh_commons.h::z_attachment_iterate +.. autocstruct:: zenoh_commons.h::z_owned_sample_t Publication =========== Types ----- - +.. autocstruct:: zenoh_commons.h::z_loaned_publisher_t .. autocstruct:: zenoh_commons.h::z_owned_publisher_t .. autocstruct:: zenoh_commons.h::z_congestion_control_t @@ -188,7 +235,8 @@ Types Functions --------- -.. autocfunction:: zenoh_commons.h::z_put +.. autocfunction:: zenoh_commons.h:: +.. autocfunction:: zenoh_commons.h::z_delete .. autocfunction:: zenoh_commons.h::z_declare_publisher .. autocfunction:: zenoh_commons.h::z_publisher_put @@ -201,10 +249,9 @@ Subscription Types ----- +.. autocstruct:: zenoh_concrete.h::z_loaned_subscriber_t .. autocstruct:: zenoh_concrete.h::z_owned_subscriber_t -.. autocstruct:: zenoh_concrete.h::z_owned_pull_subscriber_t - .. autocstruct:: zenoh_commons.h::z_owned_closure_sample_t .. autocenum:: zenoh_commons.h::z_reliability_t @@ -219,11 +266,6 @@ Functions .. autocfunction:: zenoh_commons.h::z_subscriber_check .. autocfunction:: zenoh_commons.h::z_undeclare_subscriber -.. autocfunction:: zenoh_commons.h::z_declare_pull_subscriber -.. autocfunction:: zenoh_commons.h::z_subscriber_pull -.. autocfunction:: zenoh_commons.h::z_pull_subscriber_check -.. autocfunction:: zenoh_commons.h::z_undeclare_pull_subscriber - .. autocfunction:: zenoh_commons.h::z_closure_sample_call .. autocfunction:: zenoh_commons.h::z_closure_sample_drop @@ -237,7 +279,7 @@ Types .. autocstruct:: zenoh_commons.h::z_get_options_t -.. autocenum:: zenoh_commons.h::z_loaned_query_target_t +.. autocenum:: zenoh_commons.h::z_query_target_t .. autocenum:: zenoh_commons.h::z_consolidation_mode_t diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index 746fb2e7b..0d5e84642 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -48,7 +48,7 @@ int main(int argc, char **argv) { printf("Sending Query '%s'...\n", expr); z_get_options_t opts; z_get_options_default(&opts); - opts.target = Z_LOANED_QUERY_TARGET_ALL; + opts.target = Z_QUERY_TARGET_ALL; z_owned_reply_channel_t channel; zc_reply_non_blocking_fifo_new(&channel, 16); z_get(z_loan(s), z_loan(keyexpr), "", z_move(channel.send), diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index c581a9bde..a53aea5c2 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -59,18 +59,6 @@ typedef enum z_keyexpr_intersection_level_t { Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, } z_keyexpr_intersection_level_t; -/** - * The Queryables that should be target of a :c:func:`z_get`. - * - * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. - * - **ALL_COMPLETE**: All complete queryables. - * - **ALL**: All matching queryables. - */ -typedef enum z_loaned_query_target_t { - Z_LOANED_QUERY_TARGET_BEST_MATCHING, - Z_LOANED_QUERY_TARGET_ALL, - Z_LOANED_QUERY_TARGET_ALL_COMPLETE, -} z_loaned_query_target_t; /** * The priority of zenoh messages. * @@ -91,6 +79,18 @@ typedef enum z_priority_t { Z_PRIORITY_DATA_LOW = 6, Z_PRIORITY_BACKGROUND = 7, } z_priority_t; +/** + * The Queryables that should be target of a :c:func:`z_get`. + * + * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. + * - **ALL_COMPLETE**: All complete queryables. + * - **ALL**: All matching queryables. + */ +typedef enum z_query_target_t { + Z_QUERY_TARGET_BEST_MATCHING, + Z_QUERY_TARGET_ALL, + Z_QUERY_TARGET_ALL_COMPLETE, +} z_query_target_t; /** * The subscription reliability. * @@ -477,7 +477,7 @@ typedef struct z_query_consolidation_t { * Options passed to the :c:func:`z_get` function. * * Members: - * z_loaned_query_target_t target: The Queryables that should be target of the query. + * z_query_target_t target: The Queryables that should be target of the query. * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. * z_owned_payload_t* payload: An optional payload to attach to the query. * z_owned_encdoing_t* encdoing: An optional encoding of the query payload and or attachment. @@ -485,7 +485,7 @@ typedef struct z_query_consolidation_t { * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. */ typedef struct z_get_options_t { - enum z_loaned_query_target_t target; + enum z_query_target_t target; struct z_query_consolidation_t consolidation; struct z_owned_bytes_t *payload; struct z_owned_encoding_t *encoding; @@ -813,7 +813,7 @@ typedef struct ALIGN(8) ze_owned_querying_subscriber_t { * zcu_locality_t allowed_origin: The restriction for the matching publications that will be * receive by this subscriber. * z_loaned_keyexpr_t query_selector: The selector to be used for queries. - * z_loaned_query_target_t query_target: The target to be used for queries. + * z_query_target_t query_target: The target to be used for queries. * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. * uint64_t query_timeout_ms: The timeout to be used for queries. @@ -822,7 +822,7 @@ typedef struct ze_querying_subscriber_options_t { enum z_reliability_t reliability; enum zcu_locality_t allowed_origin; const struct z_loaned_keyexpr_t *query_selector; - enum z_loaned_query_target_t query_target; + enum z_query_target_t query_target; struct z_query_consolidation_t query_consolidation; enum zcu_reply_keyexpr_t query_accept_replies; uint64_t query_timeout_ms; @@ -1439,10 +1439,6 @@ enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_loaned_ */ ZENOHC_API void z_keyexpr_to_string(const struct z_loaned_keyexpr_t *ke, struct z_owned_str_t *s); ZENOHC_API z_error_t z_loaned_mutex_try_lock(struct z_loaned_mutex_t *this_); -/** - * Create a default :c:type:`z_loaned_query_target_t`. - */ -ZENOHC_API enum z_loaned_query_target_t z_loaned_query_target_default(void); /** * The samples timestamp * @@ -1675,6 +1671,10 @@ z_error_t z_query_reply(const struct z_loaned_query_t *query, * Constructs the default value for :c:type:`z_query_reply_options_t`. */ ZENOHC_API void z_query_reply_options_default(struct z_query_reply_options_t *this_); +/** + * Create a default :c:type:`z_query_target_t`. + */ +ZENOHC_API enum z_query_target_t z_query_target_default(void); /** * Gets a query's `payload value `_ by aliasing it. * diff --git a/src/commons.rs b/src/commons.rs index 25311c0a9..855a1c1cd 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -362,37 +362,37 @@ pub extern "C" fn zcu_reply_keyexpr_default() -> zcu_reply_keyexpr_t { #[allow(non_camel_case_types)] #[repr(C)] #[derive(Clone, Copy)] -pub enum z_loaned_query_target_t { +pub enum z_query_target_t { BEST_MATCHING, ALL, ALL_COMPLETE, } -impl From for z_loaned_query_target_t { +impl From for z_query_target_t { #[inline] fn from(t: QueryTarget) -> Self { match t { - QueryTarget::BestMatching => z_loaned_query_target_t::BEST_MATCHING, - QueryTarget::All => z_loaned_query_target_t::ALL, - QueryTarget::AllComplete => z_loaned_query_target_t::ALL_COMPLETE, + QueryTarget::BestMatching => z_query_target_t::BEST_MATCHING, + QueryTarget::All => z_query_target_t::ALL, + QueryTarget::AllComplete => z_query_target_t::ALL_COMPLETE, } } } -impl From for QueryTarget { +impl From for QueryTarget { #[inline] - fn from(val: z_loaned_query_target_t) -> Self { + fn from(val: z_query_target_t) -> Self { match val { - z_loaned_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, - z_loaned_query_target_t::ALL => QueryTarget::All, - z_loaned_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, + z_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, + z_query_target_t::ALL => QueryTarget::All, + z_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, } } } -/// Create a default :c:type:`z_loaned_query_target_t`. +/// Create a default :c:type:`z_query_target_t`. #[no_mangle] -pub extern "C" fn z_loaned_query_target_default() -> z_loaned_query_target_t { +pub extern "C" fn z_query_target_default() -> z_query_target_t { QueryTarget::default().into() } diff --git a/src/get.rs b/src/get.rs index e57a09a36..b620c93b3 100644 --- a/src/get.rs +++ b/src/get.rs @@ -31,7 +31,7 @@ use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; use crate::z_consolidation_mode_t; -use crate::z_loaned_query_target_t; +use crate::z_query_target_t; use crate::z_loaned_sample_t; use crate::z_loaned_value_t; use crate::z_owned_bytes_t; @@ -105,7 +105,7 @@ pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: /// Options passed to the :c:func:`z_get` function. /// /// Members: -/// z_loaned_query_target_t target: The Queryables that should be target of the query. +/// z_query_target_t target: The Queryables that should be target of the query. /// z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. /// z_owned_payload_t* payload: An optional payload to attach to the query. /// z_owned_encdoing_t* encdoing: An optional encoding of the query payload and or attachment. @@ -113,7 +113,7 @@ pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: /// uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. #[repr(C)] pub struct z_get_options_t { - pub target: z_loaned_query_target_t, + pub target: z_query_target_t, pub consolidation: z_query_consolidation_t, pub payload: *mut z_owned_bytes_t, pub encoding: *mut z_owned_encoding_t, diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index c1d180ecc..fb3ebdb57 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -26,7 +26,7 @@ use crate::z_loaned_keyexpr_t; use crate::z_owned_closure_sample_t; use crate::z_reliability_t; use crate::{ - z_closure_sample_call, z_get_options_t, z_loaned_query_target_default, z_loaned_query_target_t, + z_closure_sample_call, z_get_options_t, z_query_target_default, z_query_target_t, z_loaned_session_t, z_query_consolidation_none, z_query_consolidation_t, zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, }; @@ -65,7 +65,7 @@ pub extern "C" fn ze_querying_subscriber_null( /// zcu_locality_t allowed_origin: The restriction for the matching publications that will be /// receive by this subscriber. /// z_loaned_keyexpr_t query_selector: The selector to be used for queries. -/// z_loaned_query_target_t query_target: The target to be used for queries. +/// z_query_target_t query_target: The target to be used for queries. /// z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. /// zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. /// uint64_t query_timeout_ms: The timeout to be used for queries. @@ -75,7 +75,7 @@ pub struct ze_querying_subscriber_options_t { reliability: z_reliability_t, allowed_origin: zcu_locality_t, query_selector: *const z_loaned_keyexpr_t, - query_target: z_loaned_query_target_t, + query_target: z_query_target_t, query_consolidation: z_query_consolidation_t, query_accept_replies: zcu_reply_keyexpr_t, query_timeout_ms: u64, @@ -90,7 +90,7 @@ pub extern "C" fn ze_querying_subscriber_options_default( reliability: Reliability::DEFAULT.into(), allowed_origin: zcu_locality_default(), query_selector: null(), - query_target: z_loaned_query_target_default(), + query_target: z_query_target_default(), query_consolidation: z_query_consolidation_none(), query_accept_replies: zcu_reply_keyexpr_default(), query_timeout_ms: 0, diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 071718a37..023b0f16e 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -326,7 +326,7 @@ int main(int argc, char **argv) { z_closure(&_ret_closure_reply, reply_handler, NULL, &ls2); z_get_options_t _ret_get_opt; z_get_options_default(&_ret_get_opt); - _ret_get_opt.target = z_loaned_query_target_default(); + _ret_get_opt.target = z_query_target_default(); _ret_get_opt.consolidation = z_query_consolidation_auto(); _ret_get_opt.consolidation = z_query_consolidation_default(); _ret_get_opt.consolidation = z_query_consolidation_latest(); From e62568c584161b79f766797db7426a50f0521167 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 10:17:18 +0200 Subject: [PATCH 071/377] update docs/api.rst --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index cabb6ca5d..bcd345ec9 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -30,7 +30,7 @@ Slice .. autocfunction:: zenoh_commons.h::z_view_slice_empty .. autocfunction:: zenoh_commons.h::z_slice_wrap .. autocfunction:: zenoh_commons.h::z_view_slice_wrap -.. autocfunction:: zenoh_commons.h::z_slice_from_string +.. autocfunction:: zenoh_commons.h::z_slice_from_str .. autocfunction:: zenoh_commons.h::z_slice_check .. autocfunction:: zenoh_commons.h::z_view_slice_check .. autocfunction:: zenoh_commons.h::z_slice_drop From d860c28a5039124cdb256fcb708d6c934f0874cf Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 10:21:09 +0200 Subject: [PATCH 072/377] update docs/api.rst; fix z_slice_check name --- docs/api.rst | 1 - include/zenoh_commons.h | 8 ++++---- include/zenoh_macros.h | 2 -- src/collections.rs | 4 ++-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index bcd345ec9..0d5d48832 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -111,7 +111,6 @@ Session configuration .. autocstruct:: zenoh_commons.h::z_owned_config_t .. autocstruct:: zenoh_commons.h::z_owned_scouting_config_t -.. autocfunction:: zenoh_commons.h::z_config_new .. autocfunction:: zenoh_commons.h::z_config_default .. autocfunction:: zenoh_commons.h::z_config_client .. autocfunction:: zenoh_commons.h::z_config_peer diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index a53aea5c2..34a9e8283 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1461,10 +1461,6 @@ ZENOHC_API z_error_t z_mutex_unlock(struct z_loaned_mutex_t *this_); ZENOHC_API z_error_t z_open(struct z_owned_session_t *this_, struct z_owned_config_t *config); -/** - * Returns ``true`` if `this` is initialized. - */ -ZENOHC_API bool z_owned_slice_check(const struct z_owned_slice_t *this_); /** * Returns ``true`` if `pub` is valid. */ @@ -1913,6 +1909,10 @@ size_t z_slice_array_push_by_alias(struct z_loaned_slice_array_t *this_, ZENOHC_API size_t z_slice_array_push_by_copy(struct z_loaned_slice_array_t *this_, const struct z_loaned_slice_t *value); +/** + * Returns ``true`` if `this` is initialized. + */ +ZENOHC_API bool z_slice_checkck(const struct z_owned_slice_t *this_); ZENOHC_API void z_slice_clone(const struct z_loaned_slice_t *this_, struct z_owned_slice_t *dst); ZENOHC_API const uint8_t *z_slice_data(const struct z_loaned_slice_t *this_); /** diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index fe305cebc..13aac5e71 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -120,7 +120,6 @@ z_owned_hello_t : z_hello_check, \ z_owned_keyexpr_t : z_keyexpr_check, \ z_owned_mutex_t : z_mutex_check, \ - z_owned_slice_t : z_owned_slice_check, \ z_owned_publisher_t : z_publisher_check, \ z_owned_query_t : z_query_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -265,7 +264,6 @@ inline bool z_check(const z_owned_encoding_t& encoding) { return z_encoding_chec inline bool z_check(const z_owned_hello_t& this_) { return z_hello_check(&this_); }; inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; inline bool z_check(const z_owned_mutex_t& this_) { return z_mutex_check(&this_); }; -inline bool z_check(const z_owned_slice_t& this_) { return z_owned_slice_check(&this_); }; inline bool z_check(const z_owned_publisher_t& this_) { return z_publisher_check(&this_); }; inline bool z_check(const z_owned_query_t& query) { return z_query_check(&query); }; inline bool z_check(const z_owned_queryable_t& qable) { return z_queryable_check(&qable); }; diff --git a/src/collections.rs b/src/collections.rs index fa82b309c..f4649688a 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -235,7 +235,7 @@ pub extern "C" fn z_slice_clone(this: &z_loaned_slice_t, dst: *mut MaybeUninit bool { +pub extern "C" fn z_slice_checkck(this: &z_owned_slice_t) -> bool { !this.transmute_ref().is_empty() } @@ -267,7 +267,7 @@ pub unsafe extern "C" fn z_str_drop(this: &mut z_owned_str_t) { /// Returns ``true`` if `s` is a valid string #[no_mangle] pub extern "C" fn z_str_check(this: &z_owned_str_t) -> bool { - z_owned_slice_check(this.transmute_ref().transmute_ref()) + z_slice_checkck(this.transmute_ref().transmute_ref()) } /// Returns undefined `z_owned_str_t` From 8b77e565bedfa07dbd147183ff9d87f10d548292 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 10:23:32 +0200 Subject: [PATCH 073/377] fix z_slice_check name --- include/zenoh_commons.h | 2 +- include/zenoh_macros.h | 2 ++ src/collections.rs | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 34a9e8283..e43641462 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1912,7 +1912,7 @@ size_t z_slice_array_push_by_copy(struct z_loaned_slice_array_t *this_, /** * Returns ``true`` if `this` is initialized. */ -ZENOHC_API bool z_slice_checkck(const struct z_owned_slice_t *this_); +ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *this_); ZENOHC_API void z_slice_clone(const struct z_loaned_slice_t *this_, struct z_owned_slice_t *dst); ZENOHC_API const uint8_t *z_slice_data(const struct z_loaned_slice_t *this_); /** diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 13aac5e71..26d6f6ec2 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -128,6 +128,7 @@ z_owned_scouting_config_t : z_scouting_config_check, \ z_owned_session_t : z_session_check, \ z_owned_slice_array_t : z_slice_array_check, \ + z_owned_slice_t : z_slice_check, \ z_owned_slice_map_t : z_slice_map_check, \ z_owned_str_t : z_str_check, \ z_owned_subscriber_t : z_subscriber_check, \ @@ -272,6 +273,7 @@ inline bool z_check(const z_owned_sample_t& sample) { return z_sample_check(&sam inline bool z_check(const z_owned_scouting_config_t& config) { return z_scouting_config_check(&config); }; inline bool z_check(const z_owned_session_t& this_) { return z_session_check(&this_); }; inline bool z_check(const z_owned_slice_array_t& this_) { return z_slice_array_check(&this_); }; +inline bool z_check(const z_owned_slice_t& this_) { return z_slice_check(&this_); }; inline bool z_check(const z_owned_slice_map_t& map) { return z_slice_map_check(&map); }; inline bool z_check(const z_owned_str_t& this_) { return z_str_check(&this_); }; inline bool z_check(const z_owned_subscriber_t& subscriber) { return z_subscriber_check(&subscriber); }; diff --git a/src/collections.rs b/src/collections.rs index f4649688a..4a67ffc2a 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -235,7 +235,7 @@ pub extern "C" fn z_slice_clone(this: &z_loaned_slice_t, dst: *mut MaybeUninit bool { +pub extern "C" fn z_slice_check(this: &z_owned_slice_t) -> bool { !this.transmute_ref().is_empty() } @@ -267,7 +267,7 @@ pub unsafe extern "C" fn z_str_drop(this: &mut z_owned_str_t) { /// Returns ``true`` if `s` is a valid string #[no_mangle] pub extern "C" fn z_str_check(this: &z_owned_str_t) -> bool { - z_slice_checkck(this.transmute_ref().transmute_ref()) + z_slice_check(this.transmute_ref().transmute_ref()) } /// Returns undefined `z_owned_str_t` From 749bc44a3cf5c43ba1ea7193d312dfaebc463066 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 10:26:19 +0200 Subject: [PATCH 074/377] remove non-exisiting z_view_slice_drop and z_view_str_drop from docs --- docs/api.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 0d5d48832..72659249b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -34,7 +34,6 @@ Slice .. autocfunction:: zenoh_commons.h::z_slice_check .. autocfunction:: zenoh_commons.h::z_view_slice_check .. autocfunction:: zenoh_commons.h::z_slice_drop -.. autocfunction:: zenoh_commons.h::z_view_slice_drop .. autocfunction:: zenoh_commons.h::z_slice_loan .. autocfunction:: zenoh_commons.h::z_view_slice_loan .. autocfunction:: zenoh_commons.h::z_slice_data @@ -58,7 +57,6 @@ String .. autocfunction:: zenoh_commons.h::z_view_str_wrap .. autocfunction:: zenoh_commons.h::z_str_from_substring .. autocfunction:: zenoh_commons.h::z_str_drop -.. autocfunction:: zenoh_commons.h::z_view_str_drop .. autocfunction:: zenoh_commons.h::z_str_loan .. autocfunction:: zenoh_commons.h::z_view_str_loan .. autocfunction:: zenoh_commons.h::z_str_data From 2133e42a8b60af29ed0e7dbae78575714afe64f7 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 10:30:36 +0200 Subject: [PATCH 075/377] fix z_str_len --- include/zenoh_commons.h | 2 +- src/collections.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index e43641462..fae7c14be 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -2016,6 +2016,7 @@ ZENOHC_API void z_str_empty(struct z_owned_str_t *this_); * Calling this with `str == NULL` is equivalent to `z_str_null`. */ ZENOHC_API void z_str_from_substring(struct z_owned_str_t *this_, const char *str, size_t len); +ZENOHC_API size_t z_str_len(const struct z_loaned_str_t *this_); /** * Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_owned_str_t`. */ @@ -2194,7 +2195,6 @@ ZENOHC_API void z_view_slice_wrap(struct z_view_slice_t *this_, const uint8_t *s */ ZENOHC_API bool z_view_str_check(const struct z_view_str_t *this_); ZENOHC_API void z_view_str_empty(struct z_view_str_t *this_); -ZENOHC_API size_t z_view_str_len(const struct z_loaned_str_t *this_); /** * Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_view_str_t`. */ diff --git a/src/collections.rs b/src/collections.rs index 4a67ffc2a..34e36c30c 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -366,8 +366,8 @@ pub unsafe extern "C" fn z_view_str_wrap( } #[no_mangle] -pub extern "C" fn z_view_str_len(this: &z_loaned_str_t) -> usize { - z_slice_len(this.transmute_ref().transmute_handle()) - 1 +pub extern "C" fn z_str_len(this: &z_loaned_str_t) -> usize { + z_slice_len(this.transmute_ref().transmute_handle()).max(1) - 1 } #[no_mangle] From dbccc30cf1aae81e32161e832c0b454431764167 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 10:32:25 +0200 Subject: [PATCH 076/377] fix docs/api.rst --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index 72659249b..0e61a27f3 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -182,7 +182,7 @@ Key expression .. autocfunction:: zenoh_commons.h::z_declare_keyexpr -.. autocfunction:: zenoh_commons.h::z_undeclare_declare_keyexpr +.. autocfunction:: zenoh_commons.h::z_undeclare_keyexpr Encoding ======== From 3bed72f5350990baa7ed8a8f1eb7685454471df2 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 10:37:11 +0200 Subject: [PATCH 077/377] fix encoding --- docs/api.rst | 2 -- include/zenoh_commons.h | 4 ++-- src/commons.rs | 9 +++++---- src/get.rs | 2 +- src/querying_subscriber.rs | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 0e61a27f3..6d76843d7 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -196,8 +196,6 @@ Encoding .. autocfunction:: zenoh_commons.h::z_encoding_check .. autocfunction:: zenoh_commons.h::z_encoding_drop -.. autocstruct:: zenoh_commons.h::z_encoding_prefix_t - Value ===== diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index fae7c14be..b38c3c2a1 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1229,7 +1229,7 @@ ZENOHC_API void z_delete_options_default(struct z_delete_options_t *this_); */ ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); /** - * Constructs a default :c:type:`z_loaned_encoding_t`. + * Returns a default :c:type:`z_loaned_encoding_t`. */ ZENOHC_API const struct z_loaned_encoding_t *z_encoding_default(void); /** @@ -1239,7 +1239,7 @@ ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); /** * Constructs a specific :c:type:`z_loaned_encoding_t`. */ -ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); +ZENOHC_API z_error_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); /** * Returns a :c:type:`z_loaned_encoding_t` loaned from `encoding`. */ diff --git a/src/commons.rs b/src/commons.rs index 855a1c1cd..a56a8dae7 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -17,6 +17,7 @@ use std::mem::MaybeUninit; use std::ptr::null; use std::str::FromStr; +use crate::errors; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::TransmuteCopy; @@ -235,20 +236,20 @@ pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit pub unsafe extern "C" fn z_encoding_from_str( encoding: *mut MaybeUninit, s: *const c_char, -) -> i8 { +) -> errors::z_error_t { let encoding = encoding.transmute_uninit_ptr(); if s.is_null() { Inplace::empty(encoding); - 0 + errors::Z_OK } else { let s = CStr::from_ptr(s).to_string_lossy(); let value = Encoding::from_str(s.as_ref()).unwrap_infallible(); Inplace::init(encoding, value); - 0 + errors::Z_OK } } -/// Constructs a default :c:type:`z_loaned_encoding_t`. +/// Returns a default :c:type:`z_loaned_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> &'static z_loaned_encoding_t { diff --git a/src/get.rs b/src/get.rs index b620c93b3..8ef975343 100644 --- a/src/get.rs +++ b/src/get.rs @@ -31,11 +31,11 @@ use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; use crate::z_consolidation_mode_t; -use crate::z_query_target_t; use crate::z_loaned_sample_t; use crate::z_loaned_value_t; use crate::z_owned_bytes_t; use crate::z_owned_encoding_t; +use crate::z_query_target_t; use crate::{ z_closure_reply_call, z_loaned_keyexpr_t, z_loaned_session_t, z_owned_closure_reply_t, }; diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index fb3ebdb57..bd9554217 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -26,8 +26,8 @@ use crate::z_loaned_keyexpr_t; use crate::z_owned_closure_sample_t; use crate::z_reliability_t; use crate::{ - z_closure_sample_call, z_get_options_t, z_query_target_default, z_query_target_t, - z_loaned_session_t, z_query_consolidation_none, z_query_consolidation_t, zcu_locality_default, + z_closure_sample_call, z_get_options_t, z_loaned_session_t, z_query_consolidation_none, + z_query_consolidation_t, z_query_target_default, z_query_target_t, zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, }; use zenoh::prelude::sync::SyncResolve; From bd33ce7b05497c3bcd87ea261e219094afbf043f Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 11:03:36 +0200 Subject: [PATCH 078/377] docs build --- include/zenoh_commons.h | 36 ------------------------------------ include/zenoh_concrete.h | 36 ++++++++++++++++++++++++++++++++++++ splitguide.yaml | 4 ++++ 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index b38c3c2a1..60674b721 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -661,9 +661,6 @@ typedef struct ALIGN(8) z_loaned_slice_array_t { typedef bool (*z_slice_map_iter_body_t)(const struct z_loaned_slice_t *key, const struct z_loaned_slice_t *value, void *context); -typedef struct ALIGN(8) z_loaned_subscriber_t { - uint8_t _0[32]; -} z_loaned_subscriber_t; typedef struct ALIGN(8) z_owned_task_t { uint8_t _0[24]; } z_owned_task_t; @@ -756,21 +753,6 @@ typedef struct zcu_owned_closure_matching_status_t { typedef struct ALIGN(8) zcu_owned_matching_listener_t { uint8_t _0[40]; } zcu_owned_matching_listener_t; -/** - * An owned zenoh publication_cache. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) ze_owned_publication_cache_t { - uint8_t _0[96]; -} ze_owned_publication_cache_t; /** * Options passed to the :c:func:`ze_declare_publication_cache` function. * @@ -789,21 +771,6 @@ typedef struct ze_publication_cache_options_t { size_t history; size_t resources_limit; } ze_publication_cache_options_t; -/** - * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) ze_owned_querying_subscriber_t { - uint8_t _0[64]; -} ze_owned_querying_subscriber_t; /** * Represents the set of options that can be applied to a querying subscriber, * upon its declaration via :c:func:`ze_declare_querying_subscriber`. @@ -827,9 +794,6 @@ typedef struct ze_querying_subscriber_options_t { enum zcu_reply_keyexpr_t query_accept_replies; uint64_t query_timeout_ms; } ze_querying_subscriber_options_t; -typedef struct ALIGN(8) ze_loaned_querying_subscriber_t { - uint8_t _0[64]; -} ze_loaned_querying_subscriber_t; ZENOHC_API extern const unsigned int Z_ROUTER; ZENOHC_API extern const unsigned int Z_PEER; ZENOHC_API extern const unsigned int Z_CLIENT; diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index f9f91304e..7c4d34675 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -72,6 +72,42 @@ typedef struct ALIGN(8) z_owned_queryable_t { typedef struct ALIGN(8) z_owned_subscriber_t { uint8_t _0[32]; } z_owned_subscriber_t; +typedef struct ALIGN(8) z_loaned_subscriber_t { + uint8_t _0[32]; +} z_loaned_subscriber_t; +/** + * An owned zenoh publication_cache. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_publication_cache_t { + uint8_t _0[96]; +} ze_owned_publication_cache_t; +/** + * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. + * + * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_querying_subscriber_t { + uint8_t _0[64]; +} ze_owned_querying_subscriber_t; +typedef struct ALIGN(8) ze_loaned_querying_subscriber_t { + uint8_t _0[64]; +} ze_loaned_querying_subscriber_t; #define Z_OK 0 #define Z_EINVAL -1 #define Z_EPARSE -2 diff --git a/splitguide.yaml b/splitguide.yaml index 6614c0356..74de0c903 100644 --- a/splitguide.yaml +++ b/splitguide.yaml @@ -9,5 +9,9 @@ zenoh_concrete.h: - z_owned_session_t! - z_loaned_session_t! - z_owned_subscriber_t! + - z_loaned_subscriber_t! - z_loaned_query_t! - z_owned_queryable_t! + - ze_owned_publication_cache_t! + - ze_owned_querying_subscriber_t! + - ze_loaned_querying_subscriber_t! From e6f8eb9d4bdb48a3f795f8cca44af9e8604838e9 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 11:07:49 +0200 Subject: [PATCH 079/377] docs/api.rst --- docs/api.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 6d76843d7..99c60297c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -41,7 +41,7 @@ Slice String ------ +------ .. autocstruct:: zenoh_commons.h::z_view_str_t .. autocstruct:: zenoh_commons.h::z_owned_str_t @@ -81,7 +81,7 @@ Slice map .. autocfunction:: zenoh_commons.h::z_slice_map_iterate Slice array ---------- +----------- .. autocstruct:: zenoh_commons.h::z_owned_slice_array_t @@ -200,7 +200,6 @@ Value ===== .. autocstruct:: zenoh_commons.h::z_loaned_value_t -.. autocstruct:: zenoh_commons.h::z_owned_value_t Sample ====== @@ -230,7 +229,7 @@ Types Functions --------- -.. autocfunction:: zenoh_commons.h:: +.. autocfunction:: zenoh_commons.h::z_put .. autocfunction:: zenoh_commons.h::z_delete .. autocfunction:: zenoh_commons.h::z_declare_publisher @@ -292,6 +291,9 @@ Types .. autocfunction:: zenoh_commons.h::z_query_consolidation_latest .. autocstruct:: zenoh_commons.h::z_owned_reply_t +.. autocstruct:: zenoh_commons.h::z_loaned_reply_t +.. autocstruct:: zenoh_commons.h::z_owned_query_t +.. autocstruct:: zenoh_commons.h::z_loaned_query_t .. autocfunction:: zenoh_commons.h::z_reply_check .. autocfunction:: zenoh_commons.h::z_reply_drop @@ -341,9 +343,9 @@ Types ----- .. autocstruct:: zenoh_commons.h::zc_owned_liveliness_token_t -.. autocstruct:: zenoh_commons.h::zc_owned_liveliness_declaration_options_t +.. autocstruct:: zenoh_commons.h::zc_liveliness_declaration_options_t .. autocstruct:: zenoh_commons.h::zc_liveliness_get_options_t -.. autocstruct:: zenoh_commons.h::zc_owned_liveliness_declare_subscriber_options_t +.. autocstruct:: zenoh_commons.h::zc_liveliness_declare_subscriber_options_t Functions --------- @@ -363,7 +365,7 @@ Types ----- .. autocstruct:: zenoh_commons.h::ze_publication_cache_options_t -.. autocstruct:: zenoh_commons.h::ze_owned_publication_cache_t +.. autocstruct:: zenoh_concrete.h::ze_owned_publication_cache_t Functions --------- @@ -380,7 +382,8 @@ Querying Subscriber Types ----- -.. autocstruct:: zenoh_commons.h::ze_owned_querying_subscriber_t +.. autocstruct:: zenoh_concrete.h::ze_owned_querying_subscriber_t +.. autocstruct:: zenoh_concrete.h::ze_loaned_querying_subscriber_t .. autocstruct:: zenoh_commons.h::ze_querying_subscriber_options_t Functions From 63fff2f5ecdc14c9a5920f872b13670c71b810bf Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 3 May 2024 18:06:46 +0200 Subject: [PATCH 080/377] refactoring of macros-generation code to reduce amount of copy/paste --- build.rs | 294 ++++++++++++++++-------------------- include/zenoh_macros.h | 336 ++++++++++++++++++++--------------------- 2 files changed, 299 insertions(+), 331 deletions(-) diff --git a/build.rs b/build.rs index 2b53b51e7..f45603a93 100644 --- a/build.rs +++ b/build.rs @@ -737,24 +737,47 @@ impl<'a> Iterator for Tokenizer<'a> { #[derive(Clone, Debug)] pub struct FuncArg { typename: String, - cv: String, name: String, } impl FuncArg { - pub fn new(typename: &str, cv: &str, name: &str) -> Self { + pub fn new(typename: &str, name: &str) -> Self { FuncArg { typename: typename.to_owned(), - cv: cv.to_owned(), name: name.to_owned(), } } + + pub fn without_cv(self) -> Self { + FuncArg { + typename: self.typename.replace("const ", ""), + name: self.name, + } + } + + pub fn without_ptr(self) -> Self { + FuncArg { + typename: self.typename.replace(['*', '&'], ""), + name: self.name, + } + } + + pub fn with_ref(self) -> Self { + FuncArg { + typename: self.typename.replace('*', "&"), + name: self.name, + } + } + + pub fn decay(self) -> Self { + self.without_cv().without_ptr() + } } #[derive(Clone, Debug)] pub struct FunctionSignature { return_type: String, func_name: String, - arg_type_and_name: Vec, + args: Vec, } pub fn create_generics_header(path_in: &str, path_out: &str) { @@ -856,9 +879,12 @@ pub fn find_loan_functions(path_in: &str) -> Vec { re.captures_iter(&bindings).map(|c| c.extract()) { let f = FunctionSignature { - return_type: return_type.to_string(), + return_type: "const ".to_string() + return_type + "*", func_name: func_name.to_string() + "_loan", - arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), + args: vec![FuncArg::new( + &("const ".to_string() + arg_type + "*"), + arg_name, + )], }; res.push(f); } @@ -874,9 +900,9 @@ pub fn find_loan_mut_functions(path_in: &str) -> Vec { re.captures_iter(&bindings).map(|c| c.extract()) { let f = FunctionSignature { - return_type: return_type.to_string(), + return_type: return_type.to_string() + "*", func_name: func_name.to_string() + "_loan_mut", - arg_type_and_name: [FuncArg::new(arg_type, "", arg_name)].to_vec(), + args: vec![FuncArg::new(&(arg_type.to_string() + "*"), arg_name)], }; res.push(f); } @@ -892,7 +918,7 @@ pub fn find_drop_functions(path_in: &str) -> Vec { let f = FunctionSignature { return_type: "void".to_string(), func_name: func_name.to_string() + "_drop", - arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), + args: vec![FuncArg::new(&(arg_type.to_string() + "*"), arg_name)], }; res.push(f); } @@ -908,7 +934,7 @@ pub fn find_null_functions(path_in: &str) -> Vec { let f = FunctionSignature { return_type: "void".to_string(), func_name: func_name.to_string() + "_null", - arg_type_and_name: [FuncArg::new(arg_type, "", arg_name)].to_vec(), + args: vec![FuncArg::new(&(arg_type.to_string() + "*"), arg_name)], }; res.push(f); } @@ -924,7 +950,10 @@ pub fn find_check_functions(path_in: &str) -> Vec { let f = FunctionSignature { return_type: "bool".to_string(), func_name: func_name.to_string() + "_check", - arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), + args: vec![FuncArg::new( + &("const ".to_string() + arg_type + "*"), + arg_name, + )], }; res.push(f); } @@ -942,115 +971,85 @@ pub fn find_call_functions(path_in: &str) -> Vec { for (_, [return_type, func_name, closure_type, closure_name, arg_cv, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { + let arg_cv: String = if arg_cv.is_empty() { + "".to_string() + } else { + "const ".to_string() + }; let f = FunctionSignature { return_type: return_type.to_string(), func_name: func_name.to_string() + "_call", - arg_type_and_name: [ - FuncArg::new(closure_type, "const", closure_name), - FuncArg::new(arg_type, arg_cv, arg_name), - ] - .to_vec(), + args: vec![ + FuncArg::new(&("const ".to_string() + closure_type + "*"), closure_name), + FuncArg::new(&(arg_cv + arg_type + "*"), arg_name), + ], }; res.push(f); } res } -pub fn generate_generic_loan_c(macro_func: &[FunctionSignature]) -> String { - let mut out = "#define z_loan(x) \\ +pub fn generate_generic_c( + macro_func: &[FunctionSignature], + generic_name: &str, + decay: bool, +) -> String { + let va_args = macro_func.iter().any(|f| f.args.len() > 1); + let mut out = if va_args { + format!( + "#define {generic_name}(x, ...) \\ _Generic((x)" - .to_owned(); + ) + } else { + format!( + "#define {generic_name}(x) \\ + _Generic((x)" + ) + }; + + let x = if decay { "&x" } else { "x" }; for func in macro_func { - let owned_type = &func.arg_type_and_name[0].typename; + let owned_type = if decay { + func.args[0].clone().decay().typename + } else { + func.args[0].clone().typename + }; let func_name = &func.func_name; out += ", \\\n"; out += &format!(" {owned_type} : {func_name}"); } out += " \\\n"; - out += " )(&x)"; + if va_args { + out += &format!(" )({x}, __VA_ARGS__)"); + } else { + out += &format!(" )({x})"); + } out } -pub fn generate_generic_loan_mut_c(macro_func: &[FunctionSignature]) -> String { - let mut out = "#define z_loan_mut(x) \\ - _Generic((x)" - .to_owned(); +pub fn generate_generic_loan_c(macro_func: &[FunctionSignature]) -> String { + generate_generic_c(macro_func, "z_loan", true) +} - for func in macro_func { - let owned_type = &func.arg_type_and_name[0].typename; - let func_name = &func.func_name; - out += ", \\\n"; - out += &format!(" {owned_type} : {func_name}"); - } - out += " \\\n"; - out += " )(&x)"; - out +pub fn generate_generic_loan_mut_c(macro_func: &[FunctionSignature]) -> String { + generate_generic_c(macro_func, "z_loan_mut", true) } pub fn generate_generic_drop_c(macro_func: &[FunctionSignature]) -> String { - let mut out = "#define z_drop(x) \\ - _Generic((x)" - .to_owned(); - - for func in macro_func { - let owned_type = &func.arg_type_and_name[0].typename; - let func_name = &func.func_name; - out += ",\\\n"; - out += &format!(" {owned_type} * : {func_name}"); - } - out += " \\\n"; - out += " )(x)"; - out + generate_generic_c(macro_func, "z_drop", false) } pub fn generate_generic_null_c(macro_func: &[FunctionSignature]) -> String { - let mut out = "#define z_null(x) \\ - _Generic((x)" - .to_owned(); - - for func in macro_func { - let owned_type = &func.arg_type_and_name[0].typename; - let func_name = &func.func_name; - out += ", \\\n"; - out += &format!(" {owned_type} * : {func_name}"); - } - out += " \\\n"; - out += " )(x)"; - out + generate_generic_c(macro_func, "z_null", false) } pub fn generate_generic_check_c(macro_func: &[FunctionSignature]) -> String { - let mut out = "#define z_check(x) \\ - _Generic((x)" - .to_owned(); - - for func in macro_func { - let owned_type = &func.arg_type_and_name[0].typename; - let func_name = &func.func_name; - out += ", \\\n"; - out += &format!(" {owned_type} : {func_name}"); - } - out += " \\\n"; - out += " )(&x)"; - out + generate_generic_c(macro_func, "z_check", true) } pub fn generate_generic_call_c(macro_func: &[FunctionSignature]) -> String { - let mut out = "#define z_call(x, ...) \\ - _Generic((x)" - .to_owned(); - - for func in macro_func { - let func_name = &func.func_name; - let owned_type = &func.arg_type_and_name[0].typename; - out += ", \\\n"; - out += &format!(" {owned_type} : {func_name}"); - } - out += " \\\n"; - out += " )(&x, __VA_ARGS__)"; - - out + generate_generic_c(macro_func, "z_call", true) } pub fn generate_generic_closure_c(_macro_func: &[FunctionSignature]) -> String { @@ -1059,99 +1058,69 @@ pub fn generate_generic_closure_c(_macro_func: &[FunctionSignature]) -> String { .to_owned() } -pub fn generate_generic_loan_cpp(macro_func: &[FunctionSignature]) -> String { +pub fn generate_generic_cpp( + macro_func: &[FunctionSignature], + generic_name: &str, + decay: bool, +) -> String { let mut out = "".to_owned(); + let (body_start, body_end) = if macro_func.iter().any(|f| f.args.len() > 1) { + ("\n ", "\n") + } else { + (" ", " ") + }; + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; - let cv = &func.arg_type_and_name[0].cv; - let arg_name = &func.arg_type_and_name[0].name; - let arg_type = &func.arg_type_and_name[0].typename; + let arg_name = &func.args[0].name; + let arg_type = if decay { + func.args[0].clone().with_ref().typename + } else { + func.args[0].clone().typename + }; + let x = if decay { + "&".to_string() + arg_name + } else { + arg_name.to_owned() + }; out += "\n"; - out += &format!("inline const {return_type}* z_loan({cv} {arg_type}* {arg_name}) {{ return {func_name}({arg_name}); }};"); + out += &format!("inline {return_type} {generic_name}({arg_type} {arg_name}"); + for i in 1..func.args.len() { + out += &format!(", {} {}", func.args[i].typename, func.args[i].name); + } + out += &format!(") {{{body_start}return {func_name}({x}"); + for i in 1..func.args.len() { + out += &format!(", {}", func.args[i].name); + } + out += &format!(");{body_end}}};"); } out } -pub fn generate_generic_loan_mut_cpp(macro_func: &[FunctionSignature]) -> String { - let mut out = "".to_owned(); +pub fn generate_generic_loan_cpp(macro_func: &[FunctionSignature]) -> String { + generate_generic_cpp(macro_func, "z_loan", true) +} - for func in macro_func { - let func_name = &func.func_name; - let return_type = &func.return_type; - let cv = &func.arg_type_and_name[0].cv; - let arg_name = &func.arg_type_and_name[0].name; - let arg_type = &func.arg_type_and_name[0].typename; - out += "\n"; - out += &format!("inline {return_type}* z_loan_mut({cv} {arg_type}& {arg_name}) {{ return {func_name}(&{arg_name}); }};"); - } - out +pub fn generate_generic_loan_mut_cpp(macro_func: &[FunctionSignature]) -> String { + generate_generic_cpp(macro_func, "z_loan_mut", true) } pub fn generate_generic_drop_cpp(macro_func: &[FunctionSignature]) -> String { - let mut out = "".to_owned(); - - for func in macro_func { - let func_name = &func.func_name; - let return_type = &func.return_type; - let cv = &func.arg_type_and_name[0].cv; - let arg_name = &func.arg_type_and_name[0].name; - let arg_type = &func.arg_type_and_name[0].typename; - out += "\n"; - out += &format!("inline {return_type} z_drop({cv} {arg_type}* {arg_name}) {{ return {func_name}({arg_name}); }};"); - } - out + generate_generic_cpp(macro_func, "z_drop", false) } pub fn generate_generic_null_cpp(macro_func: &[FunctionSignature]) -> String { - let mut out = "".to_owned(); - - for func in macro_func { - let func_name = &func.func_name; - let return_type = &func.return_type; - let cv = &func.arg_type_and_name[0].cv; - let arg_name = &func.arg_type_and_name[0].name; - let arg_type = &func.arg_type_and_name[0].typename; - out += "\n"; - out += &format!("inline {return_type} z_null({cv} {arg_type}* {arg_name}) {{ return {func_name}({arg_name}); }};"); - } - out + generate_generic_cpp(macro_func, "z_null", false) } pub fn generate_generic_check_cpp(macro_func: &[FunctionSignature]) -> String { - let mut out = "".to_owned(); - - for func in macro_func { - let func_name = &func.func_name; - let return_type = &func.return_type; - let cv = &func.arg_type_and_name[0].cv; - let arg_name = &func.arg_type_and_name[0].name; - let arg_type = &func.arg_type_and_name[0].typename; - out += "\n"; - out += &format!("inline {return_type} z_check({cv} {arg_type}& {arg_name}) {{ return {func_name}(&{arg_name}); }};"); - } - out + generate_generic_cpp(macro_func, "z_check", true) } pub fn generate_generic_call_cpp(macro_func: &[FunctionSignature]) -> String { - let mut out = "".to_owned(); - - for func in macro_func { - let func_name = &func.func_name; - let return_type = &func.return_type; - let closure_cv = &func.arg_type_and_name[0].cv; - let closure_name = &func.arg_type_and_name[0].name; - let closure_type = &func.arg_type_and_name[0].typename; - let arg_cv = &func.arg_type_and_name[1].cv; - let arg_name = &func.arg_type_and_name[1].name; - let arg_type = &func.arg_type_and_name[1].typename; - out += "\n"; - out += &format!("inline {return_type} z_call({closure_cv} {closure_type}& {closure_name}, {arg_cv} {arg_type}* {arg_name}) {{ - return {func_name}(&{closure_name}, {arg_name}); -}};"); - } - out + generate_generic_cpp(macro_func, "z_call", true) } pub fn generate_generic_closure_cpp(macro_func: &[FunctionSignature]) -> String { @@ -1159,15 +1128,14 @@ pub fn generate_generic_closure_cpp(macro_func: &[FunctionSignature]) -> String for func in macro_func { let return_type = &func.return_type; - let closure_name = &func.arg_type_and_name[0].name; - let closure_type = &func.arg_type_and_name[0].typename; - let arg_cv = &func.arg_type_and_name[1].cv; - let arg_type = &func.arg_type_and_name[1].typename; + let closure_name = &func.args[0].name; + let closure_type = func.args[0].clone().without_cv().typename; + let arg_type = &func.args[1].typename; out += "\n"; out += &format!( "inline void z_closure( - {closure_type}* {closure_name}, - {return_type} (*call)({arg_cv} {arg_type}*, void*), + {closure_type} {closure_name}, + {return_type} (*call)({arg_type}, void*), void (*drop)(void*), void *context) {{ {closure_name}->context = context; diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 26d6f6ec2..68c5e91e5 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -41,73 +41,73 @@ )(&x) #define z_drop(x) \ - _Generic((x),\ - z_owned_bytes_t * : z_bytes_drop,\ - z_owned_bytes_reader_t * : z_bytes_reader_drop,\ - z_owned_closure_hello_t * : z_closure_hello_drop,\ - z_owned_closure_owned_query_t * : z_closure_owned_query_drop,\ - z_owned_closure_query_t * : z_closure_query_drop,\ - z_owned_closure_reply_t * : z_closure_reply_drop,\ - z_owned_closure_sample_t * : z_closure_sample_drop,\ - z_owned_closure_zid_t * : z_closure_zid_drop,\ - z_owned_condvar_t * : z_condvar_drop,\ - z_owned_config_t * : z_config_drop,\ - z_owned_encoding_t * : z_encoding_drop,\ - z_owned_hello_t * : z_hello_drop,\ - z_owned_keyexpr_t * : z_keyexpr_drop,\ - z_owned_mutex_t * : z_mutex_drop,\ - z_owned_query_channel_closure_t * : z_query_channel_closure_drop,\ - z_owned_query_channel_t * : z_query_channel_drop,\ - z_owned_query_t * : z_query_drop,\ - z_owned_reply_channel_closure_t * : z_reply_channel_closure_drop,\ - z_owned_reply_channel_t * : z_reply_channel_drop,\ - z_owned_reply_t * : z_reply_drop,\ - z_owned_sample_t * : z_sample_drop,\ - z_owned_scouting_config_t * : z_scouting_config_drop,\ - z_owned_slice_array_t * : z_slice_array_drop,\ - z_owned_slice_t * : z_slice_drop,\ - z_owned_slice_map_t * : z_slice_map_drop,\ - z_owned_str_t * : z_str_drop,\ - zc_owned_liveliness_token_t * : zc_liveliness_token_drop,\ - zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop \ + _Generic((x), \ + z_owned_bytes_t* : z_bytes_drop, \ + z_owned_bytes_reader_t* : z_bytes_reader_drop, \ + z_owned_closure_hello_t* : z_closure_hello_drop, \ + z_owned_closure_owned_query_t* : z_closure_owned_query_drop, \ + z_owned_closure_query_t* : z_closure_query_drop, \ + z_owned_closure_reply_t* : z_closure_reply_drop, \ + z_owned_closure_sample_t* : z_closure_sample_drop, \ + z_owned_closure_zid_t* : z_closure_zid_drop, \ + z_owned_condvar_t* : z_condvar_drop, \ + z_owned_config_t* : z_config_drop, \ + z_owned_encoding_t* : z_encoding_drop, \ + z_owned_hello_t* : z_hello_drop, \ + z_owned_keyexpr_t* : z_keyexpr_drop, \ + z_owned_mutex_t* : z_mutex_drop, \ + z_owned_query_channel_closure_t* : z_query_channel_closure_drop, \ + z_owned_query_channel_t* : z_query_channel_drop, \ + z_owned_query_t* : z_query_drop, \ + z_owned_reply_channel_closure_t* : z_reply_channel_closure_drop, \ + z_owned_reply_channel_t* : z_reply_channel_drop, \ + z_owned_reply_t* : z_reply_drop, \ + z_owned_sample_t* : z_sample_drop, \ + z_owned_scouting_config_t* : z_scouting_config_drop, \ + z_owned_slice_array_t* : z_slice_array_drop, \ + z_owned_slice_t* : z_slice_drop, \ + z_owned_slice_map_t* : z_slice_map_drop, \ + z_owned_str_t* : z_str_drop, \ + zc_owned_liveliness_token_t* : zc_liveliness_token_drop, \ + zcu_owned_closure_matching_status_t* : zcu_closure_matching_status_drop \ )(x) #define z_null(x) \ _Generic((x), \ - z_owned_bytes_t * : z_bytes_null, \ - z_owned_bytes_reader_t * : z_bytes_reader_null, \ - z_owned_closure_hello_t * : z_closure_hello_null, \ - z_owned_closure_query_t * : z_closure_query_null, \ - z_owned_closure_reply_t * : z_closure_reply_null, \ - z_owned_closure_sample_t * : z_closure_sample_null, \ - z_owned_closure_zid_t * : z_closure_zid_null, \ - z_owned_condvar_t * : z_condvar_null, \ - z_owned_config_t * : z_config_null, \ - z_owned_encoding_t * : z_encoding_null, \ - z_owned_hello_t * : z_hello_null, \ - z_owned_keyexpr_t * : z_keyexpr_null, \ - z_owned_mutex_t * : z_mutex_null, \ - z_owned_publisher_t * : z_publisher_null, \ - z_owned_query_channel_closure_t * : z_query_channel_closure_null, \ - z_owned_query_t * : z_query_null, \ - z_owned_queryable_t * : z_queryable_null, \ - z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ - z_owned_reply_channel_t * : z_reply_channel_null, \ - z_owned_reply_t * : z_reply_null, \ - z_owned_sample_t * : z_sample_null, \ - z_owned_scouting_config_t * : z_scouting_config_null, \ - z_owned_session_t * : z_session_null, \ - z_owned_slice_array_t * : z_slice_array_null, \ - z_owned_slice_map_t * : z_slice_map_null, \ - z_owned_str_t * : z_str_null, \ - z_owned_subscriber_t * : z_subscriber_null, \ - z_owned_task_t * : z_task_null, \ - z_view_keyexpr_t * : z_view_keyexpr_null, \ - z_view_str_t * : z_view_str_null, \ - zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ - zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ - ze_owned_publication_cache_t * : ze_publication_cache_null, \ - ze_owned_querying_subscriber_t * : ze_querying_subscriber_null \ + z_owned_bytes_t* : z_bytes_null, \ + z_owned_bytes_reader_t* : z_bytes_reader_null, \ + z_owned_closure_hello_t* : z_closure_hello_null, \ + z_owned_closure_query_t* : z_closure_query_null, \ + z_owned_closure_reply_t* : z_closure_reply_null, \ + z_owned_closure_sample_t* : z_closure_sample_null, \ + z_owned_closure_zid_t* : z_closure_zid_null, \ + z_owned_condvar_t* : z_condvar_null, \ + z_owned_config_t* : z_config_null, \ + z_owned_encoding_t* : z_encoding_null, \ + z_owned_hello_t* : z_hello_null, \ + z_owned_keyexpr_t* : z_keyexpr_null, \ + z_owned_mutex_t* : z_mutex_null, \ + z_owned_publisher_t* : z_publisher_null, \ + z_owned_query_channel_closure_t* : z_query_channel_closure_null, \ + z_owned_query_t* : z_query_null, \ + z_owned_queryable_t* : z_queryable_null, \ + z_owned_reply_channel_closure_t* : z_reply_channel_closure_null, \ + z_owned_reply_channel_t* : z_reply_channel_null, \ + z_owned_reply_t* : z_reply_null, \ + z_owned_sample_t* : z_sample_null, \ + z_owned_scouting_config_t* : z_scouting_config_null, \ + z_owned_session_t* : z_session_null, \ + z_owned_slice_array_t* : z_slice_array_null, \ + z_owned_slice_map_t* : z_slice_map_null, \ + z_owned_str_t* : z_str_null, \ + z_owned_subscriber_t* : z_subscriber_null, \ + z_owned_task_t* : z_task_null, \ + z_view_keyexpr_t* : z_view_keyexpr_null, \ + z_view_str_t* : z_view_str_null, \ + zc_owned_liveliness_token_t* : zc_liveliness_token_null, \ + zcu_owned_closure_matching_status_t* : zcu_closure_matching_status_null, \ + ze_owned_publication_cache_t* : ze_publication_cache_null, \ + ze_owned_querying_subscriber_t* : ze_querying_subscriber_null \ )(x) #define z_check(x) \ @@ -142,7 +142,7 @@ )(&x) #define z_call(x, ...) \ - _Generic((x), \ + _Generic((x), \ z_owned_closure_hello_t : z_closure_hello_call, \ z_owned_closure_owned_query_t : z_closure_owned_query_call, \ z_owned_closure_query_t : z_closure_query_call, \ @@ -160,101 +160,101 @@ -inline const z_loaned_bytes_t* z_loan(const z_owned_bytes_t* payload) { return z_bytes_loan(payload); }; -inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t* reader) { return z_bytes_reader_loan(reader); }; -inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t* this_) { return z_condvar_loan(this_); }; -inline const z_loaned_config_t* z_loan(const z_owned_config_t* this_) { return z_config_loan(this_); }; -inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* encoding) { return z_encoding_loan(encoding); }; -inline const z_loaned_hello_t* z_loan(const z_owned_hello_t* this_) { return z_hello_loan(this_); }; -inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t* key_expr) { return z_keyexpr_loan(key_expr); }; -inline const z_loaned_publisher_t* z_loan(const z_owned_publisher_t* this_) { return z_publisher_loan(this_); }; -inline const z_loaned_query_t* z_loan(const z_owned_query_t* this_) { return z_query_loan(this_); }; -inline const z_loaned_reply_t* z_loan(const z_owned_reply_t* this_) { return z_reply_loan(this_); }; -inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* sample) { return z_sample_loan(sample); }; -inline const z_loaned_session_t* z_loan(const z_owned_session_t* this_) { return z_session_loan(this_); }; -inline const z_loaned_slice_array_t* z_loan(const z_owned_slice_array_t* this_) { return z_slice_array_loan(this_); }; -inline const z_loaned_slice_t* z_loan(const z_owned_slice_t* this_) { return z_slice_loan(this_); }; -inline const z_loaned_slice_map_t* z_loan(const z_owned_slice_map_t* this_) { return z_slice_map_loan(this_); }; -inline const z_loaned_str_t* z_loan(const z_owned_str_t* this_) { return z_str_loan(this_); }; -inline const z_loaned_subscriber_t* z_loan(const z_owned_subscriber_t* this_) { return z_subscriber_loan(this_); }; -inline const z_loaned_keyexpr_t* z_loan(const z_view_keyexpr_t* key_expr) { return z_view_keyexpr_loan(key_expr); }; -inline const z_loaned_slice_t* z_loan(const z_view_slice_t* this_) { return z_view_slice_loan(this_); }; -inline const z_loaned_str_t* z_loan(const z_view_str_t* this_) { return z_view_str_loan(this_); }; -inline const ze_loaned_querying_subscriber_t* z_loan(const ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_loan(this_); }; +inline const z_loaned_bytes_t* z_loan(const z_owned_bytes_t& payload) { return z_bytes_loan(&payload); }; +inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t& reader) { return z_bytes_reader_loan(&reader); }; +inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t& this_) { return z_condvar_loan(&this_); }; +inline const z_loaned_config_t* z_loan(const z_owned_config_t& this_) { return z_config_loan(&this_); }; +inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t& encoding) { return z_encoding_loan(&encoding); }; +inline const z_loaned_hello_t* z_loan(const z_owned_hello_t& this_) { return z_hello_loan(&this_); }; +inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t& key_expr) { return z_keyexpr_loan(&key_expr); }; +inline const z_loaned_publisher_t* z_loan(const z_owned_publisher_t& this_) { return z_publisher_loan(&this_); }; +inline const z_loaned_query_t* z_loan(const z_owned_query_t& this_) { return z_query_loan(&this_); }; +inline const z_loaned_reply_t* z_loan(const z_owned_reply_t& this_) { return z_reply_loan(&this_); }; +inline const z_loaned_sample_t* z_loan(const z_owned_sample_t& sample) { return z_sample_loan(&sample); }; +inline const z_loaned_session_t* z_loan(const z_owned_session_t& this_) { return z_session_loan(&this_); }; +inline const z_loaned_slice_array_t* z_loan(const z_owned_slice_array_t& this_) { return z_slice_array_loan(&this_); }; +inline const z_loaned_slice_t* z_loan(const z_owned_slice_t& this_) { return z_slice_loan(&this_); }; +inline const z_loaned_slice_map_t* z_loan(const z_owned_slice_map_t& this_) { return z_slice_map_loan(&this_); }; +inline const z_loaned_str_t* z_loan(const z_owned_str_t& this_) { return z_str_loan(&this_); }; +inline const z_loaned_subscriber_t* z_loan(const z_owned_subscriber_t& this_) { return z_subscriber_loan(&this_); }; +inline const z_loaned_keyexpr_t* z_loan(const z_view_keyexpr_t& key_expr) { return z_view_keyexpr_loan(&key_expr); }; +inline const z_loaned_slice_t* z_loan(const z_view_slice_t& this_) { return z_view_slice_loan(&this_); }; +inline const z_loaned_str_t* z_loan(const z_view_str_t& this_) { return z_view_str_loan(&this_); }; +inline const ze_loaned_querying_subscriber_t* z_loan(const ze_owned_querying_subscriber_t& this_) { return ze_querying_subscriber_loan(&this_); }; -inline z_loaned_bytes_reader_t* z_loan_mut( z_owned_bytes_reader_t& reader) { return z_bytes_reader_loan_mut(&reader); }; -inline z_loaned_condvar_t* z_loan_mut( z_owned_condvar_t& this_) { return z_condvar_loan_mut(&this_); }; -inline z_loaned_config_t* z_loan_mut( z_owned_config_t& this_) { return z_config_loan_mut(&this_); }; -inline z_loaned_mutex_t* z_loan_mut( z_owned_mutex_t& this_) { return z_mutex_loan_mut(&this_); }; -inline z_loaned_slice_array_t* z_loan_mut( z_owned_slice_array_t& this_) { return z_slice_array_loan_mut(&this_); }; -inline z_loaned_slice_map_t* z_loan_mut( z_owned_slice_map_t& this_) { return z_slice_map_loan_mut(&this_); }; +inline z_loaned_bytes_reader_t* z_loan_mut(z_owned_bytes_reader_t& reader) { return z_bytes_reader_loan_mut(&reader); }; +inline z_loaned_condvar_t* z_loan_mut(z_owned_condvar_t& this_) { return z_condvar_loan_mut(&this_); }; +inline z_loaned_config_t* z_loan_mut(z_owned_config_t& this_) { return z_config_loan_mut(&this_); }; +inline z_loaned_mutex_t* z_loan_mut(z_owned_mutex_t& this_) { return z_mutex_loan_mut(&this_); }; +inline z_loaned_slice_array_t* z_loan_mut(z_owned_slice_array_t& this_) { return z_slice_array_loan_mut(&this_); }; +inline z_loaned_slice_map_t* z_loan_mut(z_owned_slice_map_t& this_) { return z_slice_map_loan_mut(&this_); }; -inline void z_drop(const z_owned_bytes_t* this_) { return z_bytes_drop(this_); }; -inline void z_drop(const z_owned_bytes_reader_t* this_) { return z_bytes_reader_drop(this_); }; -inline void z_drop(const z_owned_closure_hello_t* closure) { return z_closure_hello_drop(closure); }; -inline void z_drop(const z_owned_closure_owned_query_t* closure) { return z_closure_owned_query_drop(closure); }; -inline void z_drop(const z_owned_closure_query_t* closure) { return z_closure_query_drop(closure); }; -inline void z_drop(const z_owned_closure_reply_t* closure) { return z_closure_reply_drop(closure); }; -inline void z_drop(const z_owned_closure_sample_t* closure) { return z_closure_sample_drop(closure); }; -inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; -inline void z_drop(const z_owned_condvar_t* this_) { return z_condvar_drop(this_); }; -inline void z_drop(const z_owned_config_t* config) { return z_config_drop(config); }; -inline void z_drop(const z_owned_encoding_t* encoding) { return z_encoding_drop(encoding); }; -inline void z_drop(const z_owned_hello_t* this_) { return z_hello_drop(this_); }; -inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; -inline void z_drop(const z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; -inline void z_drop(const z_owned_query_channel_closure_t* closure) { return z_query_channel_closure_drop(closure); }; -inline void z_drop(const z_owned_query_channel_t* channel) { return z_query_channel_drop(channel); }; -inline void z_drop(const z_owned_query_t* this_) { return z_query_drop(this_); }; -inline void z_drop(const z_owned_reply_channel_closure_t* closure) { return z_reply_channel_closure_drop(closure); }; -inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_channel_drop(channel); }; -inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; -inline void z_drop(const z_owned_sample_t* sample) { return z_sample_drop(sample); }; -inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; -inline void z_drop(const z_owned_slice_array_t* this_) { return z_slice_array_drop(this_); }; -inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; -inline void z_drop(const z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; -inline void z_drop(const z_owned_str_t* this_) { return z_str_drop(this_); }; -inline void z_drop(const zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_drop(this_); }; -inline void z_drop(const zcu_owned_closure_matching_status_t* closure) { return zcu_closure_matching_status_drop(closure); }; +inline void z_drop(z_owned_bytes_t* this_) { return z_bytes_drop(this_); }; +inline void z_drop(z_owned_bytes_reader_t* this_) { return z_bytes_reader_drop(this_); }; +inline void z_drop(z_owned_closure_hello_t* closure) { return z_closure_hello_drop(closure); }; +inline void z_drop(z_owned_closure_owned_query_t* closure) { return z_closure_owned_query_drop(closure); }; +inline void z_drop(z_owned_closure_query_t* closure) { return z_closure_query_drop(closure); }; +inline void z_drop(z_owned_closure_reply_t* closure) { return z_closure_reply_drop(closure); }; +inline void z_drop(z_owned_closure_sample_t* closure) { return z_closure_sample_drop(closure); }; +inline void z_drop(z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; +inline void z_drop(z_owned_condvar_t* this_) { return z_condvar_drop(this_); }; +inline void z_drop(z_owned_config_t* config) { return z_config_drop(config); }; +inline void z_drop(z_owned_encoding_t* encoding) { return z_encoding_drop(encoding); }; +inline void z_drop(z_owned_hello_t* this_) { return z_hello_drop(this_); }; +inline void z_drop(z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; +inline void z_drop(z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; +inline void z_drop(z_owned_query_channel_closure_t* closure) { return z_query_channel_closure_drop(closure); }; +inline void z_drop(z_owned_query_channel_t* channel) { return z_query_channel_drop(channel); }; +inline void z_drop(z_owned_query_t* this_) { return z_query_drop(this_); }; +inline void z_drop(z_owned_reply_channel_closure_t* closure) { return z_reply_channel_closure_drop(closure); }; +inline void z_drop(z_owned_reply_channel_t* channel) { return z_reply_channel_drop(channel); }; +inline void z_drop(z_owned_reply_t* this_) { return z_reply_drop(this_); }; +inline void z_drop(z_owned_sample_t* sample) { return z_sample_drop(sample); }; +inline void z_drop(z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; +inline void z_drop(z_owned_slice_array_t* this_) { return z_slice_array_drop(this_); }; +inline void z_drop(z_owned_slice_t* this_) { return z_slice_drop(this_); }; +inline void z_drop(z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; +inline void z_drop(z_owned_str_t* this_) { return z_str_drop(this_); }; +inline void z_drop(zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_drop(this_); }; +inline void z_drop(zcu_owned_closure_matching_status_t* closure) { return zcu_closure_matching_status_drop(closure); }; -inline void z_null( z_owned_bytes_t* this_) { return z_bytes_null(this_); }; -inline void z_null( z_owned_bytes_reader_t* this_) { return z_bytes_reader_null(this_); }; -inline void z_null( z_owned_closure_hello_t* this_) { return z_closure_hello_null(this_); }; -inline void z_null( z_owned_closure_query_t* this_) { return z_closure_query_null(this_); }; -inline void z_null( z_owned_closure_reply_t* this_) { return z_closure_reply_null(this_); }; -inline void z_null( z_owned_closure_sample_t* this_) { return z_closure_sample_null(this_); }; -inline void z_null( z_owned_closure_zid_t* this_) { return z_closure_zid_null(this_); }; -inline void z_null( z_owned_condvar_t* this_) { return z_condvar_null(this_); }; -inline void z_null( z_owned_config_t* this_) { return z_config_null(this_); }; -inline void z_null( z_owned_encoding_t* encoding) { return z_encoding_null(encoding); }; -inline void z_null( z_owned_hello_t* this_) { return z_hello_null(this_); }; -inline void z_null( z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; -inline void z_null( z_owned_mutex_t* this_) { return z_mutex_null(this_); }; -inline void z_null( z_owned_publisher_t* this_) { return z_publisher_null(this_); }; -inline void z_null( z_owned_query_channel_closure_t* this_) { return z_query_channel_closure_null(this_); }; -inline void z_null( z_owned_query_t* this_) { return z_query_null(this_); }; -inline void z_null( z_owned_queryable_t* this_) { return z_queryable_null(this_); }; -inline void z_null( z_owned_reply_channel_closure_t* this_) { return z_reply_channel_closure_null(this_); }; -inline void z_null( z_owned_reply_channel_t* this_) { return z_reply_channel_null(this_); }; -inline void z_null( z_owned_reply_t* this_) { return z_reply_null(this_); }; -inline void z_null( z_owned_sample_t* sample) { return z_sample_null(sample); }; -inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; -inline void z_null( z_owned_session_t* this_) { return z_session_null(this_); }; -inline void z_null( z_owned_slice_array_t* this_) { return z_slice_array_null(this_); }; -inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; -inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; -inline void z_null( z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; -inline void z_null( z_owned_task_t* this_) { return z_task_null(this_); }; -inline void z_null( z_view_keyexpr_t* this_) { return z_view_keyexpr_null(this_); }; -inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; -inline void z_null( zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_null(this_); }; -inline void z_null( zcu_owned_closure_matching_status_t* this_) { return zcu_closure_matching_status_null(this_); }; -inline void z_null( ze_owned_publication_cache_t* this_) { return ze_publication_cache_null(this_); }; -inline void z_null( ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_null(this_); }; +inline void z_null(z_owned_bytes_t* this_) { return z_bytes_null(this_); }; +inline void z_null(z_owned_bytes_reader_t* this_) { return z_bytes_reader_null(this_); }; +inline void z_null(z_owned_closure_hello_t* this_) { return z_closure_hello_null(this_); }; +inline void z_null(z_owned_closure_query_t* this_) { return z_closure_query_null(this_); }; +inline void z_null(z_owned_closure_reply_t* this_) { return z_closure_reply_null(this_); }; +inline void z_null(z_owned_closure_sample_t* this_) { return z_closure_sample_null(this_); }; +inline void z_null(z_owned_closure_zid_t* this_) { return z_closure_zid_null(this_); }; +inline void z_null(z_owned_condvar_t* this_) { return z_condvar_null(this_); }; +inline void z_null(z_owned_config_t* this_) { return z_config_null(this_); }; +inline void z_null(z_owned_encoding_t* encoding) { return z_encoding_null(encoding); }; +inline void z_null(z_owned_hello_t* this_) { return z_hello_null(this_); }; +inline void z_null(z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; +inline void z_null(z_owned_mutex_t* this_) { return z_mutex_null(this_); }; +inline void z_null(z_owned_publisher_t* this_) { return z_publisher_null(this_); }; +inline void z_null(z_owned_query_channel_closure_t* this_) { return z_query_channel_closure_null(this_); }; +inline void z_null(z_owned_query_t* this_) { return z_query_null(this_); }; +inline void z_null(z_owned_queryable_t* this_) { return z_queryable_null(this_); }; +inline void z_null(z_owned_reply_channel_closure_t* this_) { return z_reply_channel_closure_null(this_); }; +inline void z_null(z_owned_reply_channel_t* this_) { return z_reply_channel_null(this_); }; +inline void z_null(z_owned_reply_t* this_) { return z_reply_null(this_); }; +inline void z_null(z_owned_sample_t* sample) { return z_sample_null(sample); }; +inline void z_null(z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; +inline void z_null(z_owned_session_t* this_) { return z_session_null(this_); }; +inline void z_null(z_owned_slice_array_t* this_) { return z_slice_array_null(this_); }; +inline void z_null(z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; +inline void z_null(z_owned_str_t* this_) { return z_str_null(this_); }; +inline void z_null(z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; +inline void z_null(z_owned_task_t* this_) { return z_task_null(this_); }; +inline void z_null(z_view_keyexpr_t* this_) { return z_view_keyexpr_null(this_); }; +inline void z_null(z_view_str_t* this_) { return z_view_str_null(this_); }; +inline void z_null(zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_null(this_); }; +inline void z_null(zcu_owned_closure_matching_status_t* this_) { return zcu_closure_matching_status_null(this_); }; +inline void z_null(ze_owned_publication_cache_t* this_) { return ze_publication_cache_null(this_); }; +inline void z_null(ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_null(this_); }; inline bool z_check(const z_owned_bytes_t& payload) { return z_bytes_check(&payload); }; @@ -287,31 +287,31 @@ inline bool z_check(const ze_owned_querying_subscriber_t& this_) { return ze_que inline void z_call(const z_owned_closure_hello_t& closure, const z_loaned_hello_t* hello) { - return z_closure_hello_call(&closure, hello); + return z_closure_hello_call(&closure, hello); }; -inline void z_call(const z_owned_closure_owned_query_t& closure, z_owned_query_t* query) { - return z_closure_owned_query_call(&closure, query); +inline void z_call(const z_owned_closure_owned_query_t& closure, z_owned_query_t* query) { + return z_closure_owned_query_call(&closure, query); }; inline void z_call(const z_owned_closure_query_t& closure, const z_loaned_query_t* query) { - return z_closure_query_call(&closure, query); + return z_closure_query_call(&closure, query); }; inline void z_call(const z_owned_closure_reply_t& closure, const z_loaned_reply_t* reply) { - return z_closure_reply_call(&closure, reply); + return z_closure_reply_call(&closure, reply); }; inline void z_call(const z_owned_closure_sample_t& closure, const z_loaned_sample_t* sample) { - return z_closure_sample_call(&closure, sample); + return z_closure_sample_call(&closure, sample); }; inline void z_call(const z_owned_closure_zid_t& closure, const z_id_t* sample) { - return z_closure_zid_call(&closure, sample); + return z_closure_zid_call(&closure, sample); }; -inline bool z_call(const z_owned_query_channel_closure_t& closure, z_owned_query_t* query) { - return z_query_channel_closure_call(&closure, query); +inline bool z_call(const z_owned_query_channel_closure_t& closure, z_owned_query_t* query) { + return z_query_channel_closure_call(&closure, query); }; -inline bool z_call(const z_owned_reply_channel_closure_t& closure, z_owned_reply_t* reply) { - return z_reply_channel_closure_call(&closure, reply); +inline bool z_call(const z_owned_reply_channel_closure_t& closure, z_owned_reply_t* reply) { + return z_reply_channel_closure_call(&closure, reply); }; inline void z_call(const zcu_owned_closure_matching_status_t& closure, const zcu_matching_status_t* sample) { - return zcu_closure_matching_status_call(&closure, sample); + return zcu_closure_matching_status_call(&closure, sample); }; @@ -326,7 +326,7 @@ inline void z_closure( }; inline void z_closure( z_owned_closure_owned_query_t* closure, - void (*call)( z_owned_query_t*, void*), + void (*call)(z_owned_query_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -371,7 +371,7 @@ inline void z_closure( }; inline void z_closure( z_owned_query_channel_closure_t* closure, - bool (*call)( z_owned_query_t*, void*), + bool (*call)(z_owned_query_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -380,7 +380,7 @@ inline void z_closure( }; inline void z_closure( z_owned_reply_channel_closure_t* closure, - bool (*call)( z_owned_reply_t*, void*), + bool (*call)(z_owned_reply_t*, void*), void (*drop)(void*), void *context) { closure->context = context; From 25b3dd38956b9fdb822c6debf5bde641cc469794 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 6 May 2024 12:14:01 +0200 Subject: [PATCH 081/377] docs for opaque types --- build-resources/opaque-types/src/lib.rs | 203 +++++++++--------------- docs/api.rst | 51 ++++++ include/zenoh_commons.h | 171 +++++++++++--------- include/zenoh_concrete.h | 69 +++----- src/commons.rs | 4 +- src/platform/synchronization.rs | 2 +- 6 files changed, 247 insertions(+), 253 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index ad328a522..eb417733b 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,4 +1,3 @@ -use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; use std::sync::Condvar; @@ -40,106 +39,98 @@ macro_rules! get_opaque_type_data { } } -/// A split buffer that owns all of its data. +/// A serialized Zenoh data. /// -/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. +/// To minimize copies and reallocations, Zenoh may provide you data in several separate buffers. get_opaque_type_data!(Option, z_owned_bytes_t); -/// A loaned payload. +/// A loaned serialized Zenoh data. get_opaque_type_data!(ZBytes, z_loaned_bytes_t); type CSlice = (usize, isize); -/// A contiguous view of bytes owned by some other entity. -/// -/// `start` being `null` is considered a gravestone value, -/// and empty slices are represented using a possibly dangling pointer for `start`. +/// A contiguous owned sequence of bytes allocated by Zenoh. +/// The instances should be released with `z_drop` macro or with `z_slice_drop` function and checked to validity with +/// `z_check` and `z_slice_check` correspondently. get_opaque_type_data!(CSlice, z_owned_slice_t); +/// A contiguous sequence of bytes owned by some other entity. get_opaque_type_data!(CSlice, z_view_slice_t); +/// A loaned sequence of bytes. get_opaque_type_data!(CSlice, z_loaned_slice_t); -/// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` +/// The wrapper type for null-terminated string values allocated by Zenoh. The instances of `z_owned_str_t` /// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with -/// `z_check` and `z_str_check` correspondently +/// `z_check` and `z_str_check` correspondently. get_opaque_type_data!(CSlice, z_owned_str_t); +/// The view over a null-terminated string. get_opaque_type_data!(CSlice, z_view_str_t); +/// A loaned null-terminated string. get_opaque_type_data!(CSlice, z_loaned_str_t); /// A map of maybe-owned slices to maybe-owned slices. /// -/// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher +/// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher. get_opaque_type_data!(Option>, z_owned_slice_map_t); +/// A loaned Slice Map. get_opaque_type_data!(HashMap, z_loaned_slice_map_t); /// An array of maybe-owned slices /// get_opaque_type_data!(Option>, z_owned_slice_array_t); +/// A loaned slice array. get_opaque_type_data!(Vec, z_loaned_slice_array_t); -/// An owned sample. +/// An owned Zenoh sample. /// /// This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. -/// Like all owned types, its memory must be freed by passing a mutable reference to it to `z_sample_drop`. +/// Like all owned types, it should be freed using z_drop or z_sample_drop. get_opaque_type_data!(Option, z_owned_sample_t); +/// A loaned Zenoh sample. get_opaque_type_data!(Sample, z_loaned_sample_t); /// A reader for payload data. get_opaque_type_data!(Option>, z_owned_bytes_reader_t); get_opaque_type_data!(ZBytesReader<'static>, z_loaned_bytes_reader_t); -/// The encoding of a payload, in a MIME-like format. -/// -/// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. +/// The encoding of Zenoh payload, (for example in a MIME-like format). get_opaque_type_data!(Encoding, z_loaned_encoding_t); +/// A loaned Zenoh-encoding. get_opaque_type_data!(Encoding, z_owned_encoding_t); -/// An owned reply to a :c:func:`z_get`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +/// An owned reply from a Quryable to a :c:func:`z_get`. get_opaque_type_data!(Option, z_owned_reply_t); +/// A loaned reply to a :c:func:`z_get`. get_opaque_type_data!(Reply, z_loaned_reply_t); -/// A zenoh value. +/// A Zenoh value - a compination of payload and its encoding. get_opaque_type_data!(Value, z_owned_value_t); +/// A loaned Zenoh value. get_opaque_type_data!(Value, z_loaned_value_t); -// Loaned variant of a Query received by a Queryable. +/// An owned Zenoh query received by a queryable. /// /// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. -/// `z_loaned_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. get_opaque_type_data!(Option, z_owned_query_t); +/// A loaned Zenoh query. +/// +/// It is valid as long as at least the corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. get_opaque_type_data!(Query, z_loaned_query_t); -/// An owned zenoh queryable. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +/// An owned Zenoh queryable. +/// +/// Responds to queries sent via :c:func:`z_get` with intersecting key expression. get_opaque_type_data!(Option>, z_owned_queryable_t); +/// A loaned Zenoh queryable. get_opaque_type_data!(Queryable<'static, ()>, z_loaned_queryable_t); -/// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. -/// -/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +/// An owned Zenoh querying subscriber. +/// +/// In addition to receiving the data it is subscribed to, +/// it also will fetch data from a Quryable at startup and peridodically (using :c:func: `ze_querying_subscriber_get`). get_opaque_type_data!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); +/// A loaned Zenoh querying subscriber get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_loaned_querying_subscriber_t); -/// A zenoh-allocated key expression. +/// A Zenoh-allocated `key expression `_. /// /// Key expressions can identify a single key or a set of keys. /// @@ -147,23 +138,15 @@ get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Sess /// - ``"key/expression"``. /// - ``"key/ex*"``. /// -/// Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` +/// Key expressions can be mapped to numerical ids through :c:func:`z_declare_keyexpr` /// for wire and computation efficiency. /// -/// A `key expression `_ can be either: +/// Internally key expressiobn can be either: /// - A plain string expression. /// - A pure numerical id. /// - The combination of a numerical prefix and a string suffix. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_keyexpr_t); +/// A user allocated string, viewed as a key expression. get_opaque_type_data!(Option>, z_view_keyexpr_t); /// A loaned key expression. @@ -174,80 +157,46 @@ get_opaque_type_data!(Option>, z_view_keyexpr_t); /// - ``"key/expression"``. /// - ``"key/ex*"``. /// -/// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, +/// Using :c:func:`z_declare_keyexpr` allows Zenoh to optimize a key expression, /// both for local processing and network-wise. get_opaque_type_data!(KeyExpr<'_>, z_loaned_keyexpr_t); -/// An owned zenoh session. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +/// An owned Zenoh session. get_opaque_type_data!(Option>, z_owned_session_t); +/// A loaned Zenoh session. get_opaque_type_data!(Session, z_loaned_session_t); -/// An owned zenoh configuration. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +/// An owned Zenoh configuration. get_opaque_type_data!(Option, z_owned_config_t); -/// A loaned zenoh configuration. +/// A loaned Zenoh configuration. get_opaque_type_data!(Config, z_loaned_config_t); -/// Represents a Zenoh ID. +/// A Zenoh ID. /// /// In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. get_opaque_type_data!(ZenohId, z_id_t); +/// A Zenoh `timestamp `_. +/// +/// It consists of a time generated by a Hybrid Logical Clock (HLC) in NPT64 format and a unique zenoh identifier. get_opaque_type_data!(Timestamp, z_timestamp_t); -/// An owned zenoh publisher. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +/// An owned Zenoh publisher. get_opaque_type_data!(Option>, z_owned_publisher_t); +/// A loaned Zenoh publisher. get_opaque_type_data!(Publisher<'static>, z_loaned_publisher_t); -/// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +/// An owned Zenoh matching listener. +/// +/// A listener that sends notifications when the [`MatchingStatus`] of a publisher changes. +/// Destroying the matching listener cancels the subscription. get_opaque_type_data!(Option>, zcu_owned_matching_listener_t); -/// An owned zenoh subscriber. Destroying the subscriber cancels the subscription. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +/// An owned Zenoh subscriber. +/// +/// Receives data from publication on intersecting key expressions. +/// Destroying the subscriber cancels the subscription. get_opaque_type_data!(Option>, z_owned_subscriber_t); get_opaque_type_data!(Subscriber<'static, ()>, z_loaned_subscriber_t); @@ -260,34 +209,30 @@ get_opaque_type_data!(Option>, zc_owned_liveliness_toke get_opaque_type_data!(LivelinessToken<'static>, zc_loaned_liveliness_token_t); -/// An owned zenoh publication_cache. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +/// An owned Zenoh publication cache. +/// +/// Used to store publications on intersecting key expressions. Can be queried later via :c:func:z_get to retrieve this data +/// (for example by Querying Subscriber). get_opaque_type_data!(Option>, ze_owned_publication_cache_t); +/// A loaned Zenoh publication cache. get_opaque_type_data!(zenoh_ext::PublicationCache<'static>, ze_loaned_publication_cache_t); - +/// An owned mutex. get_opaque_type_data!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); +/// A loaned mutex. get_opaque_type_data!((Mutex<()>, Option>), z_loaned_mutex_t); +/// An owned conditional variable. +/// +/// Used in combination with to wake up thread when certain conditions are met. get_opaque_type_data!(Option, z_owned_condvar_t); +/// A loaned conditional variable. get_opaque_type_data!(Condvar, z_loaned_condvar_t); +/// An owned Zenoh task. get_opaque_type_data!(Option>, z_owned_task_t); -/// A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +/// An owned Zenoh-allocated hello message returned by a Zenoh entity to a scout message sent with `z_scout`. get_opaque_type_data!(Option, z_owned_hello_t); +/// A loaned hello message. get_opaque_type_data!(Hello, z_loaned_hello_t); \ No newline at end of file diff --git a/docs/api.rst b/docs/api.rst index 99c60297c..28f449883 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -95,6 +95,57 @@ Slice array .. autocfunction:: zenoh_commons.h::z_slice_array_len .. autocfunction:: zenoh_commons.h::z_slice_array_is_empty +Common +====== + +Timestamp +--------- +.. autocstruct:: zenoh_commons.h::z_timestamp_t + +.. autocfunction:: zenoh_commons.h::z_timestamp_id +.. autocfunction:: zenoh_commons.h::z_timestamp_npt64_time + +System +====== + +Mutex +----- +.. autocstruct:: zenoh_commons.h::z_owned_mutex_t +.. autocstruct:: zenoh_commons.h::z_loaned_mutex_t + +.. autocfunction:: zenoh_commons.h::z_mutex_check +.. autocfunction:: zenoh_commons.h::z_mutex_null +.. autocfunction:: zenoh_commons.h::z_mutex_loan_mut +.. autocfunction:: zenoh_commons.h::z_mutex_drop +.. autocfunction:: zenoh_commons.h::z_mutex_init +.. autocfunction:: zenoh_commons.h::z_mutex_lock +.. autocfunction:: zenoh_commons.h::z_mutex_unlock +.. autocfunction:: zenoh_commons.h::z_mutex_try_lock + + +Conditional Variable +-------------------- +.. autocstruct:: zenoh_commons.h::z_owned_condvar_t +.. autocstruct:: zenoh_commons.h::z_loaned_condvar_t + +.. autocfunction:: zenoh_commons.h::z_condvar_check +.. autocfunction:: zenoh_commons.h::z_condvar_null +.. autocfunction:: zenoh_commons.h::z_condvar_loan +.. autocfunction:: zenoh_commons.h::z_condvar_drop +.. autocfunction:: zenoh_commons.h::z_condvar_init +.. autocfunction:: zenoh_commons.h::z_condvar_wait +.. autocfunction:: zenoh_commons.h::z_condvar_signal + + +Task +---- +.. autocstruct:: zenoh_commons.h::z_owned_task_t + +.. autocfunction:: zenoh_commons.h::z_task_check +.. autocfunction:: zenoh_commons.h::z_task_null +.. autocfunction:: zenoh_commons.h::z_task_join +.. autocfunction:: zenoh_commons.h::z_task_detach + .. Scouting .. ======== diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 60674b721..2c47e601f 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -115,25 +115,24 @@ typedef enum zcu_reply_keyexpr_t { ZCU_REPLY_KEYEXPR_MATCHING_QUERY = 1, } zcu_reply_keyexpr_t; /** - * A split buffer that owns all of its data. + * A serialized Zenoh data. * - * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + * To minimize copies and reallocations, Zenoh may provide you data in several separate buffers. */ typedef struct ALIGN(8) z_owned_bytes_t { uint8_t _0[40]; } z_owned_bytes_t; /** - * A loaned payload. + * A loaned serialized Zenoh data. */ typedef struct ALIGN(8) z_loaned_bytes_t { uint8_t _0[40]; } z_loaned_bytes_t; typedef int8_t z_error_t; /** - * A contiguous view of bytes owned by some other entity. - * - * `start` being `null` is considered a gravestone value, - * and empty slices are represented using a possibly dangling pointer for `start`. + * A contiguous owned sequence of bytes allocated by Zenoh. + * The instances should be released with `z_drop` macro or with `z_slice_drop` function and checked to validity with + * `z_check` and `z_slice_check` correspondently. */ typedef struct ALIGN(8) z_owned_slice_t { uint8_t _0[16]; @@ -141,25 +140,34 @@ typedef struct ALIGN(8) z_owned_slice_t { /** * A map of maybe-owned slices to maybe-owned slices. * - * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher + * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher. */ typedef struct ALIGN(8) z_owned_slice_map_t { uint8_t _0[48]; } z_owned_slice_map_t; /** - * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` + * The wrapper type for null-terminated string values allocated by Zenoh. The instances of `z_owned_str_t` * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with - * `z_check` and `z_str_check` correspondently + * `z_check` and `z_str_check` correspondently. */ typedef struct ALIGN(8) z_owned_str_t { uint8_t _0[16]; } z_owned_str_t; +/** + * A loaned sequence of bytes. + */ typedef struct ALIGN(8) z_loaned_slice_t { uint8_t _0[16]; } z_loaned_slice_t; +/** + * A loaned Slice Map. + */ typedef struct ALIGN(8) z_loaned_slice_map_t { uint8_t _0[48]; } z_loaned_slice_map_t; +/** + * A loaned null-terminated string. + */ typedef struct ALIGN(8) z_loaned_str_t { uint8_t _0[16]; } z_loaned_str_t; @@ -180,6 +188,9 @@ typedef struct z_clock_t { uint64_t t; const void *t_base; } z_clock_t; +/** + * A loaned hello message. + */ typedef struct ALIGN(8) z_loaned_hello_t { uint8_t _0[48]; } z_loaned_hello_t; @@ -205,9 +216,9 @@ typedef struct z_owned_closure_hello_t { void (*drop)(void*); } z_owned_closure_hello_t; /** + * An owned Zenoh query received by a queryable. * * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. - * `z_loaned_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. */ typedef struct ALIGN(8) z_owned_query_t { uint8_t _0[16]; @@ -254,6 +265,9 @@ typedef struct z_owned_closure_query_t { void (*call)(const struct z_loaned_query_t*, void *context); void (*drop)(void*); } z_owned_closure_query_t; +/** + * A loaned reply to a :c:func:`z_get`. + */ typedef struct ALIGN(8) z_loaned_reply_t { uint8_t _0[256]; } z_loaned_reply_t; @@ -278,6 +292,9 @@ typedef struct z_owned_closure_reply_t { void (*call)(const struct z_loaned_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; +/** + * A loaned Zenoh sample. + */ typedef struct ALIGN(8) z_loaned_sample_t { uint8_t _0[240]; } z_loaned_sample_t; @@ -303,7 +320,7 @@ typedef struct z_owned_closure_sample_t { void (*drop)(void*); } z_owned_closure_sample_t; /** - * Represents a Zenoh ID. + * A Zenoh ID. * * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. */ @@ -331,38 +348,40 @@ typedef struct z_owned_closure_zid_t { void (*call)(const struct z_id_t*, void*); void (*drop)(void*); } z_owned_closure_zid_t; +/** + * An owned conditional variable. + * + * Used in combination with to wake up thread when certain conditions are met. + */ typedef struct ALIGN(8) z_owned_condvar_t { uint8_t _0[24]; } z_owned_condvar_t; +/** + * A loaned conditional variable. + */ typedef struct ALIGN(8) z_loaned_condvar_t { uint8_t _0[16]; } z_loaned_condvar_t; +/** + * A loaned mutex. + */ typedef struct ALIGN(8) z_loaned_mutex_t { uint8_t _0[32]; } z_loaned_mutex_t; /** - * An owned zenoh configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * An owned Zenoh configuration. */ typedef struct ALIGN(8) z_owned_config_t { uint8_t _0[1544]; } z_owned_config_t; /** - * A loaned zenoh configuration. + * A loaned Zenoh configuration. */ typedef struct ALIGN(8) z_loaned_config_t { uint8_t _0[1544]; } z_loaned_config_t; /** - * A zenoh-allocated key expression. + * A Zenoh-allocated `key expression `_. * * Key expressions can identify a single key or a set of keys. * @@ -370,22 +389,13 @@ typedef struct ALIGN(8) z_loaned_config_t { * - ``"key/expression"``. * - ``"key/ex*"``. * - * Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` + * Key expressions can be mapped to numerical ids through :c:func:`z_declare_keyexpr` * for wire and computation efficiency. * - * A `key expression `_ can be either: + * Internally key expressiobn can be either: * - A plain string expression. * - A pure numerical id. * - The combination of a numerical prefix and a string suffix. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. */ typedef struct ALIGN(8) z_owned_keyexpr_t { uint8_t _0[32]; @@ -399,23 +409,14 @@ typedef struct ALIGN(8) z_owned_keyexpr_t { * - ``"key/expression"``. * - ``"key/ex*"``. * - * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, + * Using :c:func:`z_declare_keyexpr` allows Zenoh to optimize a key expression, * both for local processing and network-wise. */ typedef struct ALIGN(8) z_loaned_keyexpr_t { uint8_t _0[32]; } z_loaned_keyexpr_t; /** - * An owned zenoh publisher. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * An owned Zenoh publisher. */ typedef struct ALIGN(8) z_owned_publisher_t { uint8_t _0[56]; @@ -456,13 +457,14 @@ typedef struct z_delete_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_delete_options_t; +/** + * A loaned Zenoh-encoding. + */ typedef struct ALIGN(8) z_owned_encoding_t { uint8_t _0[48]; } z_owned_encoding_t; /** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + * The encoding of Zenoh payload, (for example in a MIME-like format). */ typedef struct ALIGN(8) z_loaned_encoding_t { uint8_t _0[48]; @@ -493,13 +495,7 @@ typedef struct z_get_options_t { uint64_t timeout_ms; } z_get_options_t; /** - * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + * An owned Zenoh-allocated hello message returned by a Zenoh entity to a scout message sent with `z_scout`. */ typedef struct ALIGN(8) z_owned_hello_t { uint8_t _0[48]; @@ -511,15 +507,29 @@ typedef struct ALIGN(8) z_owned_hello_t { typedef struct ALIGN(8) z_owned_slice_array_t { uint8_t _0[24]; } z_owned_slice_array_t; +/** + * A contiguous sequence of bytes owned by some other entity. + */ typedef struct ALIGN(8) z_view_slice_t { uint8_t _0[16]; } z_view_slice_t; +/** + * A Zenoh `timestamp `_. + * + * It consists of a time generated by a Hybrid Logical Clock (HLC) in NPT64 format and a unique zenoh identifier. + */ typedef struct ALIGN(8) z_timestamp_t { uint8_t _0[24]; } z_timestamp_t; +/** + * An owned mutex. + */ typedef struct ALIGN(8) z_owned_mutex_t { uint8_t _0[32]; } z_owned_mutex_t; +/** + * A loaned Zenoh publisher. + */ typedef struct ALIGN(8) z_loaned_publisher_t { uint8_t _0[56]; } z_loaned_publisher_t; @@ -593,17 +603,14 @@ typedef struct z_query_reply_options_t { struct z_owned_encoding_t *encoding; struct z_owned_bytes_t *attachment; } z_query_reply_options_t; +/** + * A loaned Zenoh value. + */ typedef struct ALIGN(8) z_loaned_value_t { uint8_t _0[88]; } z_loaned_value_t; /** - * An owned reply to a :c:func:`z_get`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + * An owned reply from a Quryable to a :c:func:`z_get`. */ typedef struct ALIGN(8) z_owned_reply_t { uint8_t _0[256]; @@ -634,10 +641,10 @@ typedef struct z_owned_reply_channel_t { struct z_owned_reply_channel_closure_t recv; } z_owned_reply_channel_t; /** - * An owned sample. + * An owned Zenoh sample. * * This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `z_sample_drop`. + * Like all owned types, it should be freed using z_drop or z_sample_drop. */ typedef struct ALIGN(8) z_owned_sample_t { uint8_t _0[240]; @@ -647,6 +654,9 @@ typedef struct z_owned_scouting_config_t { unsigned long zc_timeout_ms; uint8_t zc_what; } z_owned_scouting_config_t; +/** + * A loaned slice array. + */ typedef struct ALIGN(8) z_loaned_slice_array_t { uint8_t _0[24]; } z_loaned_slice_array_t; @@ -661,6 +671,9 @@ typedef struct ALIGN(8) z_loaned_slice_array_t { typedef bool (*z_slice_map_iter_body_t)(const struct z_loaned_slice_t *key, const struct z_loaned_slice_t *value, void *context); +/** + * An owned Zenoh task. + */ typedef struct ALIGN(8) z_owned_task_t { uint8_t _0[24]; } z_owned_task_t; @@ -674,9 +687,15 @@ typedef struct z_task_attr_t { typedef struct z_time_t { uint64_t t; } z_time_t; +/** + * A user allocated string, viewed as a key expression. + */ typedef struct ALIGN(8) z_view_keyexpr_t { uint8_t _0[32]; } z_view_keyexpr_t; +/** + * The view over a null-terminated string. + */ typedef struct ALIGN(8) z_view_str_t { uint8_t _0[16]; } z_view_str_t; @@ -739,16 +758,10 @@ typedef struct zcu_owned_closure_matching_status_t { void (*drop)(void*); } zcu_owned_closure_matching_status_t; /** - * An owned zenoh matching listener. Destroying the matching listener cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * An owned Zenoh matching listener. * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * A listener that sends notifications when the [`MatchingStatus`] of a publisher changes. + * Destroying the matching listener cancels the subscription. */ typedef struct ALIGN(8) zcu_owned_matching_listener_t { uint8_t _0[40]; @@ -1402,7 +1415,6 @@ enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_loaned_ * The user is responsible of droping the returned string using `z_drop` */ ZENOHC_API void z_keyexpr_to_string(const struct z_loaned_keyexpr_t *ke, struct z_owned_str_t *s); -ZENOHC_API z_error_t z_loaned_mutex_try_lock(struct z_loaned_mutex_t *this_); /** * The samples timestamp * @@ -1417,6 +1429,7 @@ ZENOHC_API z_error_t z_mutex_init(struct z_owned_mutex_t *this_); ZENOHC_API struct z_loaned_mutex_t *z_mutex_loan_mut(struct z_owned_mutex_t *this_); ZENOHC_API z_error_t z_mutex_lock(struct z_loaned_mutex_t *this_); ZENOHC_API void z_mutex_null(struct z_owned_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_try_lock(struct z_loaned_mutex_t *this_); ZENOHC_API z_error_t z_mutex_unlock(struct z_loaned_mutex_t *this_); /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. @@ -2039,7 +2052,13 @@ ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); ZENOHC_API struct z_time_t z_time_now(void); ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); -ZENOHC_API struct z_id_t z_timestamp_get_id(const struct z_timestamp_t *timestamp); +/** + * Returns id associated with this `timestamp` + */ +ZENOHC_API struct z_id_t z_timestamp_id(const struct z_timestamp_t *timestamp); +/** + * Returns NPT64 time associated with this `timestamp` + */ ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); /** * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 7c4d34675..c3f6c6391 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -22,52 +22,38 @@ #include #define DEFAULT_SCOUTING_TIMEOUT 1000 /** - * An owned zenoh session. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * An owned Zenoh session. */ typedef struct ALIGN(8) z_owned_session_t { uint8_t _0[8]; } z_owned_session_t; +/** + * A loaned Zenoh query. + * + * It is valid as long as at least the corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. + */ typedef struct ALIGN(8) z_loaned_query_t { uint8_t _0[16]; } z_loaned_query_t; +/** + * A loaned Zenoh session. + */ typedef struct ALIGN(8) z_loaned_session_t { uint8_t _0[40]; } z_loaned_session_t; /** - * An owned zenoh queryable. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * An owned Zenoh queryable. * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * Responds to queries sent via :c:func:`z_get` with intersecting key expression. */ typedef struct ALIGN(8) z_owned_queryable_t { uint8_t _0[32]; } z_owned_queryable_t; /** - * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * An owned Zenoh subscriber. * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * Receives data from publication on intersecting key expressions. + * Destroying the subscriber cancels the subscription. */ typedef struct ALIGN(8) z_owned_subscriber_t { uint8_t _0[32]; @@ -76,35 +62,26 @@ typedef struct ALIGN(8) z_loaned_subscriber_t { uint8_t _0[32]; } z_loaned_subscriber_t; /** - * An owned zenoh publication_cache. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * An owned Zenoh publication cache. * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * Used to store publications on intersecting key expressions. Can be queried later via :c:func:z_get to retrieve this data + * (for example by Querying Subscriber). */ typedef struct ALIGN(8) ze_owned_publication_cache_t { uint8_t _0[96]; } ze_owned_publication_cache_t; /** - * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. + * An owned Zenoh querying subscriber. * - * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * In addition to receiving the data it is subscribed to, + * it also will fetch data from a Quryable at startup and peridodically (using :c:func: `ze_querying_subscriber_get`). */ typedef struct ALIGN(8) ze_owned_querying_subscriber_t { uint8_t _0[64]; } ze_owned_querying_subscriber_t; +/** + * A loaned Zenoh querying subscriber + */ typedef struct ALIGN(8) ze_loaned_querying_subscriber_t { uint8_t _0[64]; } ze_loaned_querying_subscriber_t; diff --git a/src/commons.rs b/src/commons.rs index a56a8dae7..77838a09d 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -75,13 +75,15 @@ impl From for SampleKind { use crate::opaque_types::z_timestamp_t; decl_transmute_copy!(Timestamp, z_timestamp_t); +/// Returns NPT64 time associated with this `timestamp` #[no_mangle] pub extern "C" fn z_timestamp_npt64_time(timestamp: &z_timestamp_t) -> u64 { timestamp.transmute_copy().get_time().0 } +/// Returns id associated with this `timestamp` #[no_mangle] -pub extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t { +pub extern "C" fn z_timestamp_id(timestamp: &z_timestamp_t) -> z_id_t { timestamp.transmute_copy().get_id().to_le_bytes().into() } diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index 52032c8aa..4dfb8abd0 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -84,7 +84,7 @@ pub extern "C" fn z_mutex_unlock(this: &mut z_loaned_mutex_t) -> errors::z_error #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_loaned_mutex_try_lock(this: &mut z_loaned_mutex_t) -> errors::z_error_t { +pub unsafe extern "C" fn z_mutex_try_lock(this: &mut z_loaned_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.try_lock() { Ok(new_lock) => { From 1da85f2ebf8bac07be477d0eae38d624455233b2 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 6 May 2024 16:50:15 +0200 Subject: [PATCH 082/377] docs for collections --- build-resources/opaque-types/src/lib.rs | 11 +- docs/api.rst | 4 + include/zenoh_commons.h | 197 ++++++++++++++-------- src/collections.rs | 214 +++++++++++++++--------- 4 files changed, 268 insertions(+), 158 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index eb417733b..fad58475b 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -48,18 +48,15 @@ get_opaque_type_data!(ZBytes, z_loaned_bytes_t); type CSlice = (usize, isize); + /// A contiguous owned sequence of bytes allocated by Zenoh. -/// The instances should be released with `z_drop` macro or with `z_slice_drop` function and checked to validity with -/// `z_check` and `z_slice_check` correspondently. get_opaque_type_data!(CSlice, z_owned_slice_t); /// A contiguous sequence of bytes owned by some other entity. get_opaque_type_data!(CSlice, z_view_slice_t); /// A loaned sequence of bytes. get_opaque_type_data!(CSlice, z_loaned_slice_t); -/// The wrapper type for null-terminated string values allocated by Zenoh. The instances of `z_owned_str_t` -/// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with -/// `z_check` and `z_str_check` correspondently. +/// The wrapper type for null-terminated string values allocated by Zenoh. get_opaque_type_data!(CSlice, z_owned_str_t); /// The view over a null-terminated string. get_opaque_type_data!(CSlice, z_view_str_t); @@ -70,10 +67,10 @@ get_opaque_type_data!(CSlice, z_loaned_str_t); /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher. get_opaque_type_data!(Option>, z_owned_slice_map_t); -/// A loaned Slice Map. +/// A loaned slice map. get_opaque_type_data!(HashMap, z_loaned_slice_map_t); -/// An array of maybe-owned slices +/// An array of maybe-owned slices. /// get_opaque_type_data!(Option>, z_owned_slice_array_t); /// A loaned slice array. diff --git a/docs/api.rst b/docs/api.rst index 28f449883..0cac3e582 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -38,6 +38,7 @@ Slice .. autocfunction:: zenoh_commons.h::z_view_slice_loan .. autocfunction:: zenoh_commons.h::z_slice_data .. autocfunction:: zenoh_commons.h::z_slice_len +.. autocfunction:: zenoh_commons.h::z_slice_is_empty String @@ -61,11 +62,13 @@ String .. autocfunction:: zenoh_commons.h::z_view_str_loan .. autocfunction:: zenoh_commons.h::z_str_data .. autocfunction:: zenoh_commons.h::z_str_len +.. autocfunction:: zenoh_commons.h::z_str_is_empty Slice map --------- .. autocstruct:: zenoh_commons.h::z_owned_slice_map_t +.. autocstruct:: zenoh_commons.h::z_loaned_slice_map_t .. autocfunction:: zenoh_commons.h::z_slice_map_new .. autocfunction:: zenoh_commons.h::z_slice_map_check @@ -84,6 +87,7 @@ Slice array ----------- .. autocstruct:: zenoh_commons.h::z_owned_slice_array_t +.. autocstruct:: zenoh_commons.h::z_loaned_slice_array_t .. autocfunction:: zenoh_commons.h::z_slice_array_new .. autocfunction:: zenoh_commons.h::z_slice_array_check diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 2c47e601f..3cee7e68c 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -131,8 +131,6 @@ typedef struct ALIGN(8) z_loaned_bytes_t { typedef int8_t z_error_t; /** * A contiguous owned sequence of bytes allocated by Zenoh. - * The instances should be released with `z_drop` macro or with `z_slice_drop` function and checked to validity with - * `z_check` and `z_slice_check` correspondently. */ typedef struct ALIGN(8) z_owned_slice_t { uint8_t _0[16]; @@ -146,9 +144,7 @@ typedef struct ALIGN(8) z_owned_slice_map_t { uint8_t _0[48]; } z_owned_slice_map_t; /** - * The wrapper type for null-terminated string values allocated by Zenoh. The instances of `z_owned_str_t` - * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with - * `z_check` and `z_str_check` correspondently. + * The wrapper type for null-terminated string values allocated by Zenoh. */ typedef struct ALIGN(8) z_owned_str_t { uint8_t _0[16]; @@ -160,7 +156,7 @@ typedef struct ALIGN(8) z_loaned_slice_t { uint8_t _0[16]; } z_loaned_slice_t; /** - * A loaned Slice Map. + * A loaned slice map. */ typedef struct ALIGN(8) z_loaned_slice_map_t { uint8_t _0[48]; @@ -501,7 +497,7 @@ typedef struct ALIGN(8) z_owned_hello_t { uint8_t _0[48]; } z_owned_hello_t; /** - * An array of maybe-owned slices + * An array of maybe-owned slices. * */ typedef struct ALIGN(8) z_owned_slice_array_t { @@ -660,17 +656,6 @@ typedef struct z_owned_scouting_config_t { typedef struct ALIGN(8) z_loaned_slice_array_t { uint8_t _0[24]; } z_loaned_slice_array_t; -/** - * The body of a loop over a z_slice_map's key-value pairs. - * - * `key` and `value` are loaned to the body for the duration of a single call. - * `context` is passed transparently through the iteration driver. - * - * Returning `true` is treated as `break`. - */ -typedef bool (*z_slice_map_iter_body_t)(const struct z_loaned_slice_t *key, - const struct z_loaned_slice_t *value, - void *context); /** * An owned Zenoh task. */ @@ -1833,45 +1818,49 @@ ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); /** - * Returns `true` if the array is not in its gravestone state + * Returns ``true`` if the slice array is valid, ``false`` if it is in a gravestone state. */ ZENOHC_API bool z_slice_array_check(const struct z_owned_slice_array_t *this_); /** - * Destroys the array, resetting `this` to its gravestone value. - * - * This function is double-free safe, passing a pointer to the gravestone value will have no effect. + * Destroys the slice array, resetting it to its gravestone value. */ ZENOHC_API void z_slice_array_drop(struct z_owned_slice_array_t *this_); /** - * Returns the value at the position of index in the array. + * Returns the value at the position of index in the slice array. * - * Will return NULL if the index is out of bounds. + * Will return `NULL` if the index is out of bounds. */ ZENOHC_API const struct z_loaned_slice_t *z_slice_array_get(const struct z_loaned_slice_array_t *this_, size_t index); /** - * Returns true if the array is empty, false otherwise. + * Returns ``true`` if the array is empty, ``false`` otherwise. */ ZENOHC_API bool z_slice_array_is_empty(const struct z_loaned_slice_array_t *this_); /** - * Returns number of key-value pairs in the map. + * Returns number of elements in the array. */ ZENOHC_API size_t z_slice_array_len(const struct z_loaned_slice_array_t *this_); +/** + * Returns a loaned slice array. + */ ZENOHC_API const struct z_loaned_slice_array_t *z_slice_array_loan(const struct z_owned_slice_array_t *this_); +/** + * Returns a mutable loaned slice array. + */ ZENOHC_API struct z_loaned_slice_array_t *z_slice_array_loan_mut(struct z_owned_slice_array_t *this_); /** - * Constructs a new empty array. + * Constructs a new empty slice array. */ ZENOHC_API void z_slice_array_new(struct z_owned_slice_array_t *this_); /** - * Constructs the gravestone value for `z_owned_slice_array_t` + * Constructs slice array in its gravestone state. */ ZENOHC_API void z_slice_array_null(struct z_owned_slice_array_t *this_); /** - * Appends specified value to the end of the array by aliasing. + * Appends specified value to the end of the slice array by alias. * * Returns the new length of the array. */ @@ -1879,7 +1868,7 @@ ZENOHC_API size_t z_slice_array_push_by_alias(struct z_loaned_slice_array_t *this_, const struct z_loaned_slice_t *value); /** - * Appends specified value to the end of the array by copying. + * Appends specified value to the end of the slice array by copying. * * Returns the new length of the array. */ @@ -1887,43 +1876,57 @@ ZENOHC_API size_t z_slice_array_push_by_copy(struct z_loaned_slice_array_t *this_, const struct z_loaned_slice_t *value); /** - * Returns ``true`` if `this` is initialized. + * Returns ``true`` if slice is not empty, ``false`` otherwise. */ ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *this_); +/** + * Constructs an owned copy of a slice. + */ ZENOHC_API void z_slice_clone(const struct z_loaned_slice_t *this_, struct z_owned_slice_t *dst); +/** + * Returns the pointer to the slice data. + */ ZENOHC_API const uint8_t *z_slice_data(const struct z_loaned_slice_t *this_); /** - * Frees `this` and invalidates it for double-drop safety. + * Frees the memory and invalidates the slice. */ ZENOHC_API void z_slice_drop(struct z_owned_slice_t *this_); /** - * Returns an empty `z_owned_slice_t` + * Constructs an empty `z_owned_slice_t`. */ ZENOHC_API void z_slice_empty(struct z_owned_slice_t *this_); /** * Copies a string into `z_owned_slice_t` using `strlen` (this should therefore not be used with untrusted inputs). * - * Calling this with `str == NULL` is equivalent to `z_slice_null`. + * Returns -1 if `str == NULL` (and creates an empty slice), 0 otherwise. */ ZENOHC_API -void z_slice_from_str(struct z_owned_slice_t *this_, - const char *str); +z_error_t z_slice_from_str(struct z_owned_slice_t *this_, + const char *str); +/** + * Returns ``true`` if slice is empty, ``false`` otherwise. + */ +ZENOHC_API bool z_slice_is_empty(const struct z_loaned_slice_t *this_); +/** + * Returns the length of the slice. + */ ZENOHC_API size_t z_slice_len(const struct z_loaned_slice_t *this_); +/** + * Returns a loaned slice. + */ ZENOHC_API const struct z_loaned_slice_t *z_slice_loan(const struct z_owned_slice_t *this_); /** - * Returns `true` if the map is not in its gravestone state + * Returns ``true`` if the map is not in its gravestone state, ``false`` otherwise. */ ZENOHC_API bool z_slice_map_check(const struct z_owned_slice_map_t *map); /** - * Destroys the map, resetting `this` to its gravestone value. - * - * This function is double-free safe, passing a pointer to the gravestone value will have no effect. + * Destroys the map, resetting it to its gravestone value. */ ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); /** * Returns the value associated with `key`. * - * Will return NULL if the key is not present in the map. + * Will return `NULL` if the key is not present in the map. */ ZENOHC_API const struct z_loaned_slice_t *z_slice_map_get(const struct z_loaned_slice_map_t *this_, @@ -1931,8 +1934,7 @@ const struct z_loaned_slice_t *z_slice_map_get(const struct z_loaned_slice_map_t /** * Associates `value` to `key` in the map, aliasing them. * - * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. - * + * If the `key` was already present in the map, its value is updated. * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API @@ -1942,6 +1944,7 @@ z_error_t z_slice_map_insert_by_alias(struct z_loaned_slice_map_t *this_, /** * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. * + * If the `key` was already present in the map, its value is updated. * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API @@ -1949,67 +1952,104 @@ uint8_t z_slice_map_insert_by_copy(struct z_loaned_slice_map_t *this_, const struct z_loaned_slice_t *key, const struct z_loaned_slice_t *value); /** - * Returns true if the map is empty, false otherwise. + * Returns ``true`` if the map is empty, ``false`` otherwise. */ ZENOHC_API bool z_slice_map_is_empty(const struct z_loaned_slice_map_t *this_); +/** + * Iterates over key-value pairs of a slice map. + * + * Parameters: + * this_: Slice map to iterate over. + * body: Iterator body function. Returning `true` is treated as iteration loop `break`. + * context: Some data passed to every body invocation. + */ ZENOHC_API void z_slice_map_iterate(const struct z_loaned_slice_map_t *this_, - z_slice_map_iter_body_t body, + bool (*body)(const struct z_loaned_slice_t *key, + const struct z_loaned_slice_t *value, + void *context), void *context); /** * Returns number of key-value pairs in the map. */ ZENOHC_API size_t z_slice_map_len(const struct z_loaned_slice_map_t *this_); +/** + * Returns a loaned slice map. + */ ZENOHC_API const struct z_loaned_slice_map_t *z_slice_map_loan(const struct z_owned_slice_map_t *this_); +/** + * Returns a mutable loaned slice map. + */ ZENOHC_API struct z_loaned_slice_map_t *z_slice_map_loan_mut(struct z_owned_slice_map_t *this_); /** * Constructs a new empty map. */ ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); /** - * Constructs the gravestone value for `z_owned_slice_map_t` + * Constructs the gravestone value for :c:type:`z_owned_slice_map_t`. */ ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); /** - * Constructs a `len` bytes long view starting at `start`. + * Constructs a slice by copying a `len` bytes long sequence starting at `start`. + * + * Returns -1 if `start == NULL` and `len > 0` (creating an empty slice), 0 otherwise. */ -ZENOHC_API void z_slice_wrap(struct z_owned_slice_t *this_, const uint8_t *start, size_t len); +ZENOHC_API z_error_t z_slice_wrap(struct z_owned_slice_t *this_, const uint8_t *start, size_t len); ZENOHC_API const struct z_loaned_slice_t *z_str_as_slice(const struct z_loaned_str_t *this_); /** - * Returns ``true`` if `s` is a valid string + * Returns ``true`` if `this_` is a valid string, ``false`` if it is in gravestone state. */ ZENOHC_API bool z_str_check(const struct z_owned_str_t *this_); +/** + * Constructs an owned copy of a string. + */ ZENOHC_API void z_str_clone(const struct z_loaned_str_t *this_, struct z_owned_str_t *dst); +/** + * Returns the pointer of the string data. + */ ZENOHC_API const char *z_str_data(const struct z_loaned_str_t *this_); /** - * Frees `z_owned_str_t`, invalidating it for double-drop safety. + * Frees memory and invalidates `z_owned_str_t`, putting it in gravestone state. */ ZENOHC_API void z_str_drop(struct z_owned_str_t *this_); +/** + * Constructs an empty owned string. + */ ZENOHC_API void z_str_empty(struct z_owned_str_t *this_); /** - * Copies a a substring of length `len`into `z_owned_str_t`. + * Constructs an owned string by copying a `str` substring of length `len` (and adding terminating 0). * - * Calling this with `str == NULL` is equivalent to `z_str_null`. + * Returns -1 if `str == NULL` and `len > 0` (and creates a string in a gravestone state), 0 otherwise. + */ +ZENOHC_API +z_error_t z_str_from_substring(struct z_owned_str_t *this_, + const char *str, + size_t len); +/** + * Returns ``true`` if string is empty, ``false`` otherwise. + */ +ZENOHC_API bool z_str_is_empty(const struct z_loaned_str_t *this_); +/** + * Returns the length of the string (without terminating 0 character). */ -ZENOHC_API void z_str_from_substring(struct z_owned_str_t *this_, const char *str, size_t len); ZENOHC_API size_t z_str_len(const struct z_loaned_str_t *this_); /** - * Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_owned_str_t`. + * Returns a loaned string. */ ZENOHC_API const struct z_loaned_str_t *z_str_loan(const struct z_owned_str_t *this_); /** - * Returns undefined `z_owned_str_t` + * Constructs owned string in a gravestone state. */ ZENOHC_API void z_str_null(struct z_owned_str_t *this_); /** - * Copies a string into `z_owned_str_t` using `strlen` (this should therefore not be used with untrusted inputs). + * Constructs an owned string by copying `str` into it (including terminating 0), using `strlen` (this should therefore not be used with untrusted inputs). * - * Calling this with `str == NULL` is equivalent to `z_str_null`. + * Returns -1 if `str == NULL` (and creates a string in a gravestone state), 0 otherwise. */ ZENOHC_API -void z_str_wrap(struct z_owned_str_t *this_, - const char *str); +z_error_t z_str_wrap(struct z_owned_str_t *this_, + const char *str); /** * Returns ``true`` if `sub` is valid. */ @@ -2155,43 +2195,58 @@ ZENOHC_API void z_view_keyexpr_unchecked(struct z_view_keyexpr_t *this_, const char *s); /** - * Returns ``true`` if `this` is initialized. + * Returns ``true`` if the slice is not empty, ``false`` otherwise. */ ZENOHC_API bool z_view_slice_check(const struct z_view_slice_t *this_); /** - * Returns an empty `z_view_slice_t` + * Constructs an empty view slice. */ ZENOHC_API void z_view_slice_empty(struct z_view_slice_t *this_); /** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * Constructs a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). * - * Calling this with `str == NULL` is equivalent to `z_view_slice_null`. + * Returns -1 if `str == NULL` (and creates an empty view slice), 0 otherwise. + */ +ZENOHC_API +z_error_t z_view_slice_from_str(struct z_view_slice_t *this_, + const char *str); +/** + * Returns a loaned view slice. */ -ZENOHC_API void z_view_slice_from_str(struct z_view_slice_t *this_, const char *str); ZENOHC_API const struct z_loaned_slice_t *z_view_slice_loan(const struct z_view_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. + * + * Returns -1 if `start == NULL` and `len > 0` (and creates an empty view slice), 0 otherwise. */ -ZENOHC_API void z_view_slice_wrap(struct z_view_slice_t *this_, const uint8_t *start, size_t len); +ZENOHC_API +z_error_t z_view_slice_wrap(struct z_view_slice_t *this_, + const uint8_t *start, + size_t len); /** - * Returns ``true`` if `s` is a valid string + * Returns ``true`` if view string is valid, ``false`` if it is in a gravestone state. */ ZENOHC_API bool z_view_str_check(const struct z_view_str_t *this_); +/** + * Constructs an empty view string. + */ ZENOHC_API void z_view_str_empty(struct z_view_str_t *this_); /** - * Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_view_str_t`. + * Returns a loaned view string. */ ZENOHC_API const struct z_loaned_str_t *z_view_str_loan(const struct z_view_str_t *this_); /** - * Returns undefined `z_owned_str_t` + * Constructs view string in a gravestone state. */ ZENOHC_API void z_view_str_null(struct z_view_str_t *this_); /** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * Constructs a view string of `str`, using `strlen` (this should therefore not be used with untrusted inputs). * - * Calling this with `str == NULL` is equivalent to `z_view_str_null`. + * Returns -1 if `str == NULL` (and creates a string in a gravestone state), 0 otherwise. */ -ZENOHC_API void z_view_str_wrap(struct z_view_str_t *this_, const char *str); +ZENOHC_API +z_error_t z_view_str_wrap(struct z_view_str_t *this_, + const char *str); /** * Converts the kind of zenoh entity into a string. * diff --git a/src/collections.rs b/src/collections.rs index 34e36c30c..4144022d5 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -20,7 +20,7 @@ use std::slice::from_raw_parts; use libc::{c_char, c_void, strlen}; -use crate::errors; +use crate::errors::{self, z_error_t}; use crate::transmute::{ unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, @@ -127,58 +127,68 @@ decl_transmute_owned!(CSlice, z_owned_slice_t); decl_transmute_owned!(custom_inplace_init CSlice, z_view_slice_t); decl_transmute_handle!(CSlice, z_loaned_slice_t); -/// Returns an empty `z_view_slice_t` +/// Constructs an empty view slice. #[no_mangle] pub extern "C" fn z_view_slice_empty(this: *mut MaybeUninit) { Inplace::init(this.transmute_uninit_ptr(), CSlice::default()) } -/// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +/// Constructs a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// Calling this with `str == NULL` is equivalent to `z_view_slice_null`. +/// Returns -1 if `str == NULL` (and creates an empty view slice), 0 otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_view_slice_from_str( this: *mut MaybeUninit, str: *const c_char, -) { +) -> z_error_t { if str.is_null() { - z_view_slice_empty(this) + z_view_slice_empty(this); + errors::Z_EINVAL } else { - z_view_slice_wrap(this, str as *const u8, libc::strlen(str)) + z_view_slice_wrap(this, str as *const u8, libc::strlen(str)); + errors::Z_OK } } /// Constructs a `len` bytes long view starting at `start`. +/// +/// Returns -1 if `start == NULL` and `len > 0` (and creates an empty view slice), 0 otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_view_slice_wrap( this: *mut MaybeUninit, start: *const u8, len: usize, -) { - if len == 0 || start.is_null() { - z_view_slice_empty(this) +) -> z_error_t { + if len == 0 { + z_view_slice_empty(this); + errors::Z_OK + } else if start.is_null() { + z_view_slice_empty(this); + errors::Z_EINVAL } else { Inplace::init( this.transmute_uninit_ptr(), CSlice::new_borrowed(start, len), - ) + ); + errors::Z_OK } } +/// Returns a loaned view slice. #[no_mangle] pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> &z_loaned_slice_t { this.transmute_ref().transmute_handle() } -/// Returns ``true`` if `this` is initialized. +/// Returns ``true`` if the slice is not empty, ``false`` otherwise. #[no_mangle] pub extern "C" fn z_view_slice_check(this: &z_view_slice_t) -> bool { !this.transmute_ref().is_empty() } -/// Returns an empty `z_owned_slice_t` +/// Constructs an empty `z_owned_slice_t`. #[no_mangle] pub extern "C" fn z_slice_empty(this: *mut MaybeUninit) { Inplace::init(this.transmute_uninit_ptr(), CSlice::default()) @@ -186,36 +196,45 @@ pub extern "C" fn z_slice_empty(this: *mut MaybeUninit) { /// Copies a string into `z_owned_slice_t` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// Calling this with `str == NULL` is equivalent to `z_slice_null`. +/// Returns -1 if `str == NULL` (and creates an empty slice), 0 otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_slice_from_str( this: *mut MaybeUninit, str: *const c_char, -) { +) -> z_error_t { if str.is_null() { - z_slice_empty(this) + z_slice_empty(this); + errors::Z_EINVAL } else { - z_slice_wrap(this, str as *const u8, libc::strlen(str)) + z_slice_wrap(this, str as *const u8, libc::strlen(str)); + errors::Z_OK } } -/// Constructs a `len` bytes long view starting at `start`. +/// Constructs a slice by copying a `len` bytes long sequence starting at `start`. +/// +/// Returns -1 if `start == NULL` and `len > 0` (creating an empty slice), 0 otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_slice_wrap( this: *mut MaybeUninit, start: *const u8, len: usize, -) { - if len == 0 || start.is_null() { - z_slice_empty(this) +) -> z_error_t { + if len == 0 { + z_slice_empty(this); + errors::Z_OK + } else if start.is_null() { + z_slice_empty(this); + errors::Z_EINVAL } else { - Inplace::init(this.transmute_uninit_ptr(), CSlice::new_owned(start, len)) + Inplace::init(this.transmute_uninit_ptr(), CSlice::new_owned(start, len)); + errors::Z_OK } } -/// Frees `this` and invalidates it for double-drop safety. +/// Frees the memory and invalidates the slice. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { @@ -223,32 +242,42 @@ pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { Inplace::drop(this); } +/// Returns a loaned slice. #[no_mangle] pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> &z_loaned_slice_t { this.transmute_ref().transmute_handle() } +/// Constructs an owned copy of a slice. #[no_mangle] pub extern "C" fn z_slice_clone(this: &z_loaned_slice_t, dst: *mut MaybeUninit) { Inplace::init(dst.transmute_uninit_ptr(), this.transmute_ref().clone()); } -/// Returns ``true`` if `this` is initialized. +/// Returns ``true`` if slice is not empty, ``false`` otherwise. #[no_mangle] pub extern "C" fn z_slice_check(this: &z_owned_slice_t) -> bool { !this.transmute_ref().is_empty() } +/// Returns the length of the slice. #[no_mangle] pub extern "C" fn z_slice_len(this: &z_loaned_slice_t) -> usize { this.transmute_ref().len() } +/// Returns the pointer to the slice data. #[no_mangle] pub extern "C" fn z_slice_data(this: &z_loaned_slice_t) -> *const u8 { this.transmute_ref().data() } +/// Returns ``true`` if slice is empty, ``false`` otherwise. +#[no_mangle] +pub extern "C" fn z_slice_is_empty(this: &z_loaned_slice_t) -> bool { + this.transmute_ref().is_empty() +} + pub use crate::opaque_types::z_loaned_str_t; pub use crate::opaque_types::z_owned_str_t; pub use crate::opaque_types::z_view_str_t; @@ -257,50 +286,52 @@ decl_transmute_owned!(custom_inplace_init CSlice, z_owned_str_t); decl_transmute_owned!(custom_inplace_init CSlice, z_view_str_t); decl_transmute_handle!(CSlice, z_loaned_str_t); -/// Frees `z_owned_str_t`, invalidating it for double-drop safety. +/// Frees memory and invalidates `z_owned_str_t`, putting it in gravestone state. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_drop(this: &mut z_owned_str_t) { z_slice_drop(this.transmute_mut().transmute_mut()); } -/// Returns ``true`` if `s` is a valid string +/// Returns ``true`` if `this_` is a valid string, ``false`` if it is in gravestone state. #[no_mangle] pub extern "C" fn z_str_check(this: &z_owned_str_t) -> bool { z_slice_check(this.transmute_ref().transmute_ref()) } -/// Returns undefined `z_owned_str_t` +/// Constructs owned string in a gravestone state. #[no_mangle] pub extern "C" fn z_str_null(this: *mut MaybeUninit) { z_slice_empty(this as *mut _) } -/// Returns ``true`` if `s` is a valid string +/// Returns ``true`` if view string is valid, ``false`` if it is in a gravestone state. #[no_mangle] pub extern "C" fn z_view_str_check(this: &z_view_str_t) -> bool { z_view_slice_check(this.transmute_ref().transmute_ref()) } -/// Returns undefined `z_owned_str_t` +/// Constructs view string in a gravestone state. #[no_mangle] pub extern "C" fn z_view_str_null(this: *mut MaybeUninit) { z_view_slice_empty(this as *mut _) } +/// Constructs an empty owned string. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_empty(this: *mut MaybeUninit) { - z_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) + z_slice_wrap(this as *mut _, [0u8].as_ptr(), 1); } +/// Constructs an empty view string. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_view_str_empty(this: *mut MaybeUninit) { - z_view_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) + z_view_slice_wrap(this as *mut _, [0u8].as_ptr(), 1); } -/// Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_owned_str_t`. +/// Returns a loaned string. #[no_mangle] pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> Option<&z_loaned_str_t> { if !z_str_check(this) { @@ -313,7 +344,7 @@ pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> Option<&z_loaned_str_t> { ) } -/// Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_view_str_t`. +/// Returns a loaned view string. #[no_mangle] pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> Option<&z_loaned_str_t> { if !z_view_str_check(this) { @@ -326,66 +357,93 @@ pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> Option<&z_loaned_str_t ) } -/// Copies a string into `z_owned_str_t` using `strlen` (this should therefore not be used with untrusted inputs). +/// Constructs an owned string by copying `str` into it (including terminating 0), using `strlen` (this should therefore not be used with untrusted inputs). /// -/// Calling this with `str == NULL` is equivalent to `z_str_null`. +/// Returns -1 if `str == NULL` (and creates a string in a gravestone state), 0 otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_wrap( this: *mut MaybeUninit, str: *const libc::c_char, -) { - z_slice_wrap(this as *mut _, str as _, strlen(str) + 1) +) -> z_error_t { + if str.is_null() { + z_str_null(this); + errors::Z_EINVAL + } else { + z_slice_wrap(this as *mut _, str as _, strlen(str) + 1); + errors::Z_OK + } } -/// Copies a a substring of length `len`into `z_owned_str_t`. +/// Constructs an owned string by copying a `str` substring of length `len` (and adding terminating 0). /// -/// Calling this with `str == NULL` is equivalent to `z_str_null`. +/// Returns -1 if `str == NULL` and `len > 0` (and creates a string in a gravestone state), 0 otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_from_substring( this: *mut MaybeUninit, str: *const libc::c_char, len: usize, -) { - let mut v = vec![0u8; len + 1]; - v[0..len].copy_from_slice(from_raw_parts(str as *const u8, len)); - Inplace::init(this.transmute_uninit_ptr(), v.into()); +) -> z_error_t { + if str.is_null() && len != 0 { + z_str_null(this); + errors::Z_EINVAL + } else { + let mut v = vec![0u8; len + 1]; + v[0..len].copy_from_slice(from_raw_parts(str as *const u8, len)); + Inplace::init(this.transmute_uninit_ptr(), v.into()); + errors::Z_OK + } } -/// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +/// Constructs a view string of `str`, using `strlen` (this should therefore not be used with untrusted inputs). /// -/// Calling this with `str == NULL` is equivalent to `z_view_str_null`. +/// Returns -1 if `str == NULL` (and creates a string in a gravestone state), 0 otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_view_str_wrap( this: *mut MaybeUninit, str: *const libc::c_char, -) { - z_view_slice_wrap(this as *mut _, str as _, strlen(str) + 1) +) -> z_error_t { + if str.is_null() { + z_view_str_null(this); + errors::Z_EINVAL + } else { + z_view_slice_wrap(this as *mut _, str as _, strlen(str) + 1); + errors::Z_OK + } } +/// Returns the length of the string (without terminating 0 character). #[no_mangle] pub extern "C" fn z_str_len(this: &z_loaned_str_t) -> usize { z_slice_len(this.transmute_ref().transmute_handle()).max(1) - 1 } +/// Returns the pointer of the string data. #[no_mangle] pub extern "C" fn z_str_data(this: &z_loaned_str_t) -> *const libc::c_char { z_slice_data(this.transmute_ref().transmute_handle()) as _ } +/// Constructs an owned copy of a string. #[no_mangle] pub extern "C" fn z_str_clone(this: &z_loaned_str_t, dst: *mut MaybeUninit) { z_slice_clone(this.transmute_ref().transmute_handle(), dst as *mut _); } -// returns string as slice (with null-terminating character) +// Converts loaned string into loaned slice (with terminating 0 character). #[no_mangle] pub extern "C" fn z_str_as_slice(this: &z_loaned_str_t) -> &z_loaned_slice_t { this.transmute_ref().transmute_handle() } +/// Returns ``true`` if string is empty, ``false`` otherwise. +#[no_mangle] +pub extern "C" fn z_str_is_empty(this: &z_loaned_str_t) -> bool { + z_str_len(this) == 0 +} + pub use crate::opaque_types::z_loaned_slice_map_t; pub use crate::opaque_types::z_owned_slice_map_t; @@ -405,29 +463,28 @@ pub extern "C" fn z_slice_map_new(this: *mut MaybeUninit) { Inplace::init(this, Some(map)); } -/// Constructs the gravestone value for `z_owned_slice_map_t` +/// Constructs the gravestone value for :c:type:`z_owned_slice_map_t`. #[no_mangle] pub extern "C" fn z_slice_map_null(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); Inplace::empty(this); } -/// Returns `true` if the map is not in its gravestone state +/// Returns ``true`` if the map is not in its gravestone state, ``false`` otherwise. #[no_mangle] pub extern "C" fn z_slice_map_check(map: &z_owned_slice_map_t) -> bool { let map = map.transmute_ref(); map.as_ref().is_some() } -/// Destroys the map, resetting `this` to its gravestone value. -/// -/// This function is double-free safe, passing a pointer to the gravestone value will have no effect. +/// Destroys the map, resetting it to its gravestone value. #[no_mangle] pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { let this = this.transmute_mut(); Inplace::drop(this); } +/// Returns a loaned slice map. #[no_mangle] pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_loaned_slice_map_t { let this = this.transmute_ref(); @@ -435,6 +492,7 @@ pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_loaned_slic this.transmute_handle() } +/// Returns a mutable loaned slice map. #[no_mangle] pub extern "C" fn z_slice_map_loan_mut( this: &mut z_owned_slice_map_t, @@ -450,26 +508,22 @@ pub extern "C" fn z_slice_map_len(this: &z_loaned_slice_map_t) -> usize { this.transmute_ref().len() } -/// Returns true if the map is empty, false otherwise. +/// Returns ``true`` if the map is empty, ``false`` otherwise. #[no_mangle] pub extern "C" fn z_slice_map_is_empty(this: &z_loaned_slice_map_t) -> bool { z_slice_map_len(this) == 0 } -/// The body of a loop over a z_slice_map's key-value pairs. -/// -/// `key` and `value` are loaned to the body for the duration of a single call. -/// `context` is passed transparently through the iteration driver. -/// -/// Returning `true` is treated as `break`. -#[allow(non_camel_case_types)] -pub type z_slice_map_iter_body_t = - extern "C" fn(key: &z_loaned_slice_t, value: &z_loaned_slice_t, context: *mut c_void) -> bool; - +/// Iterates over key-value pairs of a slice map. +/// +/// Parameters: +/// this_: Slice map to iterate over. +/// body: Iterator body function. Returning `true` is treated as iteration loop `break`. +/// context: Some data passed to every body invocation. #[no_mangle] pub extern "C" fn z_slice_map_iterate( this: &z_loaned_slice_map_t, - body: z_slice_map_iter_body_t, + body: extern "C" fn(key: &z_loaned_slice_t, value: &z_loaned_slice_t, context: *mut c_void) -> bool, context: *mut c_void, ) { let this = this.transmute_ref(); @@ -482,7 +536,7 @@ pub extern "C" fn z_slice_map_iterate( /// Returns the value associated with `key`. /// -/// Will return NULL if the key is not present in the map. +/// Will return `NULL` if the key is not present in the map. #[no_mangle] pub extern "C" fn z_slice_map_get( this: &z_loaned_slice_map_t, @@ -495,6 +549,7 @@ pub extern "C" fn z_slice_map_get( /// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. /// +/// If the `key` was already present in the map, its value is updated. /// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_copy( @@ -513,8 +568,7 @@ pub extern "C" fn z_slice_map_insert_by_copy( /// Associates `value` to `key` in the map, aliasing them. /// -/// Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. -/// +/// If the `key` was already present in the map, its value is updated. /// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_alias( @@ -539,7 +593,7 @@ decl_transmute_handle!(Vec, z_loaned_slice_array_t); decl_transmute_owned!(Option>, z_owned_slice_array_t); -/// Constructs a new empty array. +/// Constructs a new empty slice array. #[no_mangle] pub extern "C" fn z_slice_array_new(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); @@ -547,29 +601,28 @@ pub extern "C" fn z_slice_array_new(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); Inplace::empty(this); } -/// Returns `true` if the array is not in its gravestone state +/// Returns ``true`` if the slice array is valid, ``false`` if it is in a gravestone state. #[no_mangle] pub extern "C" fn z_slice_array_check(this: &z_owned_slice_array_t) -> bool { let this = this.transmute_ref(); this.as_ref().is_some() } -/// Destroys the array, resetting `this` to its gravestone value. -/// -/// This function is double-free safe, passing a pointer to the gravestone value will have no effect. +/// Destroys the slice array, resetting it to its gravestone value. #[no_mangle] pub extern "C" fn z_slice_array_drop(this: &mut z_owned_slice_array_t) { let this = this.transmute_mut(); Inplace::drop(this); } +/// Returns a loaned slice array. #[no_mangle] pub extern "C" fn z_slice_array_loan(this: &z_owned_slice_array_t) -> &z_loaned_slice_array_t { let this = this.transmute_ref(); @@ -577,6 +630,7 @@ pub extern "C" fn z_slice_array_loan(this: &z_owned_slice_array_t) -> &z_loaned_ this.transmute_handle() } +/// Returns a mutable loaned slice array. #[no_mangle] pub extern "C" fn z_slice_array_loan_mut( this: &mut z_owned_slice_array_t, @@ -586,21 +640,21 @@ pub extern "C" fn z_slice_array_loan_mut( this.transmute_handle_mut() } -/// Returns number of key-value pairs in the map. +/// Returns number of elements in the array. #[no_mangle] pub extern "C" fn z_slice_array_len(this: &z_loaned_slice_array_t) -> usize { this.transmute_ref().len() } -/// Returns true if the array is empty, false otherwise. +/// Returns ``true`` if the array is empty, ``false`` otherwise. #[no_mangle] pub extern "C" fn z_slice_array_is_empty(this: &z_loaned_slice_array_t) -> bool { z_slice_array_len(this) == 0 } -/// Returns the value at the position of index in the array. +/// Returns the value at the position of index in the slice array. /// -/// Will return NULL if the index is out of bounds. +/// Will return `NULL` if the index is out of bounds. #[no_mangle] pub extern "C" fn z_slice_array_get( this: &z_loaned_slice_array_t, @@ -614,7 +668,7 @@ pub extern "C" fn z_slice_array_get( Some(a[index].transmute_handle()) } -/// Appends specified value to the end of the array by copying. +/// Appends specified value to the end of the slice array by copying. /// /// Returns the new length of the array. #[no_mangle] @@ -629,7 +683,7 @@ pub extern "C" fn z_slice_array_push_by_copy( this.len() } -/// Appends specified value to the end of the array by aliasing. +/// Appends specified value to the end of the slice array by alias. /// /// Returns the new length of the array. #[no_mangle] From 312c05ed78934745be619b66ae8e9405d93eee54 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 6 May 2024 19:22:08 +0200 Subject: [PATCH 083/377] docs for commons --- build-resources/opaque-types/src/lib.rs | 4 +- docs/api.rst | 142 ++++++++------ include/zenoh_commons.h | 234 +++++++++++++++--------- include/zenoh_macros.h | 4 + src/collections.rs | 28 ++- src/commons.rs | 141 +++++++------- src/transmute.rs | 2 + 7 files changed, 326 insertions(+), 229 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index fad58475b..ebeab3935 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -88,9 +88,9 @@ get_opaque_type_data!(Sample, z_loaned_sample_t); get_opaque_type_data!(Option>, z_owned_bytes_reader_t); get_opaque_type_data!(ZBytesReader<'static>, z_loaned_bytes_reader_t); -/// The encoding of Zenoh payload, (for example in a MIME-like format). +/// The `encoding `_ of Zenoh data. get_opaque_type_data!(Encoding, z_loaned_encoding_t); -/// A loaned Zenoh-encoding. +/// A loaned Zenoh encoding. get_opaque_type_data!(Encoding, z_owned_encoding_t); /// An owned reply from a Quryable to a :c:func:`z_get`. diff --git a/docs/api.rst b/docs/api.rst index 0cac3e582..0b6cbc1a6 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -28,6 +28,8 @@ Slice .. autocfunction:: zenoh_commons.h::z_slice_empty .. autocfunction:: zenoh_commons.h::z_view_slice_empty +.. autocfunction:: zenoh_commons.h::z_slice_null +.. autocfunction:: zenoh_commons.h::z_view_slice_null .. autocfunction:: zenoh_commons.h::z_slice_wrap .. autocfunction:: zenoh_commons.h::z_view_slice_wrap .. autocfunction:: zenoh_commons.h::z_slice_from_str @@ -102,6 +104,78 @@ Slice array Common ====== +Key expression +-------------- + +.. autocstruct:: zenoh_commons.h::z_view_keyexpr_t +.. autocstruct:: zenoh_commons.h::z_loaned_keyexpr_t +.. autocstruct:: zenoh_commons.h::z_owned_keyexpr_t + +.. autocfunction:: zenoh_commons.h::z_keyexpr_new +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_new +.. autocfunction:: zenoh_commons.h::z_keyexpr_new_autocanonize +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_new_autocanonize +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_unchecked +.. autocfunction:: zenoh_commons.h::z_keyexpr_loan +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_loan +.. autocfunction:: zenoh_commons.h::z_keyexpr_check +.. autocfunction:: zenoh_commons.h::z_view_keyexpr_check +.. autocfunction:: zenoh_commons.h::z_keyexpr_drop +.. autocfunction:: zenoh_commons.h::z_keyexpr_to_string +.. autocfunction:: zenoh_commons.h::z_keyexpr_as_slice +.. autocfunction:: zenoh_commons.h::z_keyexpr_canonize +.. autocfunction:: zenoh_commons.h::z_keyexpr_canonize_null_terminated +.. autocfunction:: zenoh_commons.h::z_keyexpr_is_canon +.. autocfunction:: zenoh_commons.h::z_keyexpr_concat +.. autocfunction:: zenoh_commons.h::z_keyexpr_join +.. autocfunction:: zenoh_commons.h::z_keyexpr_equals +.. autocfunction:: zenoh_commons.h::z_keyexpr_includes +.. autocfunction:: zenoh_commons.h::z_keyexpr_intersects +.. autocfunction:: zenoh_commons.h::z_declare_keyexpr +.. autocfunction:: zenoh_commons.h::z_undeclare_keyexpr + +Encoding +-------- + +.. autocstruct:: zenoh_commons.h::z_loaned_encoding_t +.. autocstruct:: zenoh_commons.h::z_owned_encoding_t + +.. autocfunction:: zenoh_commons.h::z_encoding_default +.. autocfunction:: zenoh_commons.h::z_encoding_null + +.. autocfunction:: zenoh_commons.h::z_encoding_loan +.. autocfunction:: zenoh_commons.h::z_encoding_check +.. autocfunction:: zenoh_commons.h::z_encoding_drop +.. autocfunction:: zenoh_commons.h::z_encoding_from_str + +Value +----- + +.. autocstruct:: zenoh_commons.h::z_loaned_value_t + +.. autocfunction:: zenoh_commons.h::z_value_payload +.. autocfunction:: zenoh_commons.h::z_value_encoding + +Sample +------ + +.. autocstruct:: zenoh_commons.h::z_loaned_sample_t +.. autocstruct:: zenoh_commons.h::z_owned_sample_t + +.. autocfunction:: zenoh_commons.h::z_sample_loan +.. autocfunction:: zenoh_commons.h::z_sample_check +.. autocfunction:: zenoh_commons.h::z_sample_null +.. autocfunction:: zenoh_commons.h::z_sample_drop +.. autocfunction:: zenoh_commons.h::z_sample_timestamp +.. autocfunction:: zenoh_commons.h::z_sample_attachment +.. autocfunction:: zenoh_commons.h::z_sample_encoding +.. autocfunction:: zenoh_commons.h::z_sample_payload +.. autocfunction:: zenoh_commons.h::z_sample_priority +.. autocfunction:: zenoh_commons.h::z_sample_congestion_control +.. autocfunction:: zenoh_commons.h::z_sample_express + + + Timestamp --------- .. autocstruct:: zenoh_commons.h::z_timestamp_t @@ -204,64 +278,6 @@ Functions .. autocfunction:: zenoh_commons.h::z_closure_zid_call .. autocfunction:: zenoh_commons.h::z_closure_zid_drop - -Key expression -============== - -.. autocstruct:: zenoh_commons.h::z_view_keyexpr_t -.. autocstruct:: zenoh_commons.h::z_loaned_keyexpr_t -.. autocstruct:: zenoh_commons.h::z_owned_keyexpr_t - -.. autocfunction:: zenoh_commons.h::z_keyexpr_new -.. autocfunction:: zenoh_commons.h::z_view_keyexpr_new -.. autocfunction:: zenoh_commons.h::z_keyexpr_new_autocanonize -.. autocfunction:: zenoh_commons.h::z_view_keyexpr_new_autocanonize -.. autocfunction:: zenoh_commons.h::z_view_keyexpr_unchecked -.. autocfunction:: zenoh_commons.h::z_keyexpr_loan -.. autocfunction:: zenoh_commons.h::z_view_keyexpr_loan -.. autocfunction:: zenoh_commons.h::z_keyexpr_check -.. autocfunction:: zenoh_commons.h::z_view_keyexpr_check -.. autocfunction:: zenoh_commons.h::z_keyexpr_drop -.. autocfunction:: zenoh_commons.h::z_keyexpr_to_string -.. autocfunction:: zenoh_commons.h::z_keyexpr_as_slice -.. autocfunction:: zenoh_commons.h::z_keyexpr_canonize -.. autocfunction:: zenoh_commons.h::z_keyexpr_canonize_null_terminated -.. autocfunction:: zenoh_commons.h::z_keyexpr_is_canon -.. autocfunction:: zenoh_commons.h::z_keyexpr_concat -.. autocfunction:: zenoh_commons.h::z_keyexpr_join -.. autocfunction:: zenoh_commons.h::z_keyexpr_equals -.. autocfunction:: zenoh_commons.h::z_keyexpr_includes -.. autocfunction:: zenoh_commons.h::z_keyexpr_intersects - - - - -.. autocfunction:: zenoh_commons.h::z_declare_keyexpr -.. autocfunction:: zenoh_commons.h::z_undeclare_keyexpr - -Encoding -======== - -.. autocstruct:: zenoh_commons.h::z_loaned_encoding_t -.. autocstruct:: zenoh_commons.h::z_owned_encoding_t - -.. autocfunction:: zenoh_commons.h::z_encoding_default - -.. autocfunction:: zenoh_commons.h::z_encoding_loan -.. autocfunction:: zenoh_commons.h::z_encoding_check -.. autocfunction:: zenoh_commons.h::z_encoding_drop - -Value -===== - -.. autocstruct:: zenoh_commons.h::z_loaned_value_t - -Sample -====== - -.. autocstruct:: zenoh_commons.h::z_loaned_sample_t -.. autocstruct:: zenoh_commons.h::z_owned_sample_t - Publication =========== @@ -270,8 +286,10 @@ Types .. autocstruct:: zenoh_commons.h::z_loaned_publisher_t .. autocstruct:: zenoh_commons.h::z_owned_publisher_t -.. autocstruct:: zenoh_commons.h::z_congestion_control_t -.. autocstruct:: zenoh_commons.h::z_priority_t +.. autocenum:: zenoh_commons.h::z_congestion_control_t + :members: +.. autocenum:: zenoh_commons.h::z_priority_t + :members: .. autocstruct:: zenoh_commons.h::z_put_options_t .. autocfunction:: zenoh_commons.h::z_put_options_default @@ -329,8 +347,10 @@ Types .. autocstruct:: zenoh_commons.h::z_get_options_t .. autocenum:: zenoh_commons.h::z_query_target_t + :members: .. autocenum:: zenoh_commons.h::z_consolidation_mode_t + :members: .. c:type:: z_query_consolidation_t @@ -421,6 +441,8 @@ Types .. autocstruct:: zenoh_commons.h::ze_publication_cache_options_t .. autocstruct:: zenoh_concrete.h::ze_owned_publication_cache_t +.. autocenum:: zenoh_commons.h::zcu_locality_t + :members: Functions --------- diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 3cee7e68c..4a2d5a855 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -15,34 +15,41 @@ #define ALIGN(n) #define ZENOHC_API #endif -/** - * The kind of congestion control. - * - * - **BLOCK** - * - **DROP** - */ typedef enum z_congestion_control_t { + /** + * Block + */ Z_CONGESTION_CONTROL_BLOCK, + /** + * Drop + */ Z_CONGESTION_CONTROL_DROP, } z_congestion_control_t; /** * Consolidation mode values. - * - * - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector - * If the selector contains time range properties, consolidation mode `NONE` is used. - * Otherwise the `LATEST` consolidation mode is used. - * - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. - * - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time - * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple - * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp - * ts2 > ts1. It optimizes latency. - * - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. - * It optimizes bandwidth. */ typedef enum z_consolidation_mode_t { + /** + * Let Zenoh decide the best consolidation mode depending on the query selector. + * If the selector contains time range properties, consolidation mode `NONE` is used. + * Otherwise the `LATEST` consolidation mode is used. + */ Z_CONSOLIDATION_MODE_AUTO = -1, + /** + * No consolidation is applied. Replies may come in any order and any number. + */ Z_CONSOLIDATION_MODE_NONE = 0, + /** + * It guarantees that any reply for a given key expression will be monotonic in time + * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple + * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp + * ts2 > ts1. It optimizes latency. + */ Z_CONSOLIDATION_MODE_MONOTONIC = 1, + /** + * It guarantees unicity of replies for the same key expression. + * It optimizes bandwidth. + */ Z_CONSOLIDATION_MODE_LATEST = 2, } z_consolidation_mode_t; /** @@ -61,34 +68,52 @@ typedef enum z_keyexpr_intersection_level_t { } z_keyexpr_intersection_level_t; /** * The priority of zenoh messages. - * - * - **REAL_TIME** - * - **INTERACTIVE_HIGH** - * - **INTERACTIVE_LOW** - * - **DATA_HIGH** - * - **DATA** - * - **DATA_LOW** - * - **BACKGROUND** */ typedef enum z_priority_t { + /** + * REAL_TIME + */ Z_PRIORITY_REAL_TIME = 1, + /** + * INTERACTIVE_HIGFH + */ Z_PRIORITY_INTERACTIVE_HIGH = 2, + /** + * INTERACTIVE_LOW + */ Z_PRIORITY_INTERACTIVE_LOW = 3, + /** + * DATA_HIGH + */ Z_PRIORITY_DATA_HIGH = 4, + /** + * DATA + */ Z_PRIORITY_DATA = 5, + /** + * DATA_LOW + */ Z_PRIORITY_DATA_LOW = 6, + /** + * BACKGROUND + */ Z_PRIORITY_BACKGROUND = 7, } z_priority_t; /** * The Queryables that should be target of a :c:func:`z_get`. - * - * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. - * - **ALL_COMPLETE**: All complete queryables. - * - **ALL**: All matching queryables. */ typedef enum z_query_target_t { + /** + * The nearest complete queryable if any else all matching queryables. + */ Z_QUERY_TARGET_BEST_MATCHING, + /** + * All matching queryables. + */ Z_QUERY_TARGET_ALL, + /** + * All complete queryables. + */ Z_QUERY_TARGET_ALL_COMPLETE, } z_query_target_t; /** @@ -102,16 +127,43 @@ typedef enum z_reliability_t { Z_RELIABILITY_RELIABLE, } z_reliability_t; typedef enum z_sample_kind_t { + /** + * PUT + */ Z_SAMPLE_KIND_PUT = 0, + /** + * DELETE + */ Z_SAMPLE_KIND_DELETE = 1, } z_sample_kind_t; +/** + * The locality of samples to be received by subscribers or targeted by publishers. + */ typedef enum zcu_locality_t { + /** + * Any + */ ZCU_LOCALITY_ANY = 0, + /** + * Only from local sessions. + */ ZCU_LOCALITY_SESSION_LOCAL = 1, + /** + * Only from remote sessions. + */ ZCU_LOCALITY_REMOTE = 2, } zcu_locality_t; +/** + * Key expressions types to which Queryable should reply to. + */ typedef enum zcu_reply_keyexpr_t { + /** + * Replies to any key expression queries. + */ ZCU_REPLY_KEYEXPR_ANY = 0, + /** + * Replies only to queries with intersecting key expressions. + */ ZCU_REPLY_KEYEXPR_MATCHING_QUERY = 1, } zcu_reply_keyexpr_t; /** @@ -454,13 +506,13 @@ typedef struct z_delete_options_t { enum z_priority_t priority; } z_delete_options_t; /** - * A loaned Zenoh-encoding. + * A loaned Zenoh encoding. */ typedef struct ALIGN(8) z_owned_encoding_t { uint8_t _0[48]; } z_owned_encoding_t; /** - * The encoding of Zenoh payload, (for example in a MIME-like format). + * The `encoding `_ of Zenoh data. */ typedef struct ALIGN(8) z_loaned_encoding_t { uint8_t _0[48]; @@ -509,14 +561,6 @@ typedef struct ALIGN(8) z_owned_slice_array_t { typedef struct ALIGN(8) z_view_slice_t { uint8_t _0[16]; } z_view_slice_t; -/** - * A Zenoh `timestamp `_. - * - * It consists of a time generated by a Hybrid Logical Clock (HLC) in NPT64 format and a unique zenoh identifier. - */ -typedef struct ALIGN(8) z_timestamp_t { - uint8_t _0[24]; -} z_timestamp_t; /** * An owned mutex. */ @@ -645,6 +689,14 @@ typedef struct z_owned_reply_channel_t { typedef struct ALIGN(8) z_owned_sample_t { uint8_t _0[240]; } z_owned_sample_t; +/** + * A Zenoh `timestamp `_. + * + * It consists of a time generated by a Hybrid Logical Clock (HLC) in NPT64 format and a unique zenoh identifier. + */ +typedef struct ALIGN(8) z_timestamp_t { + uint8_t _0[24]; +} z_timestamp_t; typedef struct z_owned_scouting_config_t { struct z_owned_config_t _config; unsigned long zc_timeout_ms; @@ -1187,7 +1239,7 @@ z_error_t z_delete(const struct z_loaned_session_t *session, */ ZENOHC_API void z_delete_options_default(struct z_delete_options_t *this_); /** - * Returns ``true`` if `encoding` is valid. + * Returns ``true`` if `encoding` is in non-default state, ``false`` otherwise. */ ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); /** @@ -1195,20 +1247,20 @@ ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); */ ZENOHC_API const struct z_loaned_encoding_t *z_encoding_default(void); /** - * Frees `encoding`, invalidating it for double-drop safety. + * Frees memory `encoding`, resetting encoding to its default value. */ ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); /** - * Constructs a specific :c:type:`z_loaned_encoding_t`. + * Constructs a :c:type:`z_owned_encoding_t` from a specified string. */ ZENOHC_API z_error_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); /** - * Returns a :c:type:`z_loaned_encoding_t` loaned from `encoding`. + * Borrows encoding. */ ZENOHC_API const struct z_loaned_encoding_t *z_encoding_loan(const struct z_owned_encoding_t *encoding); /** - * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type + * Constructs a default :c:type:`z_owned_encoding_t`. */ ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); /** @@ -1400,14 +1452,6 @@ enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_loaned_ * The user is responsible of droping the returned string using `z_drop` */ ZENOHC_API void z_keyexpr_to_string(const struct z_loaned_keyexpr_t *ke, struct z_owned_str_t *s); -/** - * The samples timestamp - * - * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. - */ -ZENOHC_API -bool z_loaned_sample_timestamp(const struct z_loaned_sample_t *sample, - struct z_timestamp_t *timestamp_out); ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); ZENOHC_API z_error_t z_mutex_init(struct z_owned_mutex_t *this_); @@ -1718,62 +1762,71 @@ ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); ZENOHC_API const struct z_loaned_sample_t *z_reply_ok(const struct z_loaned_reply_t *reply); /** - * The qos with which the sample was received. - * TODO: split to methods (priority, congestion_control, express) - * Gets sample's attachment. + * Returns sample attachment. * - * Returns NULL if sample does not contain an attachement. + * Returns `NULL`, if sample does not contain any attachement. */ ZENOHC_API const struct z_loaned_bytes_t *z_sample_attachment(const struct z_loaned_sample_t *sample); /** - * Returns `true` if `sample` is valid. - * - * Note that there exist no fallinle constructors for `z_owned_sample_t`, so validity is always guaranteed - * unless the value has been dropped already. + * Returns ``true`` if sample is valid, ``false`` if it is in gravestone state. + */ +ZENOHC_API bool z_sample_check(const struct z_owned_sample_t *sample); +/** + * Construct a shallow copy of the sample (i.e. all modficiations applied to the copy, might be visible in the original). */ ZENOHC_API -bool z_sample_check(const struct z_owned_sample_t *sample); +void z_sample_clone(const struct z_loaned_sample_t *src, + struct z_owned_sample_t *dst); /** - * Clone a sample in the cheapest way available. + * Returns sample qos congestion control value. */ -ZENOHC_API void z_sample_clone(const struct z_loaned_sample_t *src, struct z_owned_sample_t *dst); ZENOHC_API enum z_congestion_control_t z_sample_congestion_control(const struct z_loaned_sample_t *sample); /** - * Destroy the sample. + * Frees the memory and invalidates the sample, resetting it to a gravestone state. */ ZENOHC_API void z_sample_drop(struct z_owned_sample_t *sample); /** - * The encoding of the payload. + * Returns the encoding associated with the sample data. */ ZENOHC_API const struct z_loaned_encoding_t *z_sample_encoding(const struct z_loaned_sample_t *sample); +/** + * Returns whether sample qos express flag was set or not. + */ ZENOHC_API bool z_sample_express(const struct z_loaned_sample_t *sample); /** - * The Key Expression of the sample. - * - * `sample` is aliased by its return value. + * Returns the key expression of the sample. */ ZENOHC_API const struct z_loaned_keyexpr_t *z_sample_keyexpr(const struct z_loaned_sample_t *sample); /** - * The sample's kind (put or delete). + * Returns the sample kind. */ ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_loaned_sample_t *sample); /** - * Borrow the sample, allowing calling its accessor methods. - * - * Calling this function using a dropped sample is undefined behaviour. + * Borrows sample. */ ZENOHC_API const struct z_loaned_sample_t *z_sample_loan(const struct z_owned_sample_t *sample); +/** + * Constructs sample in its gravestone state. + */ ZENOHC_API void z_sample_null(struct z_owned_sample_t *sample); /** - * The sample's data, the return value aliases the sample. - * + * Returns the sample payload data. */ ZENOHC_API const struct z_loaned_bytes_t *z_sample_payload(const struct z_loaned_sample_t *sample); +/** + * Returns sample qos priority value. + */ ZENOHC_API enum z_priority_t z_sample_priority(const struct z_loaned_sample_t *sample); +/** + * Returns the sample timestamp. + * + * Will return `NULL`, if sample is not associated with a timestamp. + */ +ZENOHC_API const struct z_timestamp_t *z_sample_timestamp(const struct z_loaned_sample_t *sample); /** * Scout for routers and/or peers. * @@ -1842,12 +1895,12 @@ ZENOHC_API bool z_slice_array_is_empty(const struct z_loaned_slice_array_t *this */ ZENOHC_API size_t z_slice_array_len(const struct z_loaned_slice_array_t *this_); /** - * Returns a loaned slice array. + * Borrows slice array. */ ZENOHC_API const struct z_loaned_slice_array_t *z_slice_array_loan(const struct z_owned_slice_array_t *this_); /** - * Returns a mutable loaned slice array. + * Mutably borrows slice array. */ ZENOHC_API struct z_loaned_slice_array_t *z_slice_array_loan_mut(struct z_owned_slice_array_t *this_); @@ -1912,7 +1965,7 @@ ZENOHC_API bool z_slice_is_empty(const struct z_loaned_slice_t *this_); */ ZENOHC_API size_t z_slice_len(const struct z_loaned_slice_t *this_); /** - * Returns a loaned slice. + * Borrows slice. */ ZENOHC_API const struct z_loaned_slice_t *z_slice_loan(const struct z_owned_slice_t *this_); /** @@ -1974,12 +2027,12 @@ void z_slice_map_iterate(const struct z_loaned_slice_map_t *this_, */ ZENOHC_API size_t z_slice_map_len(const struct z_loaned_slice_map_t *this_); /** - * Returns a loaned slice map. + * Borrows slice map. */ ZENOHC_API const struct z_loaned_slice_map_t *z_slice_map_loan(const struct z_owned_slice_map_t *this_); /** - * Returns a mutable loaned slice map. + * Mutably borrows slice map. */ ZENOHC_API struct z_loaned_slice_map_t *z_slice_map_loan_mut(struct z_owned_slice_map_t *this_); /** @@ -1990,6 +2043,10 @@ ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); * Constructs the gravestone value for :c:type:`z_owned_slice_map_t`. */ ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); +/** + * Constructs an empty `z_owned_slice_t`. + */ +ZENOHC_API void z_slice_null(struct z_owned_slice_t *this_); /** * Constructs a slice by copying a `len` bytes long sequence starting at `start`. * @@ -2035,7 +2092,7 @@ ZENOHC_API bool z_str_is_empty(const struct z_loaned_str_t *this_); */ ZENOHC_API size_t z_str_len(const struct z_loaned_str_t *this_); /** - * Returns a loaned string. + * Borrows string. */ ZENOHC_API const struct z_loaned_str_t *z_str_loan(const struct z_owned_str_t *this_); /** @@ -2124,7 +2181,13 @@ ZENOHC_API z_error_t z_undeclare_queryable(struct z_owned_queryable_t *qable); */ ZENOHC_API z_error_t z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); +/** + * Returns value encoding. + */ ZENOHC_API const struct z_loaned_encoding_t *z_value_encoding(const struct z_loaned_value_t *this_); +/** + * Returns value payload. + */ ZENOHC_API const struct z_loaned_bytes_t *z_value_payload(const struct z_loaned_value_t *this_); /** * Returns ``true`` if `keyexpr` is valid. @@ -2211,9 +2274,13 @@ ZENOHC_API z_error_t z_view_slice_from_str(struct z_view_slice_t *this_, const char *str); /** - * Returns a loaned view slice. + * Borrows view slice. */ ZENOHC_API const struct z_loaned_slice_t *z_view_slice_loan(const struct z_view_slice_t *this_); +/** + * Constructs an empty view slice. + */ +ZENOHC_API void z_view_slice_null(struct z_view_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. * @@ -2232,7 +2299,7 @@ ZENOHC_API bool z_view_str_check(const struct z_view_str_t *this_); */ ZENOHC_API void z_view_str_empty(struct z_view_str_t *this_); /** - * Returns a loaned view string. + * Borrows view string. */ ZENOHC_API const struct z_loaned_str_t *z_view_str_loan(const struct z_view_str_t *this_); /** @@ -2448,6 +2515,9 @@ void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type */ ZENOHC_API void zcu_closure_matching_status_null(struct zcu_owned_closure_matching_status_t *this_); +/** + * Returns default value of :c:type:`zcu_locality_t` + */ ZENOHC_API enum zcu_locality_t zcu_locality_default(void); /** * Register callback for notifying subscribers matching. diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 26d6f6ec2..5c3a34559 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -99,10 +99,12 @@ z_owned_session_t * : z_session_null, \ z_owned_slice_array_t * : z_slice_array_null, \ z_owned_slice_map_t * : z_slice_map_null, \ + z_owned_slice_t * : z_slice_null, \ z_owned_str_t * : z_str_null, \ z_owned_subscriber_t * : z_subscriber_null, \ z_owned_task_t * : z_task_null, \ z_view_keyexpr_t * : z_view_keyexpr_null, \ + z_view_slice_t * : z_view_slice_null, \ z_view_str_t * : z_view_str_null, \ zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ @@ -246,10 +248,12 @@ inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config inline void z_null( z_owned_session_t* this_) { return z_session_null(this_); }; inline void z_null( z_owned_slice_array_t* this_) { return z_slice_array_null(this_); }; inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; +inline void z_null( z_owned_slice_t* this_) { return z_slice_null(this_); }; inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; inline void z_null( z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; inline void z_null( z_owned_task_t* this_) { return z_task_null(this_); }; inline void z_null( z_view_keyexpr_t* this_) { return z_view_keyexpr_null(this_); }; +inline void z_null( z_view_slice_t* this_) { return z_view_slice_null(this_); }; inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; inline void z_null( zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_null(this_); }; inline void z_null( zcu_owned_closure_matching_status_t* this_) { return zcu_closure_matching_status_null(this_); }; diff --git a/src/collections.rs b/src/collections.rs index 4144022d5..04af12269 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -133,6 +133,12 @@ pub extern "C" fn z_view_slice_empty(this: *mut MaybeUninit) { Inplace::init(this.transmute_uninit_ptr(), CSlice::default()) } +/// Constructs an empty view slice. +#[no_mangle] +pub extern "C" fn z_view_slice_null(this: *mut MaybeUninit) { + Inplace::init(this.transmute_uninit_ptr(), CSlice::default()) +} + /// Constructs a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// /// Returns -1 if `str == NULL` (and creates an empty view slice), 0 otherwise. @@ -176,7 +182,7 @@ pub unsafe extern "C" fn z_view_slice_wrap( } } -/// Returns a loaned view slice. +/// Borrows view slice. #[no_mangle] pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> &z_loaned_slice_t { this.transmute_ref().transmute_handle() @@ -194,6 +200,12 @@ pub extern "C" fn z_slice_empty(this: *mut MaybeUninit) { Inplace::init(this.transmute_uninit_ptr(), CSlice::default()) } +/// Constructs an empty `z_owned_slice_t`. +#[no_mangle] +pub extern "C" fn z_slice_null(this: *mut MaybeUninit) { + z_slice_empty(this); +} + /// Copies a string into `z_owned_slice_t` using `strlen` (this should therefore not be used with untrusted inputs). /// /// Returns -1 if `str == NULL` (and creates an empty slice), 0 otherwise. @@ -242,7 +254,7 @@ pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { Inplace::drop(this); } -/// Returns a loaned slice. +/// Borrows slice. #[no_mangle] pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> &z_loaned_slice_t { this.transmute_ref().transmute_handle() @@ -331,7 +343,7 @@ pub unsafe extern "C" fn z_view_str_empty(this: *mut MaybeUninit) z_view_slice_wrap(this as *mut _, [0u8].as_ptr(), 1); } -/// Returns a loaned string. +/// Borrows string. #[no_mangle] pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> Option<&z_loaned_str_t> { if !z_str_check(this) { @@ -344,7 +356,7 @@ pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> Option<&z_loaned_str_t> { ) } -/// Returns a loaned view string. +/// Borrows view string. #[no_mangle] pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> Option<&z_loaned_str_t> { if !z_view_str_check(this) { @@ -484,7 +496,7 @@ pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { Inplace::drop(this); } -/// Returns a loaned slice map. +/// Borrows slice map. #[no_mangle] pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_loaned_slice_map_t { let this = this.transmute_ref(); @@ -492,7 +504,7 @@ pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_loaned_slic this.transmute_handle() } -/// Returns a mutable loaned slice map. +/// Mutably borrows slice map. #[no_mangle] pub extern "C" fn z_slice_map_loan_mut( this: &mut z_owned_slice_map_t, @@ -622,7 +634,7 @@ pub extern "C" fn z_slice_array_drop(this: &mut z_owned_slice_array_t) { Inplace::drop(this); } -/// Returns a loaned slice array. +/// Borrows slice array. #[no_mangle] pub extern "C" fn z_slice_array_loan(this: &z_owned_slice_array_t) -> &z_loaned_slice_array_t { let this = this.transmute_ref(); @@ -630,7 +642,7 @@ pub extern "C" fn z_slice_array_loan(this: &z_owned_slice_array_t) -> &z_loaned_ this.transmute_handle() } -/// Returns a mutable loaned slice array. +/// Mutably borrows slice array. #[no_mangle] pub extern "C" fn z_slice_array_loan_mut( this: &mut z_owned_slice_array_t, diff --git a/src/commons.rs b/src/commons.rs index 77838a09d..557c1e06f 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -51,7 +51,9 @@ pub type z_zint_t = c_ulong; #[repr(C)] #[derive(Clone, Copy, Debug)] pub enum z_sample_kind_t { + /// PUT PUT = 0, + /// DELETE DELETE = 1, } @@ -87,62 +89,50 @@ pub extern "C" fn z_timestamp_id(timestamp: &z_timestamp_t) -> z_id_t { timestamp.transmute_copy().get_id().to_le_bytes().into() } -/// A data sample. -/// -/// A sample is the value associated to a given resource at a given point in time. use crate::opaque_types::z_loaned_sample_t; decl_transmute_handle!(Sample, z_loaned_sample_t); -/// The Key Expression of the sample. -/// -/// `sample` is aliased by its return value. +/// Returns the key expression of the sample. #[no_mangle] pub extern "C" fn z_sample_keyexpr(sample: &z_loaned_sample_t) -> &z_loaned_keyexpr_t { let sample = sample.transmute_ref(); sample.key_expr().transmute_handle() } -/// The encoding of the payload. +/// Returns the encoding associated with the sample data. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: &z_loaned_sample_t) -> &z_loaned_encoding_t { let sample = sample.transmute_ref(); sample.encoding().transmute_handle() } -/// The sample's data, the return value aliases the sample. -/// +/// Returns the sample payload data. #[no_mangle] pub extern "C" fn z_sample_payload(sample: &z_loaned_sample_t) -> &z_loaned_bytes_t { let sample = sample.transmute_ref(); sample.payload().transmute_handle() } -/// The sample's kind (put or delete). +/// Returns the sample kind. #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_loaned_sample_t) -> z_sample_kind_t { let sample = sample.transmute_ref(); sample.kind().into() } -/// The samples timestamp -/// -/// Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. +/// Returns the sample timestamp. +/// +/// Will return `NULL`, if sample is not associated with a timestamp. #[no_mangle] -pub extern "C" fn z_loaned_sample_timestamp( - sample: &z_loaned_sample_t, - timestamp_out: &mut z_timestamp_t, -) -> bool { +pub extern "C" fn z_sample_timestamp(sample: &z_loaned_sample_t) -> Option<&z_timestamp_t> { let sample = sample.transmute_ref(); if let Some(t) = sample.timestamp() { - *timestamp_out = t.transmute_copy(); - true + Some(t.transmute_ref()) } else { - false + None } } -/// The qos with which the sample was received. -/// TODO: split to methods (priority, congestion_control, express) -/// Gets sample's attachment. +/// Returns sample attachment. /// -/// Returns NULL if sample does not contain an attachement. +/// Returns `NULL`, if sample does not contain any attachement. #[no_mangle] pub extern "C" fn z_sample_attachment(sample: &z_loaned_sample_t) -> *const z_loaned_bytes_t { let sample = sample.transmute_ref(); @@ -155,7 +145,7 @@ pub extern "C" fn z_sample_attachment(sample: &z_loaned_sample_t) -> *const z_lo pub use crate::opaque_types::z_owned_sample_t; decl_transmute_owned!(Option, z_owned_sample_t); -/// Clone a sample in the cheapest way available. +/// Construct a shallow copy of the sample (i.e. all modficiations applied to the copy, might be visible in the original). #[no_mangle] pub extern "C" fn z_sample_clone(src: &z_loaned_sample_t, dst: *mut MaybeUninit) { let src = src.transmute_ref(); @@ -164,18 +154,21 @@ pub extern "C" fn z_sample_clone(src: &z_loaned_sample_t, dst: *mut MaybeUninit< Inplace::init(dst, Some(src)); } +/// Returns sample qos priority value. #[no_mangle] pub extern "C" fn z_sample_priority(sample: &z_loaned_sample_t) -> z_priority_t { let sample = sample.transmute_ref(); sample.priority().into() } +/// Returns whether sample qos express flag was set or not. #[no_mangle] pub extern "C" fn z_sample_express(sample: &z_loaned_sample_t) -> bool { let sample = sample.transmute_ref(); sample.express() } +/// Returns sample qos congestion control value. #[no_mangle] pub extern "C" fn z_sample_congestion_control( sample: &z_loaned_sample_t, @@ -184,30 +177,26 @@ pub extern "C" fn z_sample_congestion_control( sample.congestion_control().into() } -/// Returns `true` if `sample` is valid. -/// -/// Note that there exist no fallinle constructors for `z_owned_sample_t`, so validity is always guaranteed -/// unless the value has been dropped already. +/// Returns ``true`` if sample is valid, ``false`` if it is in gravestone state. #[no_mangle] pub extern "C" fn z_sample_check(sample: &z_owned_sample_t) -> bool { let sample = sample.transmute_ref(); sample.is_some() } -/// Borrow the sample, allowing calling its accessor methods. -/// -/// Calling this function using a dropped sample is undefined behaviour. +/// Borrows sample. #[no_mangle] pub extern "C" fn z_sample_loan(sample: &z_owned_sample_t) -> &z_loaned_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } -/// Destroy the sample. +/// Frees the memory and invalidates the sample, resetting it to a gravestone state. #[no_mangle] pub extern "C" fn z_sample_drop(sample: &mut z_owned_sample_t) { Inplace::drop(sample.transmute_mut()); } +/// Constructs sample in its gravestone state. #[no_mangle] pub extern "C" fn z_sample_null(sample: *mut MaybeUninit) { Inplace::empty(sample.transmute_uninit_ptr()); @@ -216,23 +205,10 @@ pub extern "C" fn z_sample_null(sample: *mut MaybeUninit) { pub use crate::opaque_types::z_loaned_encoding_t; decl_transmute_handle!(Encoding, z_loaned_encoding_t); -/// An owned payload encoding. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_encoding_t; decl_transmute_owned!(Encoding, z_owned_encoding_t); -/// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type -#[no_mangle] -pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { - Inplace::empty(encoding.transmute_uninit_ptr()); -} - -/// Constructs a specific :c:type:`z_loaned_encoding_t`. +/// Constructs a :c:type:`z_owned_encoding_t` from a specified string. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_from_str( @@ -258,21 +234,27 @@ pub extern "C" fn z_encoding_default() -> &'static z_loaned_encoding_t { Encoding::ZENOH_BYTES.transmute_handle() } -/// Frees `encoding`, invalidating it for double-drop safety. +/// Constructs a default :c:type:`z_owned_encoding_t`. +#[no_mangle] +pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { + Inplace::empty(encoding.transmute_uninit_ptr()); +} + +/// Frees memory `encoding`, resetting encoding to its default value. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { Inplace::drop(encoding.transmute_mut()); } -/// Returns ``true`` if `encoding` is valid. +/// Returns ``true`` if `encoding` is in non-default state, ``false`` otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> bool { *encoding.transmute_ref() != Encoding::default() } -/// Returns a :c:type:`z_loaned_encoding_t` loaned from `encoding`. +/// Borrows encoding. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> &z_loaned_encoding_t { @@ -284,21 +266,27 @@ decl_transmute_owned!(Value, z_owned_value_t); pub use crate::opaque_types::z_loaned_value_t; decl_transmute_handle!(Value, z_loaned_value_t); +/// Returns value payload. #[no_mangle] pub extern "C" fn z_value_payload(this: &z_loaned_value_t) -> &z_loaned_bytes_t { this.transmute_ref().payload().transmute_handle() } +/// Returns value encoding. #[no_mangle] pub extern "C" fn z_value_encoding(this: &z_loaned_value_t) -> &z_loaned_encoding_t { this.transmute_ref().encoding().transmute_handle() } +/// The locality of samples to be received by subscribers or targeted by publishers. #[repr(C)] #[derive(Clone, Copy, Debug)] pub enum zcu_locality_t { + /// Any ANY = 0, + /// Only from local sessions. SESSION_LOCAL = 1, + /// Only from remote sessions. REMOTE = 2, } @@ -322,15 +310,19 @@ impl From for Locality { } } +/// Returns default value of :c:type:`zcu_locality_t` #[no_mangle] pub extern "C" fn zcu_locality_default() -> zcu_locality_t { Locality::default().into() } +/// Key expressions types to which Queryable should reply to. #[repr(C)] #[derive(Clone, Copy, Debug)] pub enum zcu_reply_keyexpr_t { + /// Replies to any key expression queries. ANY = 0, + /// Replies only to queries with intersecting key expressions. MATCHING_QUERY = 1, } @@ -358,16 +350,15 @@ pub extern "C" fn zcu_reply_keyexpr_default() -> zcu_reply_keyexpr_t { } /// The Queryables that should be target of a :c:func:`z_get`. -/// -/// - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. -/// - **ALL_COMPLETE**: All complete queryables. -/// - **ALL**: All matching queryables. #[allow(non_camel_case_types)] #[repr(C)] #[derive(Clone, Copy)] pub enum z_query_target_t { + /// The nearest complete queryable if any else all matching queryables. BEST_MATCHING, + /// All matching queryables. ALL, + /// All complete queryables. ALL_COMPLETE, } @@ -400,24 +391,23 @@ pub extern "C" fn z_query_target_default() -> z_query_target_t { } /// Consolidation mode values. -/// -/// - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector -/// If the selector contains time range properties, consolidation mode `NONE` is used. -/// Otherwise the `LATEST` consolidation mode is used. -/// - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. -/// - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time -/// w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple -/// replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp -/// ts2 > ts1. It optimizes latency. -/// - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. -/// It optimizes bandwidth. #[repr(C)] #[derive(Clone, Copy, Default)] pub enum z_consolidation_mode_t { +/// Let Zenoh decide the best consolidation mode depending on the query selector. +/// If the selector contains time range properties, consolidation mode `NONE` is used. +/// Otherwise the `LATEST` consolidation mode is used. AUTO = -1, #[default] + /// No consolidation is applied. Replies may come in any order and any number. NONE = 0, + /// It guarantees that any reply for a given key expression will be monotonic in time + /// w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple + /// replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp + /// ts2 > ts1. It optimizes latency. MONOTONIC = 1, + /// It guarantees unicity of replies for the same key expression. + /// It optimizes bandwidth. LATEST = 2, } @@ -446,24 +436,23 @@ impl From for ConsolidationMode { } /// The priority of zenoh messages. -/// -/// - **REAL_TIME** -/// - **INTERACTIVE_HIGH** -/// - **INTERACTIVE_LOW** -/// - **DATA_HIGH** -/// - **DATA** -/// - **DATA_LOW** -/// - **BACKGROUND** #[allow(non_camel_case_types)] #[repr(C)] #[derive(Clone, Copy)] pub enum z_priority_t { + /// REAL_TIME REAL_TIME = 1, + /// INTERACTIVE_HIGFH INTERACTIVE_HIGH = 2, + /// INTERACTIVE_LOW INTERACTIVE_LOW = 3, + /// DATA_HIGH DATA_HIGH = 4, + /// DATA DATA = 5, + /// DATA_LOW DATA_LOW = 6, + /// BACKGROUND BACKGROUND = 7, } @@ -495,15 +484,13 @@ impl From for Priority { } } -/// The kind of congestion control. -/// -/// - **BLOCK** -/// - **DROP** #[allow(non_camel_case_types)] #[repr(C)] #[derive(Clone, Copy)] pub enum z_congestion_control_t { + /// Block BLOCK, + /// Drop DROP, } diff --git a/src/transmute.rs b/src/transmute.rs index 181b17e36..7c7dc328f 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -157,6 +157,8 @@ macro_rules! decl_transmute_copy { validate_equivalence!($zenoh_type, $c_type); impl_transmute_copy!($zenoh_type, $c_type); impl_transmute_copy!($c_type, $zenoh_type); + impl_transmute_ref!($zenoh_type, $c_type); + impl_transmute_ref!($c_type, $zenoh_type); impl_transmute_uninit_ptr!($zenoh_type, $c_type); impl_transmute_uninit_ptr!($c_type, $zenoh_type); }; From 19cda4a9d116b16e18af9f9dcc162d90be77be5a Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 7 May 2024 10:34:26 +0200 Subject: [PATCH 084/377] fix docs for commons --- build-resources/opaque-types/src/lib.rs | 4 +- docs/api.rst | 7 +- include/zenoh_commons.h | 103 +++++++++-------- include/zenoh_concrete.h | 2 +- include/zenoh_macros.h | 16 +-- src/collections.rs | 12 +- src/commons.rs | 142 +++++++++++------------- src/get.rs | 11 +- 8 files changed, 158 insertions(+), 139 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index ebeab3935..f34bedbc7 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -208,7 +208,7 @@ get_opaque_type_data!(LivelinessToken<'static>, zc_loaned_liveliness_token_t); /// An owned Zenoh publication cache. /// -/// Used to store publications on intersecting key expressions. Can be queried later via :c:func:z_get to retrieve this data +/// Used to store publications on intersecting key expressions. Can be queried later via :c:func:`z_get` to retrieve this data /// (for example by Querying Subscriber). get_opaque_type_data!(Option>, ze_owned_publication_cache_t); /// A loaned Zenoh publication cache. @@ -221,7 +221,7 @@ get_opaque_type_data!((Mutex<()>, Option>), z_loaned_mut /// An owned conditional variable. /// -/// Used in combination with to wake up thread when certain conditions are met. +/// Used in combination with :c:type:`z_owned_mutex_t` to wake up thread when certain conditions are met. get_opaque_type_data!(Option, z_owned_condvar_t); /// A loaned conditional variable. get_opaque_type_data!(Condvar, z_loaned_condvar_t); diff --git a/docs/api.rst b/docs/api.rst index 0b6cbc1a6..4238f5598 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -140,7 +140,7 @@ Encoding .. autocstruct:: zenoh_commons.h::z_loaned_encoding_t .. autocstruct:: zenoh_commons.h::z_owned_encoding_t -.. autocfunction:: zenoh_commons.h::z_encoding_default +.. autocfunction:: zenoh_commons.h::z_encoding_loan_default .. autocfunction:: zenoh_commons.h::z_encoding_null .. autocfunction:: zenoh_commons.h::z_encoding_loan @@ -161,6 +161,8 @@ Sample .. autocstruct:: zenoh_commons.h::z_loaned_sample_t .. autocstruct:: zenoh_commons.h::z_owned_sample_t +.. autocenum:: zenoh_commons.h::z_sample_kind_t + :members: .. autocfunction:: zenoh_commons.h::z_sample_loan .. autocfunction:: zenoh_commons.h::z_sample_check @@ -364,6 +366,7 @@ Types .. autocfunction:: zenoh_commons.h::z_query_consolidation_none .. autocfunction:: zenoh_commons.h::z_query_consolidation_monotonic .. autocfunction:: zenoh_commons.h::z_query_consolidation_latest +.. autocfunction:: zenoh_commons.h::z_query_target_default .. autocstruct:: zenoh_commons.h::z_owned_reply_t .. autocstruct:: zenoh_commons.h::z_loaned_reply_t @@ -462,6 +465,7 @@ Types .. autocstruct:: zenoh_concrete.h::ze_owned_querying_subscriber_t .. autocstruct:: zenoh_concrete.h::ze_loaned_querying_subscriber_t .. autocstruct:: zenoh_commons.h::ze_querying_subscriber_options_t +.. autocenum:: zenoh_commons.h::zcu_reply_keyexpr_t Functions --------- @@ -472,3 +476,4 @@ Functions .. autocfunction:: zenoh_commons.h::ze_querying_subscriber_check .. autocfunction:: zenoh_commons.h::ze_querying_subscriber_null .. autocfunction:: zenoh_commons.h::ze_querying_subscriber_options_default +.. autocfunction:: zenoh_commons.h::zcu_reply_keyexpr_default diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 4a2d5a855..9d56cb6bd 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -17,11 +17,11 @@ #endif typedef enum z_congestion_control_t { /** - * Block + * Messages are not dropped in case of congestion. */ Z_CONGESTION_CONTROL_BLOCK, /** - * Drop + * Messages are dropped in case of congestion. */ Z_CONGESTION_CONTROL_DROP, } z_congestion_control_t; @@ -71,31 +71,31 @@ typedef enum z_keyexpr_intersection_level_t { */ typedef enum z_priority_t { /** - * REAL_TIME + * Priority for ``RealTime`` messages. */ Z_PRIORITY_REAL_TIME = 1, /** - * INTERACTIVE_HIGFH + * Highest priority for ``Interactive`` messages. */ Z_PRIORITY_INTERACTIVE_HIGH = 2, /** - * INTERACTIVE_LOW + * Lowest priority for ``Interactive`` messages. */ Z_PRIORITY_INTERACTIVE_LOW = 3, /** - * DATA_HIGH + * Highest priority for ``Data`` messages. */ Z_PRIORITY_DATA_HIGH = 4, /** - * DATA + * Default priority for ``Data`` messages. */ Z_PRIORITY_DATA = 5, /** - * DATA_LOW + * Lowest priority for ``Data`` messages. */ Z_PRIORITY_DATA_LOW = 6, /** - * BACKGROUND + * Priority for ``Background traffic`` messages. */ Z_PRIORITY_BACKGROUND = 7, } z_priority_t; @@ -128,11 +128,11 @@ typedef enum z_reliability_t { } z_reliability_t; typedef enum z_sample_kind_t { /** - * PUT + * The Sample was issued by a ``put`` operation. */ Z_SAMPLE_KIND_PUT = 0, /** - * DELETE + * The Sample was issued by a ``delete`` operation. */ Z_SAMPLE_KIND_DELETE = 1, } z_sample_kind_t; @@ -399,7 +399,7 @@ typedef struct z_owned_closure_zid_t { /** * An owned conditional variable. * - * Used in combination with to wake up thread when certain conditions are met. + * Used in combination with :c:type:`z_owned_mutex_t` to wake up thread when certain conditions are met. */ typedef struct ALIGN(8) z_owned_condvar_t { uint8_t _0[24]; @@ -1239,30 +1239,30 @@ z_error_t z_delete(const struct z_loaned_session_t *session, */ ZENOHC_API void z_delete_options_default(struct z_delete_options_t *this_); /** - * Returns ``true`` if `encoding` is in non-default state, ``false`` otherwise. + * Returns ``true`` if encoding is in non-default state, ``false`` otherwise. */ -ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); +ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *this_); /** - * Returns a default :c:type:`z_loaned_encoding_t`. + * Frees the memory and resets the encoding it to its default value. */ -ZENOHC_API const struct z_loaned_encoding_t *z_encoding_default(void); -/** - * Frees memory `encoding`, resetting encoding to its default value. - */ -ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); +ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *this_); /** * Constructs a :c:type:`z_owned_encoding_t` from a specified string. */ -ZENOHC_API z_error_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); +ZENOHC_API z_error_t z_encoding_from_str(struct z_owned_encoding_t *this_, const char *s); /** * Borrows encoding. */ ZENOHC_API -const struct z_loaned_encoding_t *z_encoding_loan(const struct z_owned_encoding_t *encoding); +const struct z_loaned_encoding_t *z_encoding_loan(const struct z_owned_encoding_t *this_); +/** + * Returns a loaned default :c:type:`z_loaned_encoding_t`. + */ +ZENOHC_API const struct z_loaned_encoding_t *z_encoding_loan_default(void); /** * Constructs a default :c:type:`z_owned_encoding_t`. */ -ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); +ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *this_); /** * Query data from the matching queryables in the system. * Replies are provided through a callback function. @@ -1609,15 +1609,24 @@ ZENOHC_API struct z_query_consolidation_t z_query_consolidation_auto(void); */ ZENOHC_API struct z_query_consolidation_t z_query_consolidation_default(void); /** - * Latest value consolidation. + * Latest consolidation. + * + * This strategy optimizes bandwidth on all links in the system but will provide a very poor latency. */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_latest(void); +ZENOHC_API +struct z_query_consolidation_t z_query_consolidation_latest(void); /** * Monotonic consolidation. + * + * This strategy offers the best latency. Replies are directly transmitted to the application when received + * without needing to wait for all replies. This mode does not guarantee that there will be no duplicates. */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_monotonic(void); +ZENOHC_API +struct z_query_consolidation_t z_query_consolidation_monotonic(void); /** - * Disable consolidation. + * No consolidation. + * + * This strategy is useful when querying timeseries data bases or when using quorums. */ ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); /** @@ -1767,66 +1776,65 @@ const struct z_loaned_sample_t *z_reply_ok(const struct z_loaned_reply_t *reply) * Returns `NULL`, if sample does not contain any attachement. */ ZENOHC_API -const struct z_loaned_bytes_t *z_sample_attachment(const struct z_loaned_sample_t *sample); +const struct z_loaned_bytes_t *z_sample_attachment(const struct z_loaned_sample_t *this_); /** * Returns ``true`` if sample is valid, ``false`` if it is in gravestone state. */ -ZENOHC_API bool z_sample_check(const struct z_owned_sample_t *sample); +ZENOHC_API bool z_sample_check(const struct z_owned_sample_t *this_); /** * Construct a shallow copy of the sample (i.e. all modficiations applied to the copy, might be visible in the original). */ ZENOHC_API -void z_sample_clone(const struct z_loaned_sample_t *src, +void z_sample_clone(const struct z_loaned_sample_t *this_, struct z_owned_sample_t *dst); /** * Returns sample qos congestion control value. */ ZENOHC_API -enum z_congestion_control_t z_sample_congestion_control(const struct z_loaned_sample_t *sample); +enum z_congestion_control_t z_sample_congestion_control(const struct z_loaned_sample_t *this_); /** * Frees the memory and invalidates the sample, resetting it to a gravestone state. */ -ZENOHC_API void z_sample_drop(struct z_owned_sample_t *sample); +ZENOHC_API void z_sample_drop(struct z_owned_sample_t *this_); /** * Returns the encoding associated with the sample data. */ ZENOHC_API -const struct z_loaned_encoding_t *z_sample_encoding(const struct z_loaned_sample_t *sample); +const struct z_loaned_encoding_t *z_sample_encoding(const struct z_loaned_sample_t *this_); /** * Returns whether sample qos express flag was set or not. */ -ZENOHC_API bool z_sample_express(const struct z_loaned_sample_t *sample); +ZENOHC_API bool z_sample_express(const struct z_loaned_sample_t *this_); /** * Returns the key expression of the sample. */ -ZENOHC_API -const struct z_loaned_keyexpr_t *z_sample_keyexpr(const struct z_loaned_sample_t *sample); +ZENOHC_API const struct z_loaned_keyexpr_t *z_sample_keyexpr(const struct z_loaned_sample_t *this_); /** * Returns the sample kind. */ -ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_loaned_sample_t *sample); +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_loaned_sample_t *this_); /** * Borrows sample. */ -ZENOHC_API const struct z_loaned_sample_t *z_sample_loan(const struct z_owned_sample_t *sample); +ZENOHC_API const struct z_loaned_sample_t *z_sample_loan(const struct z_owned_sample_t *this_); /** * Constructs sample in its gravestone state. */ -ZENOHC_API void z_sample_null(struct z_owned_sample_t *sample); +ZENOHC_API void z_sample_null(struct z_owned_sample_t *this_); /** * Returns the sample payload data. */ -ZENOHC_API const struct z_loaned_bytes_t *z_sample_payload(const struct z_loaned_sample_t *sample); +ZENOHC_API const struct z_loaned_bytes_t *z_sample_payload(const struct z_loaned_sample_t *this_); /** * Returns sample qos priority value. */ -ZENOHC_API enum z_priority_t z_sample_priority(const struct z_loaned_sample_t *sample); +ZENOHC_API enum z_priority_t z_sample_priority(const struct z_loaned_sample_t *this_); /** * Returns the sample timestamp. * * Will return `NULL`, if sample is not associated with a timestamp. */ -ZENOHC_API const struct z_timestamp_t *z_sample_timestamp(const struct z_loaned_sample_t *sample); +ZENOHC_API const struct z_timestamp_t *z_sample_timestamp(const struct z_loaned_sample_t *this_); /** * Scout for routers and/or peers. * @@ -2150,13 +2158,13 @@ ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); ZENOHC_API struct z_time_t z_time_now(void); ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); /** - * Returns id associated with this `timestamp` + * Returns id associated with this timestamp. */ -ZENOHC_API struct z_id_t z_timestamp_id(const struct z_timestamp_t *timestamp); +ZENOHC_API struct z_id_t z_timestamp_id(const struct z_timestamp_t *this_); /** - * Returns NPT64 time associated with this `timestamp` + * Returns NPT64 time associated with this timestamp. */ -ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); +ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *this_); /** * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. * The keyxpr is consumed. @@ -2526,6 +2534,9 @@ ZENOHC_API z_error_t zcu_publisher_matching_listener_callback(struct zcu_owned_matching_listener_t *this_, const struct z_loaned_publisher_t *publisher, struct zcu_owned_closure_matching_status_t *callback); +/** + * Returns the default value of :c:type:`zcu_reply_keyexpr_t` + */ ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); /** * Declares a Publication Cache. diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index c3f6c6391..8e75174e8 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -64,7 +64,7 @@ typedef struct ALIGN(8) z_loaned_subscriber_t { /** * An owned Zenoh publication cache. * - * Used to store publications on intersecting key expressions. Can be queried later via :c:func:z_get to retrieve this data + * Used to store publications on intersecting key expressions. Can be queried later via :c:func:`z_get` to retrieve this data * (for example by Querying Subscriber). */ typedef struct ALIGN(8) ze_owned_publication_cache_t { diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 5c3a34559..b296768cf 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -166,13 +166,13 @@ inline const z_loaned_bytes_t* z_loan(const z_owned_bytes_t* payload) { return z inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t* reader) { return z_bytes_reader_loan(reader); }; inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t* this_) { return z_condvar_loan(this_); }; inline const z_loaned_config_t* z_loan(const z_owned_config_t* this_) { return z_config_loan(this_); }; -inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* encoding) { return z_encoding_loan(encoding); }; +inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* this_) { return z_encoding_loan(this_); }; inline const z_loaned_hello_t* z_loan(const z_owned_hello_t* this_) { return z_hello_loan(this_); }; inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t* key_expr) { return z_keyexpr_loan(key_expr); }; inline const z_loaned_publisher_t* z_loan(const z_owned_publisher_t* this_) { return z_publisher_loan(this_); }; inline const z_loaned_query_t* z_loan(const z_owned_query_t* this_) { return z_query_loan(this_); }; inline const z_loaned_reply_t* z_loan(const z_owned_reply_t* this_) { return z_reply_loan(this_); }; -inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* sample) { return z_sample_loan(sample); }; +inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* this_) { return z_sample_loan(this_); }; inline const z_loaned_session_t* z_loan(const z_owned_session_t* this_) { return z_session_loan(this_); }; inline const z_loaned_slice_array_t* z_loan(const z_owned_slice_array_t* this_) { return z_slice_array_loan(this_); }; inline const z_loaned_slice_t* z_loan(const z_owned_slice_t* this_) { return z_slice_loan(this_); }; @@ -203,7 +203,7 @@ inline void z_drop(const z_owned_closure_sample_t* closure) { return z_closure_s inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; inline void z_drop(const z_owned_condvar_t* this_) { return z_condvar_drop(this_); }; inline void z_drop(const z_owned_config_t* config) { return z_config_drop(config); }; -inline void z_drop(const z_owned_encoding_t* encoding) { return z_encoding_drop(encoding); }; +inline void z_drop(const z_owned_encoding_t* this_) { return z_encoding_drop(this_); }; inline void z_drop(const z_owned_hello_t* this_) { return z_hello_drop(this_); }; inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; inline void z_drop(const z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; @@ -213,7 +213,7 @@ inline void z_drop(const z_owned_query_t* this_) { return z_query_drop(this_); } inline void z_drop(const z_owned_reply_channel_closure_t* closure) { return z_reply_channel_closure_drop(closure); }; inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_channel_drop(channel); }; inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; -inline void z_drop(const z_owned_sample_t* sample) { return z_sample_drop(sample); }; +inline void z_drop(const z_owned_sample_t* this_) { return z_sample_drop(this_); }; inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; inline void z_drop(const z_owned_slice_array_t* this_) { return z_slice_array_drop(this_); }; inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; @@ -232,7 +232,7 @@ inline void z_null( z_owned_closure_sample_t* this_) { return z_closure_sample_n inline void z_null( z_owned_closure_zid_t* this_) { return z_closure_zid_null(this_); }; inline void z_null( z_owned_condvar_t* this_) { return z_condvar_null(this_); }; inline void z_null( z_owned_config_t* this_) { return z_config_null(this_); }; -inline void z_null( z_owned_encoding_t* encoding) { return z_encoding_null(encoding); }; +inline void z_null( z_owned_encoding_t* this_) { return z_encoding_null(this_); }; inline void z_null( z_owned_hello_t* this_) { return z_hello_null(this_); }; inline void z_null( z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; inline void z_null( z_owned_mutex_t* this_) { return z_mutex_null(this_); }; @@ -243,7 +243,7 @@ inline void z_null( z_owned_queryable_t* this_) { return z_queryable_null(this_) inline void z_null( z_owned_reply_channel_closure_t* this_) { return z_reply_channel_closure_null(this_); }; inline void z_null( z_owned_reply_channel_t* this_) { return z_reply_channel_null(this_); }; inline void z_null( z_owned_reply_t* this_) { return z_reply_null(this_); }; -inline void z_null( z_owned_sample_t* sample) { return z_sample_null(sample); }; +inline void z_null( z_owned_sample_t* this_) { return z_sample_null(this_); }; inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; inline void z_null( z_owned_session_t* this_) { return z_session_null(this_); }; inline void z_null( z_owned_slice_array_t* this_) { return z_slice_array_null(this_); }; @@ -265,7 +265,7 @@ inline bool z_check(const z_owned_bytes_t& payload) { return z_bytes_check(&payl inline bool z_check(const z_owned_bytes_reader_t& this_) { return z_bytes_reader_check(&this_); }; inline bool z_check(const z_owned_condvar_t& this_) { return z_condvar_check(&this_); }; inline bool z_check(const z_owned_config_t& config) { return z_config_check(&config); }; -inline bool z_check(const z_owned_encoding_t& encoding) { return z_encoding_check(&encoding); }; +inline bool z_check(const z_owned_encoding_t& this_) { return z_encoding_check(&this_); }; inline bool z_check(const z_owned_hello_t& this_) { return z_hello_check(&this_); }; inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; inline bool z_check(const z_owned_mutex_t& this_) { return z_mutex_check(&this_); }; @@ -273,7 +273,7 @@ inline bool z_check(const z_owned_publisher_t& this_) { return z_publisher_check inline bool z_check(const z_owned_query_t& query) { return z_query_check(&query); }; inline bool z_check(const z_owned_queryable_t& qable) { return z_queryable_check(&qable); }; inline bool z_check(const z_owned_reply_t& this_) { return z_reply_check(&this_); }; -inline bool z_check(const z_owned_sample_t& sample) { return z_sample_check(&sample); }; +inline bool z_check(const z_owned_sample_t& this_) { return z_sample_check(&this_); }; inline bool z_check(const z_owned_scouting_config_t& config) { return z_scouting_config_check(&config); }; inline bool z_check(const z_owned_session_t& this_) { return z_session_check(&this_); }; inline bool z_check(const z_owned_slice_array_t& this_) { return z_slice_array_check(&this_); }; diff --git a/src/collections.rs b/src/collections.rs index 04af12269..bfd2b96cf 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -158,7 +158,7 @@ pub unsafe extern "C" fn z_view_slice_from_str( } /// Constructs a `len` bytes long view starting at `start`. -/// +/// /// Returns -1 if `start == NULL` and `len > 0` (and creates an empty view slice), 0 otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -225,7 +225,7 @@ pub unsafe extern "C" fn z_slice_from_str( } /// Constructs a slice by copying a `len` bytes long sequence starting at `start`. -/// +/// /// Returns -1 if `start == NULL` and `len > 0` (creating an empty slice), 0 otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -527,7 +527,7 @@ pub extern "C" fn z_slice_map_is_empty(this: &z_loaned_slice_map_t) -> bool { } /// Iterates over key-value pairs of a slice map. -/// +/// /// Parameters: /// this_: Slice map to iterate over. /// body: Iterator body function. Returning `true` is treated as iteration loop `break`. @@ -535,7 +535,11 @@ pub extern "C" fn z_slice_map_is_empty(this: &z_loaned_slice_map_t) -> bool { #[no_mangle] pub extern "C" fn z_slice_map_iterate( this: &z_loaned_slice_map_t, - body: extern "C" fn(key: &z_loaned_slice_t, value: &z_loaned_slice_t, context: *mut c_void) -> bool, + body: extern "C" fn( + key: &z_loaned_slice_t, + value: &z_loaned_slice_t, + context: *mut c_void, + ) -> bool, context: *mut c_void, ) { let this = this.transmute_ref(); diff --git a/src/commons.rs b/src/commons.rs index 557c1e06f..ac9996360 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -51,9 +51,9 @@ pub type z_zint_t = c_ulong; #[repr(C)] #[derive(Clone, Copy, Debug)] pub enum z_sample_kind_t { - /// PUT + /// The Sample was issued by a ``put`` operation. PUT = 0, - /// DELETE + /// The Sample was issued by a ``delete`` operation. DELETE = 1, } @@ -77,16 +77,16 @@ impl From for SampleKind { use crate::opaque_types::z_timestamp_t; decl_transmute_copy!(Timestamp, z_timestamp_t); -/// Returns NPT64 time associated with this `timestamp` +/// Returns NPT64 time associated with this timestamp. #[no_mangle] -pub extern "C" fn z_timestamp_npt64_time(timestamp: &z_timestamp_t) -> u64 { - timestamp.transmute_copy().get_time().0 +pub extern "C" fn z_timestamp_npt64_time(this: &z_timestamp_t) -> u64 { + this.transmute_copy().get_time().0 } -/// Returns id associated with this `timestamp` +/// Returns id associated with this timestamp. #[no_mangle] -pub extern "C" fn z_timestamp_id(timestamp: &z_timestamp_t) -> z_id_t { - timestamp.transmute_copy().get_id().to_le_bytes().into() +pub extern "C" fn z_timestamp_id(this: &z_timestamp_t) -> z_id_t { + this.transmute_copy().get_id().to_le_bytes().into() } use crate::opaque_types::z_loaned_sample_t; @@ -94,36 +94,31 @@ decl_transmute_handle!(Sample, z_loaned_sample_t); /// Returns the key expression of the sample. #[no_mangle] -pub extern "C" fn z_sample_keyexpr(sample: &z_loaned_sample_t) -> &z_loaned_keyexpr_t { - let sample = sample.transmute_ref(); - sample.key_expr().transmute_handle() +pub extern "C" fn z_sample_keyexpr(this: &z_loaned_sample_t) -> &z_loaned_keyexpr_t { + this.transmute_ref().key_expr().transmute_handle() } /// Returns the encoding associated with the sample data. #[no_mangle] -pub extern "C" fn z_sample_encoding(sample: &z_loaned_sample_t) -> &z_loaned_encoding_t { - let sample = sample.transmute_ref(); - sample.encoding().transmute_handle() +pub extern "C" fn z_sample_encoding(this: &z_loaned_sample_t) -> &z_loaned_encoding_t { + this.transmute_ref().encoding().transmute_handle() } /// Returns the sample payload data. #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_loaned_sample_t) -> &z_loaned_bytes_t { - let sample = sample.transmute_ref(); - sample.payload().transmute_handle() +pub extern "C" fn z_sample_payload(this: &z_loaned_sample_t) -> &z_loaned_bytes_t { + this.transmute_ref().payload().transmute_handle() } /// Returns the sample kind. #[no_mangle] -pub extern "C" fn z_sample_kind(sample: &z_loaned_sample_t) -> z_sample_kind_t { - let sample = sample.transmute_ref(); - sample.kind().into() +pub extern "C" fn z_sample_kind(this: &z_loaned_sample_t) -> z_sample_kind_t { + this.transmute_ref().kind().into() } /// Returns the sample timestamp. -/// +/// /// Will return `NULL`, if sample is not associated with a timestamp. #[no_mangle] -pub extern "C" fn z_sample_timestamp(sample: &z_loaned_sample_t) -> Option<&z_timestamp_t> { - let sample = sample.transmute_ref(); - if let Some(t) = sample.timestamp() { +pub extern "C" fn z_sample_timestamp(this: &z_loaned_sample_t) -> Option<&z_timestamp_t> { + if let Some(t) = this.transmute_ref().timestamp() { Some(t.transmute_ref()) } else { None @@ -134,9 +129,8 @@ pub extern "C" fn z_sample_timestamp(sample: &z_loaned_sample_t) -> Option<&z_ti /// /// Returns `NULL`, if sample does not contain any attachement. #[no_mangle] -pub extern "C" fn z_sample_attachment(sample: &z_loaned_sample_t) -> *const z_loaned_bytes_t { - let sample = sample.transmute_ref(); - match sample.attachment() { +pub extern "C" fn z_sample_attachment(this: &z_loaned_sample_t) -> *const z_loaned_bytes_t { + match this.transmute_ref().attachment() { Some(attachment) => attachment.transmute_handle() as *const _, None => null(), } @@ -147,8 +141,11 @@ decl_transmute_owned!(Option, z_owned_sample_t); /// Construct a shallow copy of the sample (i.e. all modficiations applied to the copy, might be visible in the original). #[no_mangle] -pub extern "C" fn z_sample_clone(src: &z_loaned_sample_t, dst: *mut MaybeUninit) { - let src = src.transmute_ref(); +pub extern "C" fn z_sample_clone( + this: &z_loaned_sample_t, + dst: *mut MaybeUninit, +) { + let src = this.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); @@ -156,50 +153,44 @@ pub extern "C" fn z_sample_clone(src: &z_loaned_sample_t, dst: *mut MaybeUninit< /// Returns sample qos priority value. #[no_mangle] -pub extern "C" fn z_sample_priority(sample: &z_loaned_sample_t) -> z_priority_t { - let sample = sample.transmute_ref(); - sample.priority().into() +pub extern "C" fn z_sample_priority(this: &z_loaned_sample_t) -> z_priority_t { + this.transmute_ref().priority().into() } /// Returns whether sample qos express flag was set or not. #[no_mangle] -pub extern "C" fn z_sample_express(sample: &z_loaned_sample_t) -> bool { - let sample = sample.transmute_ref(); - sample.express() +pub extern "C" fn z_sample_express(this: &z_loaned_sample_t) -> bool { + this.transmute_ref().express() } /// Returns sample qos congestion control value. #[no_mangle] -pub extern "C" fn z_sample_congestion_control( - sample: &z_loaned_sample_t, -) -> z_congestion_control_t { - let sample = sample.transmute_ref(); - sample.congestion_control().into() +pub extern "C" fn z_sample_congestion_control(this: &z_loaned_sample_t) -> z_congestion_control_t { + this.transmute_ref().congestion_control().into() } /// Returns ``true`` if sample is valid, ``false`` if it is in gravestone state. #[no_mangle] -pub extern "C" fn z_sample_check(sample: &z_owned_sample_t) -> bool { - let sample = sample.transmute_ref(); - sample.is_some() +pub extern "C" fn z_sample_check(this: &z_owned_sample_t) -> bool { + this.transmute_ref().is_some() } /// Borrows sample. #[no_mangle] -pub extern "C" fn z_sample_loan(sample: &z_owned_sample_t) -> &z_loaned_sample_t { - unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() +pub extern "C" fn z_sample_loan(this: &z_owned_sample_t) -> &z_loaned_sample_t { + unwrap_ref_unchecked(this.transmute_ref()).transmute_handle() } /// Frees the memory and invalidates the sample, resetting it to a gravestone state. #[no_mangle] -pub extern "C" fn z_sample_drop(sample: &mut z_owned_sample_t) { - Inplace::drop(sample.transmute_mut()); +pub extern "C" fn z_sample_drop(this: &mut z_owned_sample_t) { + Inplace::drop(this.transmute_mut()); } /// Constructs sample in its gravestone state. #[no_mangle] -pub extern "C" fn z_sample_null(sample: *mut MaybeUninit) { - Inplace::empty(sample.transmute_uninit_ptr()); +pub extern "C" fn z_sample_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } pub use crate::opaque_types::z_loaned_encoding_t; @@ -212,10 +203,10 @@ decl_transmute_owned!(Encoding, z_owned_encoding_t); #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_from_str( - encoding: *mut MaybeUninit, + this: *mut MaybeUninit, s: *const c_char, ) -> errors::z_error_t { - let encoding = encoding.transmute_uninit_ptr(); + let encoding = this.transmute_uninit_ptr(); if s.is_null() { Inplace::empty(encoding); errors::Z_OK @@ -227,38 +218,38 @@ pub unsafe extern "C" fn z_encoding_from_str( } } -/// Returns a default :c:type:`z_loaned_encoding_t`. +/// Returns a loaned default :c:type:`z_loaned_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_default() -> &'static z_loaned_encoding_t { +pub extern "C" fn z_encoding_loan_default() -> &'static z_loaned_encoding_t { Encoding::ZENOH_BYTES.transmute_handle() } /// Constructs a default :c:type:`z_owned_encoding_t`. #[no_mangle] -pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { - Inplace::empty(encoding.transmute_uninit_ptr()); +pub extern "C" fn z_encoding_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } -/// Frees memory `encoding`, resetting encoding to its default value. +/// Frees the memory and resets the encoding it to its default value. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - Inplace::drop(encoding.transmute_mut()); +pub unsafe extern "C" fn z_encoding_drop(this: &mut z_owned_encoding_t) { + Inplace::drop(this.transmute_mut()); } -/// Returns ``true`` if `encoding` is in non-default state, ``false`` otherwise. +/// Returns ``true`` if encoding is in non-default state, ``false`` otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> bool { - *encoding.transmute_ref() != Encoding::default() +pub extern "C" fn z_encoding_check(this: &'static z_owned_encoding_t) -> bool { + *this.transmute_ref() != Encoding::default() } /// Borrows encoding. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> &z_loaned_encoding_t { - encoding.transmute_ref().transmute_handle() +pub extern "C" fn z_encoding_loan(this: &z_owned_encoding_t) -> &z_loaned_encoding_t { + this.transmute_ref().transmute_handle() } pub use crate::opaque_types::z_owned_value_t; @@ -344,6 +335,7 @@ impl From for ReplyKeyExpr { } } +/// Returns the default value of :c:type:`zcu_reply_keyexpr_t` #[no_mangle] pub extern "C" fn zcu_reply_keyexpr_default() -> zcu_reply_keyexpr_t { ReplyKeyExpr::default().into() @@ -394,9 +386,9 @@ pub extern "C" fn z_query_target_default() -> z_query_target_t { #[repr(C)] #[derive(Clone, Copy, Default)] pub enum z_consolidation_mode_t { -/// Let Zenoh decide the best consolidation mode depending on the query selector. -/// If the selector contains time range properties, consolidation mode `NONE` is used. -/// Otherwise the `LATEST` consolidation mode is used. + /// Let Zenoh decide the best consolidation mode depending on the query selector. + /// If the selector contains time range properties, consolidation mode `NONE` is used. + /// Otherwise the `LATEST` consolidation mode is used. AUTO = -1, #[default] /// No consolidation is applied. Replies may come in any order and any number. @@ -440,19 +432,19 @@ impl From for ConsolidationMode { #[repr(C)] #[derive(Clone, Copy)] pub enum z_priority_t { - /// REAL_TIME + /// Priority for ``RealTime`` messages. REAL_TIME = 1, - /// INTERACTIVE_HIGFH + /// Highest priority for ``Interactive`` messages. INTERACTIVE_HIGH = 2, - /// INTERACTIVE_LOW + /// Lowest priority for ``Interactive`` messages. INTERACTIVE_LOW = 3, - /// DATA_HIGH + /// Highest priority for ``Data`` messages. DATA_HIGH = 4, - /// DATA + /// Default priority for ``Data`` messages. DATA = 5, - /// DATA_LOW + /// Lowest priority for ``Data`` messages. DATA_LOW = 6, - /// BACKGROUND + /// Priority for ``Background traffic`` messages. BACKGROUND = 7, } @@ -488,9 +480,9 @@ impl From for Priority { #[repr(C)] #[derive(Clone, Copy)] pub enum z_congestion_control_t { - /// Block + /// Messages are not dropped in case of congestion. BLOCK, - /// Drop + /// Messages are dropped in case of congestion. DROP, } diff --git a/src/get.rs b/src/get.rs index 8ef975343..fedfc3b3f 100644 --- a/src/get.rs +++ b/src/get.rs @@ -262,19 +262,26 @@ pub extern "C" fn z_query_consolidation_auto() -> z_query_consolidation_t { QueryConsolidation::AUTO.into() } -/// Latest value consolidation. +/// Latest consolidation. +/// +/// This strategy optimizes bandwidth on all links in the system but will provide a very poor latency. #[no_mangle] pub extern "C" fn z_query_consolidation_latest() -> z_query_consolidation_t { QueryConsolidation::from(ConsolidationMode::Latest).into() } /// Monotonic consolidation. +/// +/// This strategy offers the best latency. Replies are directly transmitted to the application when received +/// without needing to wait for all replies. This mode does not guarantee that there will be no duplicates. #[no_mangle] pub extern "C" fn z_query_consolidation_monotonic() -> z_query_consolidation_t { QueryConsolidation::from(ConsolidationMode::Monotonic).into() } -/// Disable consolidation. +/// No consolidation. +/// +/// This strategy is useful when querying timeseries data bases or when using quorums. #[no_mangle] pub extern "C" fn z_query_consolidation_none() -> z_query_consolidation_t { QueryConsolidation::from(ConsolidationMode::None).into() From 1783fa923eb87e982882c7c6aa7e58ba449c3bdc Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 7 May 2024 12:01:38 +0200 Subject: [PATCH 085/377] docs for config, session and info --- docs/api.rst | 12 ++-- include/zenoh_commons.h | 107 +++++++++++++++++------------------ include/zenoh_macros.h | 6 +- src/commons.rs | 2 +- src/config.rs | 78 +++++++++++++------------ src/info.rs | 2 +- src/session.rs | 50 ++++++++-------- tests/z_api_null_drop_test.c | 4 +- 8 files changed, 132 insertions(+), 129 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 4238f5598..f9d74a288 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -238,8 +238,12 @@ Session configuration .. autocstruct:: zenoh_commons.h::z_loaned_config_t .. autocstruct:: zenoh_commons.h::z_owned_config_t -.. autocstruct:: zenoh_commons.h::z_owned_scouting_config_t +.. autocfunction:: zenoh_commons.h::z_config_loan +.. autocfunction:: zenoh_commons.h::z_config_null +.. autocfunction:: zenoh_commons.h::z_config_loan_mut +.. autocfunction:: zenoh_commons.h::z_config_check +.. autocfunction:: zenoh_commons.h::z_config_drop .. autocfunction:: zenoh_commons.h::z_config_default .. autocfunction:: zenoh_commons.h::z_config_client .. autocfunction:: zenoh_commons.h::z_config_peer @@ -248,10 +252,6 @@ Session configuration .. autocfunction:: zenoh_commons.h::zc_config_insert_json .. autocfunction:: zenoh_commons.h::zc_config_get .. autocfunction:: zenoh_commons.h::zc_config_to_string -.. autocfunction:: zenoh_commons.h::z_config_loan -.. autocfunction:: zenoh_commons.h::z_config_loan_mut -.. autocfunction:: zenoh_commons.h::z_config_check -.. autocfunction:: zenoh_commons.h::z_config_drop Session management ------------------ @@ -272,6 +272,8 @@ Functions .. autocfunction:: zenoh_commons.h::z_session_loan .. autocfunction:: zenoh_commons.h::z_session_check +.. autocfunction:: zenoh_commons.h::z_session_null +.. autocfunction:: zenoh_commons.h::z_session_drop .. autocfunction:: zenoh_commons.h::z_info_zid .. autocfunction:: zenoh_commons.h::z_info_routers_zid diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 9d56cb6bd..2c9aeb994 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -963,12 +963,13 @@ ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); ZENOHC_API struct z_clock_t z_clock_now(void); /** - * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * Closes a zenoh session. This alos drops and invalidates `session`. * - * Returns a negative value if an error occured while closing the session. - * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + * Returns 0 in case of success, a negative value if an error occured while closing the session, + * the remaining reference count (number of shallow copies) of the session otherwise, saturating at i8::MAX. */ -ZENOHC_API z_error_t z_close(struct z_owned_session_t *session); +ZENOHC_API +z_error_t z_close(struct z_owned_session_t *this_); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1064,53 +1065,47 @@ ZENOHC_API z_error_t z_condvar_wait(const struct z_loaned_condvar_t *this_, struct z_loaned_mutex_t *m); /** - * Returns ``true`` if `config` is valid. + * Returns ``true`` if `config` is valid, ``false`` if it is in a gravestone state. */ -ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); +ZENOHC_API bool z_config_check(const struct z_owned_config_t *this_); /** * Constructs a default, zenoh-allocated, client mode configuration. - * If `peer` is not null, it is added to the configuration as remote peer. + * + * Parameters: + * peers: Array with `size >= n_peers`, containing peer locators to add to the config. + * n_peers: Number of peers to add to the config. + * Returns 0 in case of success, negative error code otherwise. */ ZENOHC_API z_error_t z_config_client(struct z_owned_config_t *this_, const char *const *peers, size_t n_peers); /** - * Clones the config. + * Clones the config into provided uninitialized memory location. */ -ZENOHC_API void z_config_clone(const struct z_loaned_config_t *src, struct z_owned_config_t *dst); +ZENOHC_API void z_config_clone(const struct z_loaned_config_t *this_, struct z_owned_config_t *dst); /** - * Return a new, zenoh-allocated, empty configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * Constructs a new empty configuration. */ -ZENOHC_API -void z_config_default(struct z_owned_config_t *this_); +ZENOHC_API void z_config_default(struct z_owned_config_t *this_); /** - * Frees `config`, invalidating it for double-drop safety. + * Frees `config`, and resets it to its gravestone state. */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); +ZENOHC_API void z_config_drop(struct z_owned_config_t *this_); /** - * Returns a :c:type:`z_loaned_config_t` loaned from `s`. + * Borrows config. */ ZENOHC_API const struct z_loaned_config_t *z_config_loan(const struct z_owned_config_t *this_); /** - * Returns a :c:type:`z_loaned_config_t` loaned from `s`. + * Mutably borrows config. */ ZENOHC_API struct z_loaned_config_t *z_config_loan_mut(struct z_owned_config_t *this_); /** - * Constructs a null safe-to-drop value of 'z_owned_config_t' type + * Constructs config in its gravestone state. */ ZENOHC_API void z_config_null(struct z_owned_config_t *this_); /** - * Constructs a default, zenoh-allocated, peer mode configuration. + * Constructs a default peer mode configuration. */ ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); /** @@ -1329,7 +1324,7 @@ ZENOHC_API z_error_t z_info_routers_zid(const struct z_loaned_session_t *session, struct z_owned_closure_zid_t *callback); /** - * Returns the local Zenoh ID. + * Returns the session's Zenoh ID. * * Unless the `session` is invalid, that ID is guaranteed to be non-zero. * In other words, this function returning an array of 16 zeros means you failed @@ -1461,8 +1456,9 @@ ZENOHC_API void z_mutex_null(struct z_owned_mutex_t *this_); ZENOHC_API z_error_t z_mutex_try_lock(struct z_loaned_mutex_t *this_); ZENOHC_API z_error_t z_mutex_unlock(struct z_loaned_mutex_t *this_); /** - * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. - * Config value is always consumed upon function return. + * Constructs and opens a new Zenoh session. + * + * Returns 0 in case of success, negative error code otherwise (in this case the session will be in its gravestone state). */ ZENOHC_API z_error_t z_open(struct z_owned_session_t *this_, @@ -1782,7 +1778,7 @@ const struct z_loaned_bytes_t *z_sample_attachment(const struct z_loaned_sample_ */ ZENOHC_API bool z_sample_check(const struct z_owned_sample_t *this_); /** - * Construct a shallow copy of the sample (i.e. all modficiations applied to the copy, might be visible in the original). + * Creates a shallow copy of the sample (i.e. all modficiations applied to the copy, might be visible in the original) in provided uninitilized memory location. */ ZENOHC_API void z_sample_clone(const struct z_loaned_sample_t *this_, @@ -1856,23 +1852,21 @@ void z_scouting_config_from(struct z_owned_scouting_config_t *this_, const struct z_loaned_config_t *config); ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); /** - * Returns ``true`` if `session` is valid. + * Returns ``true`` if `session` is valid, ``false`` otherwise. */ ZENOHC_API bool z_session_check(const struct z_owned_session_t *this_); /** - * Returns a :c:type:`z_loaned_session_t` loaned from `s`. + * Frees memory and invalidates the session. * - * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. - * - * # Safety - * The returned `z_loaned_session_t` aliases `z_owned_session_t`'s internal allocation, - * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) - * have been destroyed is UB (likely SEGFAULT) + * This will also close the session if it does not have any clones left. */ -ZENOHC_API -const struct z_loaned_session_t *z_session_loan(const struct z_owned_session_t *this_); +ZENOHC_API void z_session_drop(struct z_owned_session_t *this_); +/** + * Borrows session. + */ +ZENOHC_API const struct z_loaned_session_t *z_session_loan(const struct z_owned_session_t *this_); /** - * Constructs a null safe-to-drop value of 'z_owned_session_t' type + * Constructs a Zenoh session in its gravestone state. */ ZENOHC_API void z_session_null(struct z_owned_session_t *this_); ZENOHC_API int8_t z_sleep_ms(size_t time); @@ -2336,6 +2330,8 @@ z_error_t z_view_str_wrap(struct z_view_str_t *this_, 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. + * + * Returns 0 in case of success, negative error code otherwise. */ ZENOHC_API z_error_t zc_config_from_file(struct z_owned_config_t *this_, @@ -2343,34 +2339,35 @@ z_error_t zc_config_from_file(struct z_owned_config_t *this_, /** * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. * - * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). + * Returns 0 in case of success, negative error code otherwise. */ ZENOHC_API z_error_t zc_config_from_str(struct z_owned_config_t *this_, const char *s); /** - * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. - * Use `z_drop` to safely deallocate this string + * Gets the property with the given path key from the configuration, and constructs and owned string from it. */ ZENOHC_API -z_error_t zc_config_get(const struct z_loaned_config_t *config, +z_error_t zc_config_get(const struct z_loaned_config_t *this_, const char *key, - struct z_owned_str_t *value_string); + struct z_owned_str_t *out_value_string); /** * Inserts a JSON-serialized `value` at the `key` position of the configuration. * - * Returns 0 if successful, a negative value otherwise. + * Returns 0 if successful, a negative error code otherwise. */ ZENOHC_API -z_error_t zc_config_insert_json(struct z_loaned_config_t *config, +z_error_t zc_config_insert_json(struct z_loaned_config_t *this_, const char *key, const char *value); /** - * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. + * Constructs a json string representation of the `config`, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. + * + * Returns 0 in case of success, negative error code otherwise. */ ZENOHC_API z_error_t zc_config_to_string(const struct z_loaned_config_t *config, - struct z_owned_str_t *config_string); + struct z_owned_str_t *out_config_string); /** * Initialises the zenoh runtime logger. * @@ -2503,11 +2500,13 @@ ZENOHC_API void zc_reply_non_blocking_fifo_new(struct z_owned_reply_channel_t *this_, size_t bound); /** - * Increments the session's reference count, returning a new owning handle. + * Constructs a shallow copy of the session in provided uninitialized memory location. + * + * Returns 0 in case of success, false otherwise. */ ZENOHC_API -z_error_t zc_session_clone(struct z_owned_session_t *dst, - const struct z_owned_session_t *src); +z_error_t zc_session_clone(const struct z_owned_session_t *this_, + struct z_owned_session_t *dst); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index b296768cf..63bc2eba2 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -64,6 +64,7 @@ z_owned_reply_t * : z_reply_drop,\ z_owned_sample_t * : z_sample_drop,\ z_owned_scouting_config_t * : z_scouting_config_drop,\ + z_owned_session_t * : z_session_drop,\ z_owned_slice_array_t * : z_slice_array_drop,\ z_owned_slice_t * : z_slice_drop,\ z_owned_slice_map_t * : z_slice_map_drop,\ @@ -202,7 +203,7 @@ inline void z_drop(const z_owned_closure_reply_t* closure) { return z_closure_re inline void z_drop(const z_owned_closure_sample_t* closure) { return z_closure_sample_drop(closure); }; inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; inline void z_drop(const z_owned_condvar_t* this_) { return z_condvar_drop(this_); }; -inline void z_drop(const z_owned_config_t* config) { return z_config_drop(config); }; +inline void z_drop(const z_owned_config_t* this_) { return z_config_drop(this_); }; inline void z_drop(const z_owned_encoding_t* this_) { return z_encoding_drop(this_); }; inline void z_drop(const z_owned_hello_t* this_) { return z_hello_drop(this_); }; inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; @@ -215,6 +216,7 @@ inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_chan inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; inline void z_drop(const z_owned_sample_t* this_) { return z_sample_drop(this_); }; inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; +inline void z_drop(const z_owned_session_t* this_) { return z_session_drop(this_); }; inline void z_drop(const z_owned_slice_array_t* this_) { return z_slice_array_drop(this_); }; inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; inline void z_drop(const z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; @@ -264,7 +266,7 @@ inline void z_null( ze_owned_querying_subscriber_t* this_) { return ze_querying_ inline bool z_check(const z_owned_bytes_t& payload) { return z_bytes_check(&payload); }; inline bool z_check(const z_owned_bytes_reader_t& this_) { return z_bytes_reader_check(&this_); }; inline bool z_check(const z_owned_condvar_t& this_) { return z_condvar_check(&this_); }; -inline bool z_check(const z_owned_config_t& config) { return z_config_check(&config); }; +inline bool z_check(const z_owned_config_t& this_) { return z_config_check(&this_); }; inline bool z_check(const z_owned_encoding_t& this_) { return z_encoding_check(&this_); }; inline bool z_check(const z_owned_hello_t& this_) { return z_hello_check(&this_); }; inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; diff --git a/src/commons.rs b/src/commons.rs index ac9996360..2423ef843 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -139,7 +139,7 @@ pub extern "C" fn z_sample_attachment(this: &z_loaned_sample_t) -> *const z_loan pub use crate::opaque_types::z_owned_sample_t; decl_transmute_owned!(Option, z_owned_sample_t); -/// Construct a shallow copy of the sample (i.e. all modficiations applied to the copy, might be visible in the original). +/// Creates a shallow copy of the sample (i.e. all modficiations applied to the copy, might be visible in the original) in provided uninitilized memory location. #[no_mangle] pub extern "C" fn z_sample_clone( this: &z_loaned_sample_t, diff --git a/src/config.rs b/src/config.rs index 2514d7f3d..9cb8f7496 100644 --- a/src/config.rs +++ b/src/config.rs @@ -69,7 +69,7 @@ decl_transmute_handle!(Config, z_loaned_config_t); pub use crate::opaque_types::z_owned_config_t; decl_transmute_owned!(Option, z_owned_config_t); -/// Returns a :c:type:`z_loaned_config_t` loaned from `s`. +/// Borrows config. #[no_mangle] pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_loaned_config_t { let this = this.transmute_ref(); @@ -77,7 +77,7 @@ pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_loaned_co this.transmute_handle() } -/// Returns a :c:type:`z_loaned_config_t` loaned from `s`. +/// Mutably borrows config. #[no_mangle] pub extern "C" fn z_config_loan_mut(this: &mut z_owned_config_t) -> &mut z_loaned_config_t { let this = this.transmute_mut(); @@ -85,16 +85,7 @@ pub extern "C" fn z_config_loan_mut(this: &mut z_owned_config_t) -> &mut z_loane this.transmute_handle_mut() } -/// Return a new, zenoh-allocated, empty configuration. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +/// Constructs a new empty configuration. #[no_mangle] pub extern "C" fn z_config_default(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); @@ -102,47 +93,46 @@ pub extern "C" fn z_config_default(this: *mut MaybeUninit) { Inplace::init(this, Some(config)); } -/// Constructs a null safe-to-drop value of 'z_owned_config_t' type +/// Constructs config in its gravestone state. #[no_mangle] pub extern "C" fn z_config_null(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); Inplace::empty(this); } -/// Clones the config. +/// Clones the config into provided uninitialized memory location. #[no_mangle] -pub extern "C" fn z_config_clone(src: &z_loaned_config_t, dst: *mut MaybeUninit) { - let src = src.transmute_ref(); +pub extern "C" fn z_config_clone(this: &z_loaned_config_t, dst: *mut MaybeUninit) { + let src = this.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); } -/// Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. -/// Use `z_drop` to safely deallocate this string +/// Gets the property with the given path key from the configuration, and constructs and owned string from it. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_config_get( - config: &z_loaned_config_t, + this: &z_loaned_config_t, key: *const c_char, - value_string: *mut MaybeUninit, + out_value_string: *mut MaybeUninit, ) -> errors::z_error_t { - let config = config.transmute_ref(); + let config = this.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, Err(_) => { - z_str_null(value_string); + z_str_null(out_value_string); return errors::Z_EINVAL; } }; let val = config.get_json(key).ok(); match val { Some(val) => { - z_str_from_substring(value_string, val.as_ptr() as *const libc::c_char, val.len()); + z_str_from_substring(out_value_string, val.as_ptr() as *const libc::c_char, val.len()); errors::Z_OK } None => { - z_str_null(value_string); + z_str_null(out_value_string); errors::Z_EUNAVAILABLE } } @@ -150,15 +140,15 @@ pub unsafe extern "C" fn zc_config_get( /// Inserts a JSON-serialized `value` at the `key` position of the configuration. /// -/// Returns 0 if successful, a negative value otherwise. +/// Returns 0 if successful, a negative error code otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc, unused_must_use)] pub unsafe extern "C" fn zc_config_insert_json( - config: &mut z_loaned_config_t, + this: &mut z_loaned_config_t, key: *const c_char, value: *const c_char, ) -> errors::z_error_t { - let config = config.transmute_mut(); + let config = this.transmute_mut(); let key = CStr::from_ptr(key); let value = CStr::from_ptr(value); match config.insert_json5(&key.to_string_lossy(), &value.to_string_lossy()) { @@ -167,24 +157,24 @@ pub unsafe extern "C" fn zc_config_insert_json( } } -/// Frees `config`, invalidating it for double-drop safety. +/// Frees `config`, and resets it to its gravestone state. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_config_drop(config: &mut z_owned_config_t) { - let config = config.transmute_mut(); +pub extern "C" fn z_config_drop(this: &mut z_owned_config_t) { + let config = this.transmute_mut(); Inplace::drop(config); } -/// Returns ``true`` if `config` is valid. +/// Returns ``true`` if `config` is valid, ``false`` if it is in a gravestone state. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_config_check(config: &z_owned_config_t) -> bool { - let config = config.transmute_ref(); +pub extern "C" fn z_config_check(this: &z_owned_config_t) -> bool { + let config = this.transmute_ref(); config.as_ref().is_some() } /// Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. /// -/// Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). +/// Returns 0 in case of success, negative error code otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_config_from_str( @@ -206,29 +196,33 @@ pub unsafe extern "C" fn zc_config_from_str( res } -/// Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. +/// Constructs a json string representation of the `config`, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. +/// +/// Returns 0 in case of success, negative error code otherwise. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_config_to_string( config: &z_loaned_config_t, - config_string: *mut MaybeUninit, + out_config_string: *mut MaybeUninit, ) -> errors::z_error_t { let config: &Config = config.transmute_ref(); match json5::to_string(config) { Ok(s) => { unsafe { - z_str_from_substring(config_string, s.as_ptr() as *const libc::c_char, s.len()) + z_str_from_substring(out_config_string, s.as_ptr() as *const libc::c_char, s.len()) }; errors::Z_OK } Err(_) => { - z_str_null(config_string); + z_str_null(out_config_string); errors::Z_EPARSE } } } /// Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. +/// +/// Returns 0 in case of success, negative error code otherwise. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_config_from_file( @@ -256,7 +250,7 @@ pub unsafe extern "C" fn zc_config_from_file( res } -/// Constructs a default, zenoh-allocated, peer mode configuration. +/// Constructs a default peer mode configuration. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { @@ -264,7 +258,11 @@ pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { } /// Constructs a default, zenoh-allocated, client mode configuration. -/// If `peer` is not null, it is added to the configuration as remote peer. +/// +/// Parameters: +/// peers: Array with `size >= n_peers`, containing peer locators to add to the config. +/// n_peers: Number of peers to add to the config. +/// Returns 0 in case of success, negative error code otherwise. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_config_client( diff --git a/src/info.rs b/src/info.rs index c3b951d38..4c8f1c1f2 100644 --- a/src/info.rs +++ b/src/info.rs @@ -27,7 +27,7 @@ impl From<[u8; 16]> for z_id_t { } } -/// Returns the local Zenoh ID. +/// Returns the session's Zenoh ID. /// /// Unless the `session` is invalid, that ID is guaranteed to be non-zero. /// In other words, this function returning an array of 16 zeros means you failed diff --git a/src/session.rs b/src/session.rs index 768bdf720..52a6408c0 100644 --- a/src/session.rs +++ b/src/session.rs @@ -25,18 +25,10 @@ use zenoh::session::Session; use crate::opaque_types::z_owned_session_t; decl_transmute_owned!(Option>, z_owned_session_t); -/// A loaned zenoh session. use crate::opaque_types::z_loaned_session_t; decl_transmute_handle!(Session, z_loaned_session_t); -/// Returns a :c:type:`z_loaned_session_t` loaned from `s`. -/// -/// This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. -/// -/// # Safety -/// The returned `z_loaned_session_t` aliases `z_owned_session_t`'s internal allocation, -/// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) -/// have been destroyed is UB (likely SEGFAULT) +/// Borrows session. #[no_mangle] pub extern "C" fn z_session_loan(this: &z_owned_session_t) -> &z_loaned_session_t { let this = this.transmute_ref(); @@ -45,15 +37,16 @@ pub extern "C" fn z_session_loan(this: &z_owned_session_t) -> &z_loaned_session_ this.transmute_handle() } -/// Constructs a null safe-to-drop value of 'z_owned_session_t' type +/// Constructs a Zenoh session in its gravestone state. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_session_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } -/// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. -/// Config value is always consumed upon function return. +/// Constructs and opens a new Zenoh session. +/// +/// Returns 0 in case of success, negative error code otherwise (in this case the session will be in its gravestone state). #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_open( @@ -85,23 +78,22 @@ pub extern "C" fn z_open( } } -/// Returns ``true`` if `session` is valid. +/// Returns ``true`` if `session` is valid, ``false`` otherwise. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_session_check(this: &z_owned_session_t) -> bool { this.transmute_ref().is_some() } -/// Closes a zenoh session. This drops and invalidates `session` for double-drop safety. +/// Closes a zenoh session. This alos drops and invalidates `session`. /// -/// Returns a negative value if an error occured while closing the session. -/// Returns the remaining reference count of the session otherwise, saturating at i8::MAX. -#[allow(clippy::missing_safety_doc)] +/// Returns 0 in case of success, a negative value if an error occured while closing the session, +/// the remaining reference count (number of shallow copies) of the session otherwise, saturating at i8::MAX. #[no_mangle] -pub extern "C" fn z_close(session: &mut z_owned_session_t) -> errors::z_error_t { - let session = session.transmute_mut(); +pub extern "C" fn z_close(this: &mut z_owned_session_t) -> errors::z_error_t { + let session = this.transmute_mut(); let Some(s) = session.take() else { - return errors::Z_OK; + return errors::Z_EINVAL; }; let s = match Arc::try_unwrap(s) { Ok(s) => s, @@ -115,16 +107,26 @@ pub extern "C" fn z_close(session: &mut z_owned_session_t) -> errors::z_error_t } } -/// Increments the session's reference count, returning a new owning handle. +/// Frees memory and invalidates the session. +/// +/// This will also close the session if it does not have any clones left. +#[no_mangle] +pub extern "C" fn z_session_drop(this: &mut z_owned_session_t) { + let _ = this.transmute_mut().extract().take(); +} + + +/// Constructs a shallow copy of the session in provided uninitialized memory location. +/// +/// Returns 0 in case of success, false otherwise. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn zc_session_clone( + this: &z_owned_session_t, dst: *mut MaybeUninit, - src: &z_owned_session_t, ) -> errors::z_error_t { - // session.as_ref().as_ref().and_then(|s| s.upgrade()).into() let dst = dst.transmute_uninit_ptr(); - let Some(src) = src.transmute_ref() else { + let Some(src) = this.transmute_ref() else { return errors::Z_EINVAL; }; Inplace::init(dst, Some(src.clone())); diff --git a/tests/z_api_null_drop_test.c b/tests/z_api_null_drop_test.c index 2e65047de..010ef53d4 100644 --- a/tests/z_api_null_drop_test.c +++ b/tests/z_api_null_drop_test.c @@ -155,7 +155,7 @@ int main(int argc, char **argv) { // Test drop null and double drop it // for (int i = 0; i < 2; ++i) { - z_close(z_move(session_null_1)); + z_drop(z_move(session_null_1)); z_undeclare_publisher(z_move(publisher_null_1)); z_drop(z_move(keyexpr_null_1)); z_drop(z_move(config_null_1)); @@ -178,7 +178,7 @@ int main(int argc, char **argv) { z_drop(z_move(bytes_reader_null_1)); - z_close(z_move(session_null_2)); + z_drop(z_move(session_null_2)); z_undeclare_publisher(z_move(publisher_null_2)); z_drop(z_move(keyexpr_null_2)); z_drop(z_move(config_null_2)); From 0e67440e4759e6816f54baf68e91f75a90bcd907 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 10 May 2024 20:47:50 +0200 Subject: [PATCH 086/377] - use doxygen for docs; - docs for Queryable/Query and Publisher/Subscriber --- build-resources/opaque-types/src/lib.rs | 39 +- docs/Doxyfile | 2854 +++++++++++++++++++++++ docs/api.rst | 673 +++--- docs/conf.py | 15 +- include/zenoh_commons.h | 783 ++++--- include/zenoh_concrete.h | 17 +- include/zenoh_macros.h | 20 +- src/closures/matching_status_closure.rs | 30 +- src/closures/query_closure.rs | 30 +- src/closures/reply_closure.rs | 33 +- src/closures/response_channel.rs | 10 +- src/closures/sample_closure.rs | 27 +- src/closures/zenohid_closure.rs | 31 +- src/collections.rs | 69 +- src/commons.rs | 16 +- src/config.rs | 8 +- src/get.rs | 89 +- src/keyexpr.rs | 30 +- src/liveliness.rs | 8 +- src/publication_cache.rs | 8 +- src/publisher.rs | 117 +- src/pull_subscriber.rs | 16 +- src/put.rs | 50 +- src/queryable.rs | 102 +- src/querying_subscriber.rs | 12 +- src/scouting.rs | 2 +- src/session.rs | 22 +- src/subscriber.rs | 77 +- 28 files changed, 4063 insertions(+), 1125 deletions(-) create mode 100644 docs/Doxyfile diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index f34bedbc7..ead27dc73 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -88,14 +88,14 @@ get_opaque_type_data!(Sample, z_loaned_sample_t); get_opaque_type_data!(Option>, z_owned_bytes_reader_t); get_opaque_type_data!(ZBytesReader<'static>, z_loaned_bytes_reader_t); -/// The `encoding `_ of Zenoh data. -get_opaque_type_data!(Encoding, z_loaned_encoding_t); -/// A loaned Zenoh encoding. +/// The encoding of Zenoh data. get_opaque_type_data!(Encoding, z_owned_encoding_t); +/// A loaned Zenoh encoding. +get_opaque_type_data!(Encoding, z_loaned_encoding_t); -/// An owned reply from a Quryable to a :c:func:`z_get`. +/// An owned reply from a Queryable to a `z_get()`. get_opaque_type_data!(Option, z_owned_reply_t); -/// A loaned reply to a :c:func:`z_get`. +/// A loaned reply. get_opaque_type_data!(Reply, z_loaned_reply_t); /// A Zenoh value - a compination of payload and its encoding. @@ -108,13 +108,11 @@ get_opaque_type_data!(Value, z_loaned_value_t); /// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. get_opaque_type_data!(Option, z_owned_query_t); /// A loaned Zenoh query. -/// -/// It is valid as long as at least the corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. get_opaque_type_data!(Query, z_loaned_query_t); -/// An owned Zenoh queryable. +/// An owned Zenoh queryable . /// -/// Responds to queries sent via :c:func:`z_get` with intersecting key expression. +/// Responds to queries sent via `z_get()` with intersecting key expression. get_opaque_type_data!(Option>, z_owned_queryable_t); /// A loaned Zenoh queryable. get_opaque_type_data!(Queryable<'static, ()>, z_loaned_queryable_t); @@ -122,12 +120,12 @@ get_opaque_type_data!(Queryable<'static, ()>, z_loaned_queryable_t); /// An owned Zenoh querying subscriber. /// /// In addition to receiving the data it is subscribed to, -/// it also will fetch data from a Quryable at startup and peridodically (using :c:func: `ze_querying_subscriber_get`). +/// it also will fetch data from a Queryable at startup and peridodically (using `ze_querying_subscriber_get`). get_opaque_type_data!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); /// A loaned Zenoh querying subscriber get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_loaned_querying_subscriber_t); -/// A Zenoh-allocated `key expression `_. +/// A Zenoh-allocated key expression . /// /// Key expressions can identify a single key or a set of keys. /// @@ -135,7 +133,7 @@ get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Sess /// - ``"key/expression"``. /// - ``"key/ex*"``. /// -/// Key expressions can be mapped to numerical ids through :c:func:`z_declare_keyexpr` +/// Key expressions can be mapped to numerical ids through `z_declare_keyexpr` /// for wire and computation efficiency. /// /// Internally key expressiobn can be either: @@ -154,14 +152,14 @@ get_opaque_type_data!(Option>, z_view_keyexpr_t); /// - ``"key/expression"``. /// - ``"key/ex*"``. /// -/// Using :c:func:`z_declare_keyexpr` allows Zenoh to optimize a key expression, +/// Using `z_declare_keyexpr` allows Zenoh to optimize a key expression, /// both for local processing and network-wise. get_opaque_type_data!(KeyExpr<'_>, z_loaned_keyexpr_t); /// An owned Zenoh session. get_opaque_type_data!(Option>, z_owned_session_t); /// A loaned Zenoh session. -get_opaque_type_data!(Session, z_loaned_session_t); +get_opaque_type_data!(Arc, z_loaned_session_t); /// An owned Zenoh configuration. get_opaque_type_data!(Option, z_owned_config_t); @@ -173,12 +171,12 @@ get_opaque_type_data!(Config, z_loaned_config_t); /// In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. get_opaque_type_data!(ZenohId, z_id_t); -/// A Zenoh `timestamp `_. +/// A Zenoh timestamp . /// /// It consists of a time generated by a Hybrid Logical Clock (HLC) in NPT64 format and a unique zenoh identifier. get_opaque_type_data!(Timestamp, z_timestamp_t); -/// An owned Zenoh publisher. +/// An owned Zenoh publisher . get_opaque_type_data!(Option>, z_owned_publisher_t); /// A loaned Zenoh publisher. get_opaque_type_data!(Publisher<'static>, z_loaned_publisher_t); @@ -186,15 +184,16 @@ get_opaque_type_data!(Publisher<'static>, z_loaned_publisher_t); /// An owned Zenoh matching listener. /// /// A listener that sends notifications when the [`MatchingStatus`] of a publisher changes. -/// Destroying the matching listener cancels the subscription. +/// Dropping the corresponding publisher, also drops matching listener. get_opaque_type_data!(Option>, zcu_owned_matching_listener_t); -/// An owned Zenoh subscriber. +/// An owned Zenoh subscriber . /// /// Receives data from publication on intersecting key expressions. /// Destroying the subscriber cancels the subscription. get_opaque_type_data!(Option>, z_owned_subscriber_t); +/// A loaned Zenoh subscriber. get_opaque_type_data!(Subscriber<'static, ()>, z_loaned_subscriber_t); /// A liveliness token that can be used to provide the network with information about connectivity to its @@ -208,7 +207,7 @@ get_opaque_type_data!(LivelinessToken<'static>, zc_loaned_liveliness_token_t); /// An owned Zenoh publication cache. /// -/// Used to store publications on intersecting key expressions. Can be queried later via :c:func:`z_get` to retrieve this data +/// Used to store publications on intersecting key expressions. Can be queried later via `z_get()` to retrieve this data /// (for example by Querying Subscriber). get_opaque_type_data!(Option>, ze_owned_publication_cache_t); /// A loaned Zenoh publication cache. @@ -221,7 +220,7 @@ get_opaque_type_data!((Mutex<()>, Option>), z_loaned_mut /// An owned conditional variable. /// -/// Used in combination with :c:type:`z_owned_mutex_t` to wake up thread when certain conditions are met. +/// Used in combination with `z_owned_mutex_t` to wake up thread when certain conditions are met. get_opaque_type_data!(Option, z_owned_condvar_t); /// A loaned conditional variable. get_opaque_type_data!(Condvar, z_loaned_condvar_t); diff --git a/docs/Doxyfile b/docs/Doxyfile new file mode 100644 index 000000000..f897d03e9 --- /dev/null +++ b/docs/Doxyfile @@ -0,0 +1,2854 @@ +# Doxyfile 1.10.0 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "My Project" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# With the PROJECT_ICON tag one can specify an icon that is included in the tabs +# when the HTML document is shown. Doxygen will copy the logo to the output +# directory. + +PROJECT_ICON = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./doxyxml + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. + +CASE_SENSE_NAMES = SYSTEM + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ../include + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, +# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, +# *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to +# be provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cxxm \ + *.cpp \ + *.cppm \ + *.ccm \ + *.c++ \ + *.c++m \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.ixx \ + *.l \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f18 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# ANamespace::AClass, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# multi-line macros, enums or list initialized variables directly into the +# documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = NO + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + +# If the HTML_COPY_CLIPBOARD tag is set to YES then doxygen will show an icon in +# the top right corner of code and text fragments that allows the user to copy +# its content to the clipboard. Note this only works if supported by the browser +# and the web page is served via a secure context (see: +# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file: +# protocol. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COPY_CLIPBOARD = YES + +# Doxygen stores a couple of settings persistently in the browser (via e.g. +# cookies). By default these settings apply to all HTML pages generated by +# doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store +# the settings under a project specific key, such that the user preferences will +# be stored separately. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_PROJECT_COOKIE = + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /