1use std::ffi::CStr;
11use std::os::raw::c_char;
12use std::ptr;
13use std::sync::Arc;
14
15use hdds::api::{Participant, Publisher, QoS, Subscriber};
16
17use super::{BytePayload, HddsDataReader, HddsDataWriter, HddsParticipant, HddsQoS};
18
19#[repr(C)]
21pub struct HddsPublisher {
22 _private: [u8; 0],
23}
24
25#[repr(C)]
27pub struct HddsSubscriber {
28 _private: [u8; 0],
29}
30
31#[no_mangle]
43pub unsafe extern "C" fn hdds_publisher_create(
44 participant: *mut HddsParticipant,
45) -> *mut HddsPublisher {
46 hdds_publisher_create_with_qos(participant, ptr::null())
47}
48
49#[no_mangle]
58pub unsafe extern "C" fn hdds_publisher_create_with_qos(
59 participant: *mut HddsParticipant,
60 qos: *const HddsQoS,
61) -> *mut HddsPublisher {
62 if participant.is_null() {
63 return ptr::null_mut();
64 }
65
66 let participant_ref = &*participant.cast::<Arc<Participant>>();
67
68 let qos_value = if qos.is_null() {
69 QoS::default()
70 } else {
71 (*qos.cast::<QoS>()).clone()
72 };
73
74 match participant_ref.create_publisher(qos_value) {
75 Ok(publisher) => Box::into_raw(Box::new(publisher)).cast::<HddsPublisher>(),
76 Err(e) => {
77 log::error!("Failed to create publisher: {:?}", e);
78 ptr::null_mut()
79 }
80 }
81}
82
83#[no_mangle]
88pub unsafe extern "C" fn hdds_publisher_destroy(publisher: *mut HddsPublisher) {
89 if !publisher.is_null() {
90 let _ = Box::from_raw(publisher.cast::<Publisher>());
91 }
92}
93
94#[no_mangle]
106pub unsafe extern "C" fn hdds_subscriber_create(
107 participant: *mut HddsParticipant,
108) -> *mut HddsSubscriber {
109 hdds_subscriber_create_with_qos(participant, ptr::null())
110}
111
112#[no_mangle]
121pub unsafe extern "C" fn hdds_subscriber_create_with_qos(
122 participant: *mut HddsParticipant,
123 qos: *const HddsQoS,
124) -> *mut HddsSubscriber {
125 if participant.is_null() {
126 return ptr::null_mut();
127 }
128
129 let participant_ref = &*participant.cast::<Arc<Participant>>();
130
131 let qos_value = if qos.is_null() {
132 QoS::default()
133 } else {
134 (*qos.cast::<QoS>()).clone()
135 };
136
137 match participant_ref.create_subscriber(qos_value) {
138 Ok(subscriber) => Box::into_raw(Box::new(subscriber)).cast::<HddsSubscriber>(),
139 Err(e) => {
140 log::error!("Failed to create subscriber: {:?}", e);
141 ptr::null_mut()
142 }
143 }
144}
145
146#[no_mangle]
151pub unsafe extern "C" fn hdds_subscriber_destroy(subscriber: *mut HddsSubscriber) {
152 if !subscriber.is_null() {
153 let _ = Box::from_raw(subscriber.cast::<Subscriber>());
154 }
155}
156
157#[no_mangle]
170pub unsafe extern "C" fn hdds_publisher_create_writer(
171 publisher: *mut HddsPublisher,
172 topic_name: *const c_char,
173) -> *mut HddsDataWriter {
174 hdds_publisher_create_writer_with_qos(publisher, topic_name, ptr::null())
175}
176
177#[no_mangle]
187pub unsafe extern "C" fn hdds_publisher_create_writer_with_qos(
188 publisher: *mut HddsPublisher,
189 topic_name: *const c_char,
190 qos: *const HddsQoS,
191) -> *mut HddsDataWriter {
192 if publisher.is_null() || topic_name.is_null() {
193 return ptr::null_mut();
194 }
195
196 let Ok(topic_str) = CStr::from_ptr(topic_name).to_str() else {
197 return ptr::null_mut();
198 };
199
200 let publisher_ref = &*publisher.cast::<Publisher>();
201
202 let qos_value = if qos.is_null() {
203 QoS::default()
204 } else {
205 (*qos.cast::<QoS>()).clone()
206 };
207
208 match publisher_ref.create_writer::<BytePayload>(topic_str, qos_value) {
209 Ok(writer) => Box::into_raw(Box::new(writer)).cast::<HddsDataWriter>(),
210 Err(e) => {
211 log::error!("Failed to create writer from publisher: {:?}", e);
212 ptr::null_mut()
213 }
214 }
215}
216
217#[no_mangle]
230pub unsafe extern "C" fn hdds_subscriber_create_reader(
231 subscriber: *mut HddsSubscriber,
232 topic_name: *const c_char,
233) -> *mut HddsDataReader {
234 hdds_subscriber_create_reader_with_qos(subscriber, topic_name, ptr::null())
235}
236
237#[no_mangle]
247pub unsafe extern "C" fn hdds_subscriber_create_reader_with_qos(
248 subscriber: *mut HddsSubscriber,
249 topic_name: *const c_char,
250 qos: *const HddsQoS,
251) -> *mut HddsDataReader {
252 if subscriber.is_null() || topic_name.is_null() {
253 return ptr::null_mut();
254 }
255
256 let Ok(topic_str) = CStr::from_ptr(topic_name).to_str() else {
257 return ptr::null_mut();
258 };
259
260 let subscriber_ref = &*subscriber.cast::<Subscriber>();
261
262 let qos_value = if qos.is_null() {
263 QoS::default()
264 } else {
265 (*qos.cast::<QoS>()).clone()
266 };
267
268 match subscriber_ref.create_reader::<BytePayload>(topic_str, qos_value) {
269 Ok(reader) => Box::into_raw(Box::new(reader)).cast::<HddsDataReader>(),
270 Err(e) => {
271 log::error!("Failed to create reader from subscriber: {:?}", e);
272 ptr::null_mut()
273 }
274 }
275}