Skip to content

Commit

Permalink
[eclipse-iceoryx#210] Introduce HandleToType trait
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Jul 15, 2024
1 parent c0ca4da commit 85cc6ee
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 60 deletions.
11 changes: 9 additions & 2 deletions iceoryx2-ffi/ffi-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ pub fn iceoryx2_ffi(args: TokenStream, input: TokenStream) -> TokenStream {
// Define all the names we need
let struct_storage_name = format_ident!("iox2_{}_storage_t", stripped_struct_name);
let _struct_h_t_name = format_ident!("iox2_{}_h_t", stripped_struct_name);
let _struct_h_name = format_ident!("iox2_{}_h", stripped_struct_name);
let struct_h_name = format_ident!("iox2_{}_h", stripped_struct_name);
let _struct_ref_h_t_name = format_ident!("iox2_{}_ref_h_t", stripped_struct_name);
let _struct_ref_h_name = format_ident!("iox2_{}_ref_h", stripped_struct_name);
let struct_ref_h_name = format_ident!("iox2_{}_ref_h", stripped_struct_name);

// NOTE: cbindgen does not play well with adding new structs or fields to existing structs;
// this code is kept for reference
Expand Down Expand Up @@ -128,6 +128,13 @@ pub fn iceoryx2_ffi(args: TokenStream, input: TokenStream) -> TokenStream {
#my_struct

impl #struct_name {
pub(crate) fn as_handle(&mut self) -> #struct_h_name {
self as *mut _ as _
}
pub(crate) fn as_ref_handle(&mut self) -> #struct_ref_h_name {
self as *mut _ as _
}

pub(crate) fn take(&mut self) -> Option<#my_type> {
unsafe { self.value.as_option_mut().take() }
}
Expand Down
6 changes: 6 additions & 0 deletions iceoryx2-ffi/ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,9 @@ pub extern "C" fn zero_copy_service_list() -> i32 {
trait IntoCInt {
fn into_c_int(self) -> c_int;
}

pub trait HandleToType {
type Target;

fn as_type(self) -> Self::Target;
}
58 changes: 38 additions & 20 deletions iceoryx2-ffi/ffi/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

use crate::{
iox2_callback_progression_e, iox2_config_ptr, iox2_node_name_ptr, iox2_service_builder_h,
iox2_service_builder_t, iox2_service_name_h, iox2_service_type_e, IntoCInt, IOX2_OK,
iox2_service_builder_t, iox2_service_name_h, iox2_service_type_e, HandleToType, IntoCInt,
IOX2_OK,
};

use iceoryx2::node::{NodeId, NodeListFailure, NodeView};
Expand Down Expand Up @@ -90,19 +91,31 @@ impl iox2_node_t {
self.value.init(value);
self.deleter = deleter;
}
}

pub(crate) fn cast(node: iox2_node_h) -> *mut Self {
node as *mut _ as _
}
pub struct iox2_name_h_t;
/// The owning handle for `iox2_node_t`. Passing the handle to an function transfers the ownership.
pub type iox2_node_h = *mut iox2_name_h_t;

pub struct iox2_noderef_h_t;
/// The non-owning handle for `iox2_node_t`. Passing the handle to an function does not transfers the ownership.
pub type iox2_node_ref_h = *mut iox2_noderef_h_t;

impl HandleToType for iox2_node_h {
type Target = *mut iox2_node_t;

pub(crate) fn as_handle(&mut self) -> iox2_node_h {
fn as_type(self) -> Self::Target {
self as *mut _ as _
}
}

pub struct iox2_node_h_t;
/// The handle for `iox2_node_builder_t`. Passing the handle to an function transfers the ownership.
pub type iox2_node_h = *mut iox2_node_h_t;
impl HandleToType for iox2_node_ref_h {
type Target = *mut iox2_node_t;

fn as_type(self) -> Self::Target {
self as *mut _ as _
}
}

#[repr(C)]
#[derive(Copy, Clone)]
Expand Down Expand Up @@ -154,7 +167,7 @@ pub type iox2_node_list_callback = extern "C" fn(
pub unsafe extern "C" fn iox2_node_name(node_handle: iox2_node_h) -> iox2_node_name_ptr {
debug_assert!(!node_handle.is_null());

let node = &mut *iox2_node_t::cast(node_handle);
let node = &mut *node_handle.as_type();

match node.service_type {
iox2_service_type_e::IPC => node.value.as_ref().ipc.name(),
Expand All @@ -171,7 +184,7 @@ pub unsafe extern "C" fn iox2_node_name(node_handle: iox2_node_h) -> iox2_node_n
pub unsafe extern "C" fn iox2_node_config(node_handle: iox2_node_h) -> iox2_config_ptr {
debug_assert!(!node_handle.is_null());

let node = &mut *iox2_node_t::cast(node_handle);
let node = &mut *node_handle.as_type();

match node.service_type {
iox2_service_type_e::IPC => node.value.as_ref().ipc.config(),
Expand Down Expand Up @@ -321,7 +334,7 @@ pub unsafe extern "C" fn iox2_node_service_builder(
pub unsafe extern "C" fn iox2_node_drop(node_handle: iox2_node_h) {
debug_assert!(!node_handle.is_null());

let node = &mut *iox2_node_t::cast(node_handle);
let node = &mut *node_handle.as_type();

match node.service_type {
iox2_service_type_e::IPC => {
Expand All @@ -341,6 +354,8 @@ mod test {
use crate::*;
use iceoryx2_bb_testing::assert_that;

use core::{slice, str};

fn create_sut_node() -> iox2_node_h {
unsafe {
let node_builder_handle = iox2_node_builder_new(std::ptr::null_mut());
Expand Down Expand Up @@ -388,11 +403,8 @@ mod test {
fn basic_node_config_test() {
unsafe {
let node_handle = create_sut_node();
let expected_config = (*iox2_node_t::cast(node_handle))
.value
.as_ref()
.ipc
.config();

let expected_config = Config::global_config();

let config = iox2_node_config(node_handle);

Expand All @@ -403,17 +415,23 @@ mod test {
}

#[test]
fn basic_node_name_test() {
fn basic_node_name_test() -> Result<(), Box<dyn std::error::Error>> {
unsafe {
let node_handle = create_sut_node();
let expected_node_name = (*iox2_node_t::cast(node_handle)).value.as_ref().ipc.name();
assert_that!(expected_node_name.as_str(), eq("hypnotoad"));

let node_name = iox2_node_name(node_handle);

assert_that!(*(node_name as *const NodeName), eq(*expected_node_name));
let mut node_name_len = 0;
let node_name_c_str = iox2_node_name_as_c_str(node_name, &mut node_name_len);

let slice = slice::from_raw_parts(node_name_c_str as *const _, node_name_len as _);
let node_name_str = str::from_utf8(slice)?;

assert_that!(node_name_str, eq("hypnotoad"));

iox2_node_drop(node_handle);

Ok(())
}
}

Expand Down
47 changes: 23 additions & 24 deletions iceoryx2-ffi/ffi/src/node_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#![allow(non_camel_case_types)]

use crate::{
iox2_node_h, iox2_node_name_drop, iox2_node_name_h, iox2_node_name_t, iox2_node_t,
iox2_service_type_e, IntoCInt, NodeUnion, IOX2_OK,
iox2_node_h, iox2_node_name_drop, iox2_node_name_h, iox2_node_t, iox2_service_type_e,
HandleToType, IntoCInt, NodeUnion, IOX2_OK,
};

use iceoryx2::node::NodeCreationFailure;
Expand Down Expand Up @@ -57,23 +57,6 @@ pub struct iox2_node_builder_t {
deleter: fn(*mut iox2_node_builder_t),
}

impl iox2_node_builder_t {
pub(crate) fn cast(node_builder: iox2_node_builder_h) -> *mut Self {
node_builder as *mut _ as _
}
pub(crate) fn cast_from_ref(node_builder: iox2_node_builder_ref_h) -> *mut Self {
node_builder as *mut _ as _
}

pub(crate) fn as_handle(&mut self) -> iox2_node_builder_h {
self as *mut _ as _
}

pub(crate) fn as_ref_handle(&mut self) -> iox2_node_builder_ref_h {
self as *mut _ as _
}
}

pub struct iox2_node_builder_h_t;
/// The owning handle for `iox2_node_builder_t`. Passing the handle to an function transfers the ownership.
pub type iox2_node_builder_h = *mut iox2_node_builder_h_t;
Expand All @@ -82,6 +65,22 @@ pub struct iox2_node_builder_ref_h_t;
/// The non-owning handle for `iox2_node_builder_t`. Passing the handle to an function does not transfers the ownership.
pub type iox2_node_builder_ref_h = *mut iox2_node_builder_ref_h_t;

impl HandleToType for iox2_node_builder_h {
type Target = *mut iox2_node_builder_t;

fn as_type(self) -> Self::Target {
self as *mut _ as _
}
}

impl HandleToType for iox2_node_builder_ref_h {
type Target = *mut iox2_node_builder_t;

fn as_type(self) -> Self::Target {
self as *mut _ as _
}
}

// END type definition

// BEGIN C API
Expand Down Expand Up @@ -136,7 +135,7 @@ pub unsafe extern "C" fn iox2_cast_node_builder_ref_h(
) -> iox2_node_builder_ref_h {
debug_assert!(!node_builder_handle.is_null());

(*iox2_node_builder_t::cast(node_builder_handle)).as_ref_handle()
(*node_builder_handle.as_type()).as_ref_handle()
}

/// Sets the node name for the builder
Expand All @@ -159,11 +158,11 @@ pub unsafe extern "C" fn iox2_node_builder_set_name(
debug_assert!(!node_builder_handle.is_null());
debug_assert!(!node_name_handle.is_null());

let node_name_struct = &mut *iox2_node_name_t::cast(node_name_handle);
let node_name_struct = &mut *node_name_handle.as_type();
let node_name = node_name_struct.take().unwrap();
iox2_node_name_drop(node_name_handle);

let node_builder_struct = &mut *iox2_node_builder_t::cast_from_ref(node_builder_handle);
let node_builder_struct = &mut *node_builder_handle.as_type();

let node_builder = node_builder_struct.take().unwrap();
let node_builder = node_builder.name(node_name);
Expand All @@ -186,7 +185,7 @@ pub extern "C" fn iox2_node_builder_set_config(
unsafe fn iox2_node_builder_drop(node_builder_handle: iox2_node_builder_h) {
debug_assert!(!node_builder_handle.is_null());

let node_builder = &mut (*iox2_node_builder_t::cast(node_builder_handle));
let node_builder = &mut *node_builder_handle.as_type();
std::ptr::drop_in_place(node_builder.value.as_option_mut());
(node_builder.deleter)(node_builder);
}
Expand Down Expand Up @@ -216,7 +215,7 @@ pub unsafe extern "C" fn iox2_node_builder_create(
debug_assert!(!node_builder_handle.is_null());
debug_assert!(!node_handle_ptr.is_null());

let node_builder_struct = &mut *iox2_node_builder_t::cast(node_builder_handle);
let node_builder_struct = &mut *node_builder_handle.as_type();
let node_builder = node_builder_struct.take().unwrap();
iox2_node_builder_drop(node_builder_handle);

Expand Down
38 changes: 24 additions & 14 deletions iceoryx2-ffi/ffi/src/node_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

#![allow(non_camel_case_types)]

use crate::{iox2_semantic_string_error_e, IntoCInt, IOX2_OK};
use crate::{iox2_semantic_string_error_e, HandleToType, IntoCInt, IOX2_OK};

use iceoryx2::prelude::*;
use iceoryx2_bb_elementary::static_assert::*;
Expand All @@ -36,26 +36,36 @@ pub struct iox2_node_name_t {
deleter: fn(*mut iox2_node_name_t),
}

impl iox2_node_name_t {
pub(crate) fn cast(node_name: iox2_node_name_h) -> *mut Self {
node_name as *mut _ as _
}

pub(crate) fn as_handle(&mut self) -> iox2_node_name_h {
self as *mut _ as _
}
}

pub struct iox2_node_name_h_t;
/// The handle for `iox2_node_name_t`. Passing the handle to an function transfers the ownership.
/// The owning handle for `iox2_node_name_t`. Passing the handle to an function transfers the ownership.
pub type iox2_node_name_h = *mut iox2_node_name_h_t;

pub struct iox2_node_name_ref_h_t;
/// The non-owning handle for `iox2_node_name_t`. Passing the handle to an function does not transfers the ownership.
pub type iox2_node_name_ref_h = *mut iox2_node_name_ref_h_t;

// NOTE check the README.md for using opaque types with renaming
/// The immutable pointer to the underlying `NodeName`
pub type iox2_node_name_ptr = *const NodeName;
/// The mutable pointer to the underlying `NodeName`
pub type iox2_node_name_mut_ptr = *mut NodeName;

impl HandleToType for iox2_node_name_h {
type Target = *mut iox2_node_name_t;

fn as_type(self) -> Self::Target {
self as *mut _ as _
}
}

impl HandleToType for iox2_node_name_ref_h {
type Target = *mut iox2_node_name_t;

fn as_type(self) -> Self::Target {
self as *mut _ as _
}
}

// END type definition

// BEGIN C API
Expand Down Expand Up @@ -144,7 +154,7 @@ pub unsafe extern "C" fn iox2_cast_node_name_ptr(
) -> iox2_node_name_ptr {
debug_assert!(!node_name_handle.is_null());

(*iox2_node_name_t::cast(node_name_handle)).value.as_ref()
(*node_name_handle.as_type()).value.as_ref()
}

/// This function gives access to the node name as a C-style string
Expand Down Expand Up @@ -193,7 +203,7 @@ pub unsafe extern "C" fn iox2_node_name_as_c_str(
pub unsafe extern "C" fn iox2_node_name_drop(node_name_handle: iox2_node_name_h) {
debug_assert!(!node_name_handle.is_null());

let node_name = &mut (*iox2_node_name_t::cast(node_name_handle));
let node_name = &mut *node_name_handle.as_type();

std::ptr::drop_in_place(node_name.value.as_option_mut());
(node_name.deleter)(node_name);
Expand Down

0 comments on commit 85cc6ee

Please sign in to comment.