use crate::*;
use derivative::Derivative;
use log::warn;
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
ffi::{CStr, CString},
mem::ManuallyDrop,
os::raw::c_char,
};
pub const DDS_INFINITE_TIME: i64 = 0x7FFFFFFFFFFFFFFF;
pub const DDS_100MS_DURATION: i64 = 100 * 1_000_000;
pub const DDS_1S_DURATION: i64 = 1_000_000_000;
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct Qos {
pub user_data: Option<Vec<u8>>,
pub topic_data: Option<Vec<u8>>,
pub group_data: Option<Vec<u8>>,
pub durability: Option<Durability>,
pub durability_service: Option<DurabilityService>,
pub presentation: Option<Presentation>,
pub deadline: Option<Deadline>,
pub latency_budget: Option<LatencyBudget>,
pub ownership: Option<Ownership>,
pub ownership_strength: Option<OwnershipStrength>,
pub liveliness: Option<Liveliness>,
pub time_based_filter: Option<TimeBasedFilter>,
pub partition: Option<Vec<String>>,
pub reliability: Option<Reliability>,
pub transport_priority: Option<TransportPriority>,
pub lifespan: Option<Lifespan>,
pub destination_order: Option<DestinationOrder>,
pub history: Option<History>,
pub resource_limits: Option<ResourceLimits>,
pub writer_data_lifecycle: Option<WriterDataLifecycle>,
pub reader_data_lifecycle: Option<ReaderDataLifecycle>,
pub writer_batching: Option<WriterBatching>,
pub type_consistency: Option<TypeConsistency>,
pub entity_name: Option<EntityName>,
pub properties: Option<HashMap<String, String>>,
pub ignore_local: Option<IgnoreLocal>,
pub data_representation: Option<Vec<dds_data_representation_id_t>>,
}
#[allow(clippy::missing_safety_doc)]
impl Qos {
pub unsafe fn from_qos_native(qos: *mut dds_qos_t) -> Self {
Qos {
user_data: user_data_from_qos_native(qos),
topic_data: topic_data_from_qos_native(qos),
group_data: group_data_from_qos_native(qos),
durability: durability_from_qos_native(qos),
durability_service: durability_service_from_qos_native(qos),
presentation: presentation_from_qos_native(qos),
deadline: deadline_from_qos_native(qos),
latency_budget: latency_budget_from_qos_native(qos),
ownership: ownership_from_qos_native(qos),
ownership_strength: ownership_strength_from_qos_native(qos),
liveliness: liveliness_from_qos_native(qos),
time_based_filter: time_based_filter_from_qos_native(qos),
partition: partition_from_qos_native(qos),
reliability: reliability_from_qos_native(qos),
transport_priority: transport_priority_from_qos_native(qos),
lifespan: lifespan_from_qos_native(qos),
destination_order: destination_order_from_qos_native(qos),
history: history_from_qos_native(qos),
resource_limits: resource_limits_from_qos_native(qos),
writer_data_lifecycle: writer_data_lifecycle_from_qos_native(qos),
reader_data_lifecycle: reader_data_lifecycle_from_qos_native(qos),
writer_batching: writer_batching_from_qos_native(qos),
type_consistency: type_consistency_from_qos_native(qos),
entity_name: entity_name_from_qos_native(qos),
properties: properties_from_qos_native(qos),
ignore_local: ignore_local_from_qos_native(qos),
data_representation: data_representation_from_qos_native(qos),
}
}
pub unsafe fn to_qos_native(&self) -> *mut dds_qos_t {
unsafe {
let qos = dds_create_qos();
user_data_to_qos_native(qos, &self.user_data);
topic_data_to_qos_native(qos, &self.topic_data);
group_data_to_qos_native(qos, &self.group_data);
durability_to_qos_native(qos, &self.durability);
durability_service_to_qos_native(qos, &self.durability_service);
presentation_to_qos_native(qos, &self.presentation);
deadline_to_qos_native(qos, &self.deadline);
latency_budget_to_qos_native(qos, &self.latency_budget);
ownership_to_qos_native(qos, &self.ownership);
ownership_strength_to_qos_native(qos, &self.ownership_strength);
liveliness_to_qos_native(qos, &self.liveliness);
time_based_filter_to_qos_native(qos, &self.time_based_filter);
partition_to_qos_native(qos, &self.partition);
reliability_to_qos_native(qos, &self.reliability);
transport_priority_to_qos_native(qos, &self.transport_priority);
lifespan_to_qos_native(qos, &self.lifespan);
destination_order_to_qos_native(qos, &self.destination_order);
history_to_qos_native(qos, &self.history);
resource_limits_to_qos_native(qos, &self.resource_limits);
writer_data_lifecycle_to_qos_native(qos, &self.writer_data_lifecycle);
reader_data_lifecycle_to_qos_native(qos, &self.reader_data_lifecycle);
writer_batching_to_qos_native(qos, &self.writer_batching);
type_consistency_to_qos_native(qos, &self.type_consistency);
entity_name_to_qos_native(qos, &self.entity_name);
properties_to_qos_native(qos, &self.properties);
ignore_local_to_qos_native(qos, &self.ignore_local);
data_representation_to_qos_native(qos, &self.data_representation);
qos
}
}
pub unsafe fn delete_qos_native(qos: *mut dds_qos_t) {
unsafe {
dds_delete_qos(qos);
}
}
}
impl Default for Qos {
fn default() -> Self {
unsafe {
let native_qos = dds_create_qos();
let qos = Qos::from_qos_native(native_qos);
dds_delete_qos(native_qos);
qos
}
}
}
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
pub struct Durability {
pub kind: DurabilityKind,
}
#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub enum DurabilityKind {
#[default]
VOLATILE = dds_durability_kind_DDS_DURABILITY_VOLATILE as isize,
TRANSIENT_LOCAL = dds_durability_kind_DDS_DURABILITY_TRANSIENT_LOCAL as isize,
TRANSIENT = dds_durability_kind_DDS_DURABILITY_TRANSIENT as isize,
PERSISTENT = dds_durability_kind_DDS_DURABILITY_PERSISTENT as isize,
}
impl From<&dds_durability_kind_t> for DurabilityKind {
fn from(from: &dds_durability_kind_t) -> Self {
#[allow(non_upper_case_globals)]
match from {
&dds_durability_kind_DDS_DURABILITY_VOLATILE => DurabilityKind::VOLATILE,
&dds_durability_kind_DDS_DURABILITY_TRANSIENT_LOCAL => DurabilityKind::TRANSIENT_LOCAL,
&dds_durability_kind_DDS_DURABILITY_TRANSIENT => DurabilityKind::TRANSIENT,
&dds_durability_kind_DDS_DURABILITY_PERSISTENT => DurabilityKind::PERSISTENT,
x => panic!("Invalid numeric value for DurabilityKind: {}", x),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct DurabilityService {
#[derivative(Default(value = "0"))]
pub service_cleanup_delay: dds_duration_t,
#[derivative(Default(value = "HistoryKind::KEEP_LAST"))]
pub history_kind: HistoryKind,
#[derivative(Default(value = "1"))]
pub history_depth: i32,
#[derivative(Default(value = "DDS_LENGTH_UNLIMITED"))]
pub max_samples: i32,
#[derivative(Default(value = "DDS_LENGTH_UNLIMITED"))]
pub max_instances: i32,
#[derivative(Default(value = "DDS_LENGTH_UNLIMITED"))]
pub max_samples_per_instance: i32,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct Reliability {
#[derivative(Default(value = "ReliabilityKind::BEST_EFFORT"))]
pub kind: ReliabilityKind,
#[derivative(Default(value = "DDS_100MS_DURATION"))]
pub max_blocking_time: dds_duration_t,
}
#[derive(Debug, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub enum ReliabilityKind {
BEST_EFFORT = dds_reliability_kind_DDS_RELIABILITY_BEST_EFFORT as isize,
RELIABLE = dds_reliability_kind_DDS_RELIABILITY_RELIABLE as isize,
}
impl From<&dds_reliability_kind_t> for ReliabilityKind {
fn from(from: &dds_reliability_kind_t) -> Self {
#[allow(non_upper_case_globals)]
match from {
&dds_reliability_kind_DDS_RELIABILITY_BEST_EFFORT => ReliabilityKind::BEST_EFFORT,
&dds_reliability_kind_DDS_RELIABILITY_RELIABLE => ReliabilityKind::RELIABLE,
x => panic!("Invalid numeric value for ReliabilityKind: {}", x),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct Deadline {
#[derivative(Default(value = "DDS_INFINITE_TIME"))]
pub period: dds_duration_t,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct LatencyBudget {
#[derivative(Default(value = "0"))]
pub duration: dds_duration_t,
}
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
pub struct DestinationOrder {
pub kind: DestinationOrderKind,
}
#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub enum DestinationOrderKind {
#[default]
BY_RECEPTION_TIMESTAMP =
dds_destination_order_kind_DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP as isize,
BY_SOURCE_TIMESTAMP =
dds_destination_order_kind_DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP as isize,
}
impl From<&dds_destination_order_kind_t> for DestinationOrderKind {
fn from(from: &dds_destination_order_kind_t) -> Self {
#[allow(non_upper_case_globals)]
match from {
&dds_destination_order_kind_DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP => {
DestinationOrderKind::BY_RECEPTION_TIMESTAMP
}
&dds_destination_order_kind_DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP => {
DestinationOrderKind::BY_SOURCE_TIMESTAMP
}
x => panic!("Invalid numeric value for DestinationOrderKind: {}", x),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct Liveliness {
#[derivative(Default(value = "LivelinessKind::AUTOMATIC"))]
pub kind: LivelinessKind,
#[derivative(Default(value = "DDS_INFINITE_TIME"))]
pub lease_duration: dds_duration_t,
}
#[derive(Debug, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub enum LivelinessKind {
AUTOMATIC = dds_liveliness_kind_DDS_LIVELINESS_AUTOMATIC as isize,
MANUAL_BY_PARTICIPANT = dds_liveliness_kind_DDS_LIVELINESS_MANUAL_BY_PARTICIPANT as isize,
MANUAL_BY_TOPIC = dds_liveliness_kind_DDS_LIVELINESS_MANUAL_BY_TOPIC as isize,
}
impl From<&dds_liveliness_kind_t> for LivelinessKind {
fn from(from: &dds_liveliness_kind_t) -> Self {
#[allow(non_upper_case_globals)]
match from {
&dds_liveliness_kind_DDS_LIVELINESS_AUTOMATIC => LivelinessKind::AUTOMATIC,
&dds_liveliness_kind_DDS_LIVELINESS_MANUAL_BY_PARTICIPANT => {
LivelinessKind::MANUAL_BY_PARTICIPANT
}
&dds_liveliness_kind_DDS_LIVELINESS_MANUAL_BY_TOPIC => LivelinessKind::MANUAL_BY_TOPIC,
x => panic!("Invalid numeric value for LivelinessKind: {}", x),
}
}
}
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
pub struct Ownership {
pub kind: OwnershipKind,
}
#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub enum OwnershipKind {
#[default]
SHARED = dds_ownership_kind_DDS_OWNERSHIP_SHARED as isize,
EXCLUSIVE = dds_ownership_kind_DDS_OWNERSHIP_EXCLUSIVE as isize,
}
impl From<&dds_ownership_kind_t> for OwnershipKind {
fn from(from: &dds_ownership_kind_t) -> Self {
#[allow(non_upper_case_globals)]
match from {
&dds_ownership_kind_DDS_OWNERSHIP_SHARED => OwnershipKind::SHARED,
&dds_ownership_kind_DDS_OWNERSHIP_EXCLUSIVE => OwnershipKind::EXCLUSIVE,
x => panic!("Invalid numeric value for OwnershipKind: {}", x),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct History {
pub kind: HistoryKind,
#[derivative(Default(value = "1"))]
pub depth: i32,
}
#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub enum HistoryKind {
#[default]
KEEP_LAST = dds_history_kind_DDS_HISTORY_KEEP_LAST as isize,
KEEP_ALL = dds_history_kind_DDS_HISTORY_KEEP_ALL as isize,
}
impl From<&dds_history_kind_t> for HistoryKind {
fn from(from: &dds_history_kind_t) -> Self {
#[allow(non_upper_case_globals)]
match from {
&dds_history_kind_DDS_HISTORY_KEEP_LAST => HistoryKind::KEEP_LAST,
&dds_history_kind_DDS_HISTORY_KEEP_ALL => HistoryKind::KEEP_ALL,
x => panic!("Invalid numeric value for HistoryKind: {}", x),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct ResourceLimits {
#[derivative(Default(value = "DDS_LENGTH_UNLIMITED"))]
pub max_samples: i32,
#[derivative(Default(value = "DDS_LENGTH_UNLIMITED"))]
pub max_instances: i32,
#[derivative(Default(value = "DDS_LENGTH_UNLIMITED"))]
pub max_samples_per_instance: i32,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct Presentation {
pub access_scope: PresentationAccessScopeKind,
#[derivative(Default(value = "false"))]
pub coherent_access: bool,
#[derivative(Default(value = "false"))]
pub ordered_access: bool,
}
#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub enum PresentationAccessScopeKind {
#[default]
INSTANCE = dds_presentation_access_scope_kind_DDS_PRESENTATION_INSTANCE as isize,
TOPIC = dds_presentation_access_scope_kind_DDS_PRESENTATION_TOPIC as isize,
GROUP = dds_presentation_access_scope_kind_DDS_PRESENTATION_GROUP as isize,
}
impl From<&dds_presentation_access_scope_kind_t> for PresentationAccessScopeKind {
fn from(from: &dds_presentation_access_scope_kind_t) -> Self {
#[allow(non_upper_case_globals)]
match from {
&dds_presentation_access_scope_kind_DDS_PRESENTATION_INSTANCE => {
PresentationAccessScopeKind::INSTANCE
}
&dds_presentation_access_scope_kind_DDS_PRESENTATION_TOPIC => {
PresentationAccessScopeKind::TOPIC
}
&dds_presentation_access_scope_kind_DDS_PRESENTATION_GROUP => {
PresentationAccessScopeKind::GROUP
}
x => panic!(
"Invalid numeric value for PresentationAccessScopeKind: {}",
x
),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct Lifespan {
#[derivative(Default(value = "DDS_INFINITE_TIME"))]
pub duration: dds_duration_t,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct OwnershipStrength {
#[derivative(Default(value = "0"))]
pub value: i32,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct TimeBasedFilter {
#[derivative(Default(value = "0"))]
pub minimum_separation: dds_duration_t,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct TransportPriority {
#[derivative(Default(value = "0"))]
pub value: i32,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct WriterDataLifecycle {
#[derivative(Default(value = "true"))]
pub autodispose_unregistered_instances: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct ReaderDataLifecycle {
#[derivative(Default(value = "DDS_INFINITE_TIME"))]
pub autopurge_nowriter_samples_delay: dds_duration_t,
#[derivative(Default(value = "DDS_INFINITE_TIME"))]
pub autopurge_disposed_samples_delay: dds_duration_t,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct WriterBatching {
#[derivative(Default(value = "false"))]
pub batch_updates: bool,
}
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
pub struct IgnoreLocal {
pub kind: IgnoreLocalKind,
}
#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub enum IgnoreLocalKind {
#[default]
NONE = dds_ignorelocal_kind_DDS_IGNORELOCAL_NONE as isize,
PARTICIPANT = dds_ignorelocal_kind_DDS_IGNORELOCAL_PARTICIPANT as isize,
PROCESS = dds_ignorelocal_kind_DDS_IGNORELOCAL_PROCESS as isize,
}
impl From<&dds_ignorelocal_kind_t> for IgnoreLocalKind {
fn from(from: &dds_ignorelocal_kind_t) -> Self {
#[allow(non_upper_case_globals)]
match from {
&dds_ignorelocal_kind_DDS_IGNORELOCAL_NONE => IgnoreLocalKind::NONE,
&dds_ignorelocal_kind_DDS_IGNORELOCAL_PARTICIPANT => IgnoreLocalKind::PARTICIPANT,
&dds_ignorelocal_kind_DDS_IGNORELOCAL_PROCESS => IgnoreLocalKind::PROCESS,
x => panic!("Invalid numeric value for IgnoreLocalKind: {}", x),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct TypeConsistency {
pub kind: TypeConsistencyKind,
#[derivative(Default(value = "false"))]
pub ignore_sequence_bounds: bool,
#[derivative(Default(value = "false"))]
pub ignore_string_bounds: bool,
#[derivative(Default(value = "false"))]
pub ignore_member_names: bool,
#[derivative(Default(value = "false"))]
pub prevent_type_widening: bool,
#[derivative(Default(value = "false"))]
pub force_type_validation: bool,
}
#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub enum TypeConsistencyKind {
#[default]
DISALLOW_TYPE_COERCION =
dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_DISALLOW_TYPE_COERCION as isize,
ALLOW_TYPE_COERCION =
dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_ALLOW_TYPE_COERCION as isize,
}
impl From<&dds_type_consistency_kind_t> for TypeConsistencyKind {
fn from(from: &dds_type_consistency_kind_t) -> Self {
#[allow(non_upper_case_globals)]
match from {
&dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_DISALLOW_TYPE_COERCION => {
TypeConsistencyKind::DISALLOW_TYPE_COERCION
}
&dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_ALLOW_TYPE_COERCION => {
TypeConsistencyKind::ALLOW_TYPE_COERCION
}
x => panic!("Invalid numeric value for TypeConsistencyKind: {}", x),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Derivative)]
#[derivative(Default)]
pub struct EntityName {
pub name: String,
}
unsafe fn user_data_from_qos_native(qos: *const dds_qos_t) -> Option<Vec<u8>> {
let mut sz: usize = 0;
let mut value: *mut ::std::os::raw::c_void = std::ptr::null_mut();
if dds_qget_userdata(qos, &mut value, &mut sz) {
let vec = if value.is_null() {
Vec::with_capacity(0)
} else {
Vec::from_raw_parts(value as *mut ::std::os::raw::c_uchar, sz, sz)
};
to_option(vec)
} else {
None
}
}
unsafe fn user_data_to_qos_native(qos: *mut dds_qos_t, user_data: &Option<Vec<u8>>) {
if let Some(user_data) = user_data {
let ptr = user_data.as_ptr();
dds_qset_userdata(qos, ptr as *const ::std::os::raw::c_void, user_data.len());
}
}
unsafe fn topic_data_from_qos_native(qos: *const dds_qos_t) -> Option<Vec<u8>> {
let mut sz: usize = 0;
let mut value: *mut ::std::os::raw::c_void = std::ptr::null_mut();
if dds_qget_topicdata(qos, &mut value, &mut sz) {
let vec = if value.is_null() {
Vec::with_capacity(0)
} else {
Vec::from_raw_parts(value as *mut ::std::os::raw::c_uchar, sz, sz)
};
to_option(vec)
} else {
None
}
}
unsafe fn topic_data_to_qos_native(qos: *mut dds_qos_t, topic_data: &Option<Vec<u8>>) {
if let Some(topic_data) = topic_data {
let ptr = topic_data.as_ptr();
dds_qset_topicdata(qos, ptr as *const ::std::os::raw::c_void, topic_data.len());
}
}
unsafe fn group_data_from_qos_native(qos: *const dds_qos_t) -> Option<Vec<u8>> {
let mut sz: usize = 0;
let mut value: *mut ::std::os::raw::c_void = std::ptr::null_mut();
if dds_qget_groupdata(qos, &mut value, &mut sz) {
let vec = if value.is_null() {
Vec::with_capacity(0)
} else {
Vec::from_raw_parts(value as *mut ::std::os::raw::c_uchar, sz, sz)
};
to_option(vec)
} else {
None
}
}
unsafe fn group_data_to_qos_native(qos: *mut dds_qos_t, group_data: &Option<Vec<u8>>) {
if let Some(group_data) = group_data {
let ptr = group_data.as_ptr();
dds_qset_groupdata(qos, ptr as *const ::std::os::raw::c_void, group_data.len());
}
}
unsafe fn durability_from_qos_native(qos: *const dds_qos_t) -> Option<Durability> {
let mut dur_kind: dds_durability_kind_t = dds_durability_kind_DDS_DURABILITY_VOLATILE;
if dds_qget_durability(qos, &mut dur_kind) {
to_option(Durability {
kind: DurabilityKind::from(&dur_kind),
})
} else {
None
}
}
unsafe fn durability_to_qos_native(qos: *mut dds_qos_t, durability: &Option<Durability>) {
if let Some(durability) = durability {
dds_qset_durability(qos, durability.kind as dds_durability_kind_t);
}
}
unsafe fn history_from_qos_native(qos: *const dds_qos_t) -> Option<History> {
let mut hist_kind: dds_history_kind_t = dds_history_kind_DDS_HISTORY_KEEP_LAST;
let mut depth: i32 = 1;
if dds_qget_history(qos, &mut hist_kind, &mut depth) {
to_option(History {
kind: HistoryKind::from(&hist_kind),
depth,
})
} else {
None
}
}
unsafe fn history_to_qos_native(qos: *mut dds_qos_t, history: &Option<History>) {
if let Some(history) = history {
dds_qset_history(qos, history.kind as dds_history_kind_t, history.depth);
}
}
unsafe fn resource_limits_from_qos_native(qos: *const dds_qos_t) -> Option<ResourceLimits> {
let mut max_samples = DDS_LENGTH_UNLIMITED;
let mut max_instances = DDS_LENGTH_UNLIMITED;
let mut max_samples_per_instance = DDS_LENGTH_UNLIMITED;
if dds_qget_resource_limits(
qos,
&mut max_samples,
&mut max_instances,
&mut max_samples_per_instance,
) {
to_option(ResourceLimits {
max_samples,
max_instances,
max_samples_per_instance,
})
} else {
None
}
}
unsafe fn resource_limits_to_qos_native(
qos: *mut dds_qos_t,
resource_limits: &Option<ResourceLimits>,
) {
if let Some(resource_limits) = resource_limits {
dds_qset_resource_limits(
qos,
resource_limits.max_samples,
resource_limits.max_instances,
resource_limits.max_samples_per_instance,
);
}
}
unsafe fn presentation_from_qos_native(qos: *const dds_qos_t) -> Option<Presentation> {
let mut pres_access_scope: dds_presentation_access_scope_kind_t =
dds_presentation_access_scope_kind_DDS_PRESENTATION_INSTANCE;
let mut coherent_access: bool = false;
let mut ordered_access: bool = false;
if dds_qget_presentation(
qos,
&mut pres_access_scope,
&mut coherent_access,
&mut ordered_access,
) {
to_option(Presentation {
access_scope: PresentationAccessScopeKind::from(&pres_access_scope),
coherent_access,
ordered_access,
})
} else {
None
}
}
unsafe fn presentation_to_qos_native(qos: *mut dds_qos_t, presentation: &Option<Presentation>) {
if let Some(presentation) = presentation {
dds_qset_presentation(
qos,
presentation.access_scope as dds_presentation_access_scope_kind_t,
presentation.coherent_access,
presentation.ordered_access,
);
}
}
unsafe fn lifespan_from_qos_native(qos: *const dds_qos_t) -> Option<Lifespan> {
let mut duration: dds_duration_t = DDS_INFINITE_TIME;
if dds_qget_lifespan(qos, &mut duration) {
to_option(Lifespan { duration })
} else {
None
}
}
unsafe fn lifespan_to_qos_native(qos: *mut dds_qos_t, lifespan: &Option<Lifespan>) {
if let Some(lifespan) = lifespan {
dds_qset_lifespan(qos, lifespan.duration);
}
}
unsafe fn deadline_from_qos_native(qos: *const dds_qos_t) -> Option<Deadline> {
let mut period: dds_duration_t = DDS_INFINITE_TIME;
if dds_qget_deadline(qos, &mut period) {
to_option(Deadline { period })
} else {
None
}
}
unsafe fn deadline_to_qos_native(qos: *mut dds_qos_t, deadline: &Option<Deadline>) {
if let Some(deadline) = deadline {
dds_qset_deadline(qos, deadline.period);
}
}
unsafe fn latency_budget_from_qos_native(qos: *const dds_qos_t) -> Option<LatencyBudget> {
let mut duration: dds_duration_t = 0;
if dds_qget_latency_budget(qos, &mut duration) {
to_option(LatencyBudget { duration })
} else {
None
}
}
unsafe fn latency_budget_to_qos_native(
qos: *mut dds_qos_t,
latency_budget: &Option<LatencyBudget>,
) {
if let Some(latency_budget) = latency_budget {
dds_qset_latency_budget(qos, latency_budget.duration);
}
}
unsafe fn ownership_from_qos_native(qos: *const dds_qos_t) -> Option<Ownership> {
let mut own_kind: dds_ownership_kind_t = dds_ownership_kind_DDS_OWNERSHIP_SHARED;
if dds_qget_ownership(qos, &mut own_kind) {
to_option(Ownership {
kind: OwnershipKind::from(&own_kind),
})
} else {
None
}
}
unsafe fn ownership_to_qos_native(qos: *mut dds_qos_t, ownership: &Option<Ownership>) {
if let Some(ownership) = ownership {
dds_qset_ownership(qos, ownership.kind as dds_ownership_kind_t);
}
}
unsafe fn ownership_strength_from_qos_native(qos: *const dds_qos_t) -> Option<OwnershipStrength> {
let mut value: i32 = 0;
if dds_qget_ownership_strength(qos, &mut value) {
to_option(OwnershipStrength { value })
} else {
None
}
}
unsafe fn ownership_strength_to_qos_native(
qos: *mut dds_qos_t,
ownership_strength: &Option<OwnershipStrength>,
) {
if let Some(ownership_strength) = ownership_strength {
dds_qset_ownership_strength(qos, ownership_strength.value);
}
}
unsafe fn liveliness_from_qos_native(qos: *const dds_qos_t) -> Option<Liveliness> {
let mut live_kind: dds_liveliness_kind_t = dds_liveliness_kind_DDS_LIVELINESS_AUTOMATIC;
let mut lease_duration: dds_duration_t = DDS_INFINITE_TIME;
if dds_qget_liveliness(qos, &mut live_kind, &mut lease_duration) {
to_option(Liveliness {
kind: LivelinessKind::from(&live_kind),
lease_duration,
})
} else {
None
}
}
unsafe fn liveliness_to_qos_native(qos: *mut dds_qos_t, liveliness: &Option<Liveliness>) {
if let Some(liveliness) = liveliness {
dds_qset_liveliness(
qos,
liveliness.kind as dds_liveliness_kind_t,
liveliness.lease_duration,
);
}
}
unsafe fn time_based_filter_from_qos_native(qos: *const dds_qos_t) -> Option<TimeBasedFilter> {
let mut minimum_separation: dds_duration_t = 0;
if dds_qget_time_based_filter(qos, &mut minimum_separation) {
to_option(TimeBasedFilter { minimum_separation })
} else {
None
}
}
unsafe fn time_based_filter_to_qos_native(
qos: *mut dds_qos_t,
time_based_filter: &Option<TimeBasedFilter>,
) {
if let Some(time_based_filter) = time_based_filter {
dds_qset_time_based_filter(qos, time_based_filter.minimum_separation);
}
}
unsafe fn partition_from_qos_native(qos: *const dds_qos_t) -> Option<Vec<String>> {
let mut n: u32 = 0;
let mut ps: *mut *mut ::std::os::raw::c_char = std::ptr::null_mut();
if dds_qget_partition(qos, &mut n, &mut ps) {
let mut partitions: Vec<String> = Vec::with_capacity(n as usize);
for k in 0..n {
let p_offset = *(ps.offset(k as isize));
let p = CStr::from_ptr(p_offset).to_str().unwrap();
partitions.push(String::from(p));
dds_free(p_offset as *mut ::std::os::raw::c_void);
}
dds_free(ps as *mut ::std::os::raw::c_void);
to_option(partitions)
} else {
None
}
}
unsafe fn partition_to_qos_native(qos: *mut dds_qos_t, partitions: &Option<Vec<String>>) {
if let Some(partitions) = partitions {
let mut vcs: Vec<CString> = Vec::with_capacity(partitions.len());
let mut vptr: Vec<*const c_char> = Vec::with_capacity(partitions.len());
for p in partitions {
let cs = CString::new(p.as_str()).unwrap();
vptr.push(cs.as_ptr());
vcs.push(cs);
}
let (ptr, len, cap) = vec_into_raw_parts(vptr);
dds_qset_partition(qos, len as u32, ptr);
drop(Vec::from_raw_parts(ptr, len, cap));
}
}
unsafe fn reliability_from_qos_native(qos: *const dds_qos_t) -> Option<Reliability> {
let mut rel_kind: dds_reliability_kind_t = dds_reliability_kind_DDS_RELIABILITY_BEST_EFFORT;
let mut max_blocking_time: dds_duration_t = DDS_100MS_DURATION;
if dds_qget_reliability(qos, &mut rel_kind, &mut max_blocking_time) {
to_option(Reliability {
kind: ReliabilityKind::from(&rel_kind),
max_blocking_time,
})
} else {
None
}
}
unsafe fn reliability_to_qos_native(qos: *mut dds_qos_t, reliability: &Option<Reliability>) {
if let Some(reliability) = reliability {
dds_qset_reliability(
qos,
reliability.kind as dds_reliability_kind_t,
reliability.max_blocking_time,
);
}
}
unsafe fn transport_priority_from_qos_native(qos: *const dds_qos_t) -> Option<TransportPriority> {
let mut value: i32 = 0;
if dds_qget_transport_priority(qos, &mut value) {
to_option(TransportPriority { value })
} else {
None
}
}
unsafe fn transport_priority_to_qos_native(
qos: *mut dds_qos_t,
transport_priority: &Option<TransportPriority>,
) {
if let Some(transport_priority) = transport_priority {
dds_qset_transport_priority(qos, transport_priority.value);
}
}
unsafe fn destination_order_from_qos_native(qos: *const dds_qos_t) -> Option<DestinationOrder> {
let mut dest_kind: dds_destination_order_kind_t =
dds_destination_order_kind_DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP;
if dds_qget_destination_order(qos, &mut dest_kind) {
to_option(DestinationOrder {
kind: DestinationOrderKind::from(&dest_kind),
})
} else {
None
}
}
unsafe fn destination_order_to_qos_native(
qos: *mut dds_qos_t,
destination_order: &Option<DestinationOrder>,
) {
if let Some(destination_order) = destination_order {
dds_qset_destination_order(qos, destination_order.kind as dds_destination_order_kind_t);
}
}
unsafe fn writer_data_lifecycle_from_qos_native(
qos: *const dds_qos_t,
) -> Option<WriterDataLifecycle> {
let mut autodispose_unregistered_instances: bool = false;
if dds_qget_writer_data_lifecycle(qos, &mut autodispose_unregistered_instances) {
to_option(WriterDataLifecycle {
autodispose_unregistered_instances,
})
} else {
None
}
}
unsafe fn writer_data_lifecycle_to_qos_native(
qos: *mut dds_qos_t,
writer_data_lifecycle: &Option<WriterDataLifecycle>,
) {
if let Some(writer_data_lifecycle) = writer_data_lifecycle {
dds_qset_writer_data_lifecycle(
qos,
writer_data_lifecycle.autodispose_unregistered_instances,
);
}
}
unsafe fn reader_data_lifecycle_from_qos_native(
qos: *const dds_qos_t,
) -> Option<ReaderDataLifecycle> {
let mut autopurge_nowriter_samples_delay: dds_duration_t = DDS_INFINITE_TIME;
let mut autopurge_disposed_samples_delay: dds_duration_t = DDS_INFINITE_TIME;
if dds_qget_reader_data_lifecycle(
qos,
&mut autopurge_nowriter_samples_delay,
&mut autopurge_disposed_samples_delay,
) {
to_option(ReaderDataLifecycle {
autopurge_nowriter_samples_delay,
autopurge_disposed_samples_delay,
})
} else {
None
}
}
unsafe fn reader_data_lifecycle_to_qos_native(
qos: *mut dds_qos_t,
reader_data_lifecycle: &Option<ReaderDataLifecycle>,
) {
if let Some(reader_data_lifecycle) = reader_data_lifecycle {
dds_qset_reader_data_lifecycle(
qos,
reader_data_lifecycle.autopurge_nowriter_samples_delay,
reader_data_lifecycle.autopurge_disposed_samples_delay,
);
}
}
unsafe fn writer_batching_from_qos_native(qos: *const dds_qos_t) -> Option<WriterBatching> {
let mut batch_updates: bool = false;
if dds_qget_writer_batching(qos, &mut batch_updates) {
to_option(WriterBatching { batch_updates })
} else {
None
}
}
unsafe fn writer_batching_to_qos_native(
qos: *mut dds_qos_t,
writer_batching: &Option<WriterBatching>,
) {
if let Some(writer_batching) = writer_batching {
dds_qset_writer_batching(qos, writer_batching.batch_updates);
}
}
unsafe fn durability_service_from_qos_native(qos: *const dds_qos_t) -> Option<DurabilityService> {
let mut service_cleanup_delay: dds_duration_t = 0;
let mut durability_history_kind: dds_history_kind_t = dds_history_kind_DDS_HISTORY_KEEP_LAST;
let mut history_depth: i32 = 1;
let mut max_samples = DDS_LENGTH_UNLIMITED;
let mut max_instances = DDS_LENGTH_UNLIMITED;
let mut max_samples_per_instance = DDS_LENGTH_UNLIMITED;
if dds_qget_durability_service(
qos,
&mut service_cleanup_delay,
&mut durability_history_kind,
&mut history_depth,
&mut max_samples,
&mut max_instances,
&mut max_samples_per_instance,
) {
to_option(DurabilityService {
service_cleanup_delay,
history_kind: HistoryKind::from(&durability_history_kind),
history_depth,
max_samples,
max_instances,
max_samples_per_instance,
})
} else {
None
}
}
unsafe fn durability_service_to_qos_native(
qos: *mut dds_qos_t,
durability_service: &Option<DurabilityService>,
) {
if let Some(durability_service) = durability_service {
dds_qset_durability_service(
qos,
durability_service.service_cleanup_delay,
durability_service.history_kind as dds_history_kind_t,
durability_service.history_depth,
durability_service.max_samples,
durability_service.max_instances,
durability_service.max_samples_per_instance,
);
}
}
unsafe fn ignore_local_from_qos_native(qos: *const dds_qos_t) -> Option<IgnoreLocal> {
let mut ignore_kind: dds_ignorelocal_kind_t = dds_ignorelocal_kind_DDS_IGNORELOCAL_NONE;
if dds_qget_ignorelocal(qos, &mut ignore_kind) {
to_option(IgnoreLocal {
kind: IgnoreLocalKind::from(&ignore_kind),
})
} else {
None
}
}
unsafe fn ignore_local_to_qos_native(qos: *mut dds_qos_t, ignore_local: &Option<IgnoreLocal>) {
if let Some(ignore_local) = ignore_local {
dds_qset_ignorelocal(qos, ignore_local.kind as dds_ignorelocal_kind_t);
}
}
unsafe fn property_from_qos_native(qos: *const dds_qos_t, name: &str) -> Option<String> {
let mut pvalue: *mut ::std::os::raw::c_char = std::ptr::null_mut();
let cname = CString::new(name).unwrap();
if dds_qget_prop(qos, cname.as_ptr(), &mut pvalue) {
let value = CStr::from_ptr(pvalue).to_str().unwrap();
let policy = to_option(String::from(value));
dds_free(pvalue as *mut ::std::os::raw::c_void);
policy
} else {
None
}
}
unsafe fn properties_from_qos_native(qos: *const dds_qos_t) -> Option<HashMap<String, String>> {
let mut n: u32 = 0;
let mut ps: *mut *mut ::std::os::raw::c_char = std::ptr::null_mut();
if dds_qget_propnames(qos, &mut n, &mut ps) {
let mut map: HashMap<String, String> = HashMap::new();
for k in 0..n {
let p_offset = *(ps.offset(k as isize));
let p = CStr::from_ptr(p_offset).to_str().unwrap();
let name = String::from(p);
dds_free(p_offset as *mut ::std::os::raw::c_void);
if let Some(value) = property_from_qos_native(qos, &name) {
map.insert(name, value);
} else {
warn!("Error retrieving QoS property: name={}", name);
continue;
}
}
dds_free(ps as *mut ::std::os::raw::c_void);
to_option(map)
} else {
None
}
}
unsafe fn properties_to_qos_native(
qos: *mut dds_qos_t,
properties: &Option<HashMap<String, String>>,
) {
if let Some(properties) = properties {
for (name, value) in properties {
let cname = CString::new(name.as_str()).unwrap();
let cvalue = CString::new(value.as_str()).unwrap();
dds_qset_prop(qos, cname.as_ptr(), cvalue.as_ptr());
}
}
}
unsafe fn type_consistency_from_qos_native(qos: *const dds_qos_t) -> Option<TypeConsistency> {
let mut type_kind: dds_type_consistency_kind_t =
dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_DISALLOW_TYPE_COERCION;
let mut ignore_sequence_bounds: bool = false;
let mut ignore_string_bounds: bool = false;
let mut ignore_member_names: bool = false;
let mut prevent_type_widening: bool = false;
let mut force_type_validation: bool = false;
if dds_qget_type_consistency(
qos,
&mut type_kind,
&mut ignore_sequence_bounds,
&mut ignore_string_bounds,
&mut ignore_member_names,
&mut prevent_type_widening,
&mut force_type_validation,
) {
to_option(TypeConsistency {
kind: TypeConsistencyKind::from(&type_kind),
ignore_sequence_bounds,
ignore_string_bounds,
ignore_member_names,
prevent_type_widening,
force_type_validation,
})
} else {
None
}
}
unsafe fn type_consistency_to_qos_native(
qos: *mut dds_qos_t,
type_consistency: &Option<TypeConsistency>,
) {
if let Some(type_consistency) = type_consistency {
dds_qset_type_consistency(
qos,
type_consistency.kind as dds_type_consistency_kind_t,
type_consistency.ignore_sequence_bounds,
type_consistency.ignore_string_bounds,
type_consistency.ignore_member_names,
type_consistency.prevent_type_widening,
type_consistency.force_type_validation,
);
}
}
unsafe fn entity_name_from_qos_native(qos: *const dds_qos_t) -> Option<EntityName> {
let mut ps: *mut ::std::os::raw::c_char = std::ptr::null_mut();
if dds_qget_entity_name(qos, &mut ps) {
let p = CStr::from_ptr(ps).to_str().unwrap();
let policy = to_option(EntityName {
name: String::from(p),
});
dds_free(ps as *mut ::std::os::raw::c_void);
policy
} else {
None
}
}
unsafe fn entity_name_to_qos_native(qos: *mut dds_qos_t, entity_name: &Option<EntityName>) {
if let Some(entity_name) = entity_name {
let cname = CString::new(entity_name.name.as_str()).unwrap();
dds_qset_entity_name(qos, cname.as_ptr());
}
}
unsafe fn data_representation_from_qos_native(
qos: *const dds_qos_t,
) -> Option<Vec<dds_data_representation_id_t>> {
let mut n: u32 = 0;
let mut values_ptr: *mut dds_data_representation_id_t = std::ptr::null_mut();
if dds_qget_data_representation(qos, &mut n, &mut values_ptr) {
let mut values: Vec<dds_data_representation_id_t> = Vec::with_capacity(n as usize);
for k in 0..n {
let value = *values_ptr.offset(k as isize) as dds_data_representation_id_t;
values.push(value);
}
dds_free(values_ptr as *mut ::std::os::raw::c_void);
to_option(values)
} else {
None
}
}
unsafe fn data_representation_to_qos_native(
qos: *mut dds_qos_t,
data_representation: &Option<Vec<dds_data_representation_id_t>>,
) {
if let Some(values) = data_representation {
dds_qset_data_representation(qos, values.len() as u32, values.as_ptr());
}
}
#[inline]
fn to_option<T: Default + Eq>(v: T) -> Option<T> {
if is_default_value(&v) {
None
} else {
Some(v)
}
}
#[inline]
pub(crate) fn is_default_value<T: Default + Eq>(v: &T) -> bool {
v == &T::default()
}
#[inline]
pub fn is_default<T: Default + Eq>(o: &Option<T>) -> bool {
match o {
Some(v) => is_default_value(v),
None => true,
}
}
#[inline]
fn vec_into_raw_parts<T>(v: Vec<T>) -> (*mut T, usize, usize) {
let mut me = ManuallyDrop::new(v);
(me.as_mut_ptr(), me.len(), me.capacity())
}
#[cfg(test)]
fn assert_no_policies_set(qos: &Qos) {
assert!(qos.user_data.is_none());
assert!(qos.topic_data.is_none());
assert!(qos.group_data.is_none());
assert!(qos.durability.is_none());
assert!(qos.durability_service.is_none());
assert!(qos.presentation.is_none());
assert!(qos.deadline.is_none());
assert!(qos.latency_budget.is_none());
assert!(qos.ownership.is_none());
assert!(qos.ownership_strength.is_none());
assert!(qos.liveliness.is_none());
assert!(qos.time_based_filter.is_none());
assert!(qos.partition.is_none());
assert!(qos.reliability.is_none());
assert!(qos.transport_priority.is_none());
assert!(qos.lifespan.is_none());
assert!(qos.destination_order.is_none());
assert!(qos.history.is_none());
assert!(qos.resource_limits.is_none());
assert!(qos.writer_data_lifecycle.is_none());
assert!(qos.reader_data_lifecycle.is_none());
assert!(qos.writer_batching.is_none());
assert!(qos.type_consistency.is_none());
assert!(qos.entity_name.is_none());
assert!(qos.properties.is_none());
assert!(qos.ignore_local.is_none());
assert!(qos.data_representation.is_none());
}
#[cfg(test)]
fn assert_all_policies_set(qos: &Qos) {
assert!(qos.user_data.is_some());
assert!(qos.topic_data.is_some());
assert!(qos.group_data.is_some());
assert!(qos.durability.is_some());
assert!(qos.durability_service.is_some());
assert!(qos.presentation.is_some());
assert!(qos.deadline.is_some());
assert!(qos.latency_budget.is_some());
assert!(qos.ownership.is_some());
assert!(qos.ownership_strength.is_some());
assert!(qos.liveliness.is_some());
assert!(qos.time_based_filter.is_some());
assert!(qos.partition.is_some());
assert!(qos.reliability.is_some());
assert!(qos.transport_priority.is_some());
assert!(qos.lifespan.is_some());
assert!(qos.destination_order.is_some());
assert!(qos.history.is_some());
assert!(qos.resource_limits.is_some());
assert!(qos.writer_data_lifecycle.is_some());
assert!(qos.reader_data_lifecycle.is_some());
assert!(qos.writer_batching.is_some());
assert!(qos.type_consistency.is_some());
assert!(qos.entity_name.is_some());
assert!(qos.properties.is_some());
assert!(qos.ignore_local.is_some());
assert!(qos.data_representation.is_some());
}
#[test]
fn test_default_qos_from_native() {
unsafe {
let qos_native = dds_create_qos();
let qos = Qos::from_qos_native(qos_native);
assert_no_policies_set(&qos);
dds_delete_qos(qos_native);
}
}
#[cfg(test)]
fn create_u8_vec_for_tests() -> Vec<u8> {
vec![b'a', b'b', b'c', b'd', b'e']
}
#[test]
fn test_user_data_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = Some(create_u8_vec_for_tests());
user_data_to_qos_native(qos_native, &policy);
let mut sz: usize = 0;
let mut value: *mut ::std::os::raw::c_void = std::ptr::null_mut();
assert!(dds_qget_userdata(qos_native, &mut value, &mut sz));
let output = Vec::from_raw_parts(value as *mut ::std::os::raw::c_uchar, sz, sz);
assert!(output.len() == 5);
assert_eq!(output, policy.unwrap());
dds_delete_qos(qos_native);
}
}
#[test]
fn test_user_data_from_native() {
unsafe {
let qos_native = dds_create_qos();
let test_vec = create_u8_vec_for_tests();
let ptr = test_vec.as_ptr();
dds_qset_userdata(
qos_native,
ptr as *const ::std::os::raw::c_void,
test_vec.len(),
);
let policy = user_data_from_qos_native(qos_native);
assert!(policy.is_some());
assert!(policy.unwrap() == test_vec);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_topic_data_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = Some(create_u8_vec_for_tests());
topic_data_to_qos_native(qos_native, &policy);
let mut sz: usize = 0;
let mut value: *mut ::std::os::raw::c_void = std::ptr::null_mut();
assert!(dds_qget_topicdata(qos_native, &mut value, &mut sz));
let output = Vec::from_raw_parts(value as *mut ::std::os::raw::c_uchar, sz, sz);
assert!(output.len() == 5);
assert_eq!(output, policy.unwrap());
dds_delete_qos(qos_native);
}
}
#[test]
fn test_topic_data_from_native() {
unsafe {
let qos_native = dds_create_qos();
let test_vec = create_u8_vec_for_tests();
let ptr = test_vec.as_ptr();
dds_qset_topicdata(
qos_native,
ptr as *const ::std::os::raw::c_void,
test_vec.len(),
);
let policy = topic_data_from_qos_native(qos_native);
assert!(policy.is_some());
assert!(policy.unwrap() == test_vec);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_group_data_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = Some(create_u8_vec_for_tests());
group_data_to_qos_native(qos_native, &policy);
let mut sz: usize = 0;
let mut value: *mut ::std::os::raw::c_void = std::ptr::null_mut();
assert!(dds_qget_groupdata(qos_native, &mut value, &mut sz));
let output = Vec::from_raw_parts(value as *mut ::std::os::raw::c_uchar, sz, sz);
assert!(output.len() == 5);
assert_eq!(output, policy.unwrap());
dds_delete_qos(qos_native);
}
}
#[test]
fn test_group_data_from_native() {
unsafe {
let qos_native = dds_create_qos();
let test_vec = create_u8_vec_for_tests();
let ptr = test_vec.as_ptr();
dds_qset_groupdata(
qos_native,
ptr as *const ::std::os::raw::c_void,
test_vec.len(),
);
let policy = group_data_from_qos_native(qos_native);
assert!(policy.is_some());
assert!(policy.unwrap() == test_vec);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_durability_to_native() {
unsafe {
let kinds = vec![
(
DurabilityKind::PERSISTENT,
dds_durability_kind_DDS_DURABILITY_PERSISTENT,
),
(
DurabilityKind::TRANSIENT,
dds_durability_kind_DDS_DURABILITY_TRANSIENT,
),
(
DurabilityKind::TRANSIENT_LOCAL,
dds_durability_kind_DDS_DURABILITY_TRANSIENT_LOCAL,
),
(
DurabilityKind::VOLATILE,
dds_durability_kind_DDS_DURABILITY_VOLATILE,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let policy = Some(Durability { kind: kind.0 });
durability_to_qos_native(qos_native, &policy);
let mut dur_kind: dds_durability_kind_t = dds_durability_kind_DDS_DURABILITY_VOLATILE;
assert!(dds_qget_durability(qos_native, &mut dur_kind));
assert_eq!(dur_kind, kind.1);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_durability_from_native() {
unsafe {
let kinds = vec![
(
dds_durability_kind_DDS_DURABILITY_PERSISTENT,
DurabilityKind::PERSISTENT,
),
(
dds_durability_kind_DDS_DURABILITY_TRANSIENT,
DurabilityKind::TRANSIENT,
),
(
dds_durability_kind_DDS_DURABILITY_TRANSIENT_LOCAL,
DurabilityKind::TRANSIENT_LOCAL,
),
(
dds_durability_kind_DDS_DURABILITY_VOLATILE,
DurabilityKind::VOLATILE,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
dds_qset_durability(qos_native, kind.0);
let policy = durability_from_qos_native(qos_native);
if is_default_value(&kind.1) {
assert!(policy.is_none())
} else {
assert!(policy.is_some());
assert_eq!(policy.unwrap().kind, kind.1);
}
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_durability_service_to_native() {
unsafe {
let kinds = vec![
(
HistoryKind::KEEP_LAST,
dds_history_kind_DDS_HISTORY_KEEP_LAST,
),
(HistoryKind::KEEP_ALL, dds_history_kind_DDS_HISTORY_KEEP_ALL),
];
for kind in kinds {
let qos_native = dds_create_qos();
let policy = DurabilityService {
service_cleanup_delay: 100,
history_kind: kind.0,
history_depth: 100,
max_samples: 100,
max_instances: 100,
max_samples_per_instance: 100,
};
let input = Some(policy.clone());
durability_service_to_qos_native(qos_native, &input);
let mut service_cleanup_delay: dds_duration_t = 0;
let mut durability_history_kind: dds_history_kind_t =
dds_history_kind_DDS_HISTORY_KEEP_LAST;
let mut history_depth = 1;
let mut max_samples = DDS_LENGTH_UNLIMITED;
let mut max_instances = DDS_LENGTH_UNLIMITED;
let mut max_samples_per_instance = DDS_LENGTH_UNLIMITED;
assert!(dds_qget_durability_service(
qos_native,
&mut service_cleanup_delay,
&mut durability_history_kind,
&mut history_depth,
&mut max_samples,
&mut max_instances,
&mut max_samples_per_instance,
));
assert_eq!(service_cleanup_delay, policy.service_cleanup_delay);
assert_eq!(durability_history_kind, kind.1);
assert_eq!(history_depth, policy.history_depth);
assert_eq!(max_samples, policy.max_samples);
assert_eq!(max_instances, policy.max_instances);
assert_eq!(max_samples_per_instance, policy.max_samples_per_instance);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_durability_service_from_native() {
unsafe {
let kinds = vec![
(
dds_history_kind_DDS_HISTORY_KEEP_LAST,
HistoryKind::KEEP_LAST,
),
(dds_history_kind_DDS_HISTORY_KEEP_ALL, HistoryKind::KEEP_ALL),
];
for kind in kinds {
let qos_native = dds_create_qos();
let service_cleanup_delay = 100;
let history_depth = 100;
let max_samples = 100;
let max_instances = 100;
let max_samples_per_instance = 100;
dds_qset_durability_service(
qos_native,
service_cleanup_delay,
kind.0,
history_depth,
max_samples,
max_instances,
max_samples_per_instance,
);
let policy = durability_service_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.service_cleanup_delay, service_cleanup_delay);
assert_eq!(policy.history_kind, kind.1);
assert_eq!(policy.max_samples, max_samples);
assert_eq!(policy.max_instances, max_instances);
assert_eq!(policy.max_samples_per_instance, max_samples_per_instance);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_presentation_to_native() {
unsafe {
let kinds = vec![
(
PresentationAccessScopeKind::INSTANCE,
dds_presentation_access_scope_kind_DDS_PRESENTATION_INSTANCE,
),
(
PresentationAccessScopeKind::TOPIC,
dds_presentation_access_scope_kind_DDS_PRESENTATION_TOPIC,
),
(
PresentationAccessScopeKind::GROUP,
dds_presentation_access_scope_kind_DDS_PRESENTATION_GROUP,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let policy = Presentation {
access_scope: kind.0,
coherent_access: true,
ordered_access: true,
};
let input = Some(policy.clone());
presentation_to_qos_native(qos_native, &input.clone());
let mut pres_access_scope: dds_presentation_access_scope_kind_t =
dds_presentation_access_scope_kind_DDS_PRESENTATION_INSTANCE;
let mut coherent_access: bool = false;
let mut ordered_access: bool = false;
assert!(dds_qget_presentation(
qos_native,
&mut pres_access_scope,
&mut coherent_access,
&mut ordered_access,
));
assert_eq!(pres_access_scope, kind.1);
assert_eq!(coherent_access, policy.coherent_access);
assert_eq!(ordered_access, policy.ordered_access);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_presentation_from_native() {
unsafe {
let kinds = vec![
(
dds_presentation_access_scope_kind_DDS_PRESENTATION_INSTANCE,
PresentationAccessScopeKind::INSTANCE,
),
(
dds_presentation_access_scope_kind_DDS_PRESENTATION_TOPIC,
PresentationAccessScopeKind::TOPIC,
),
(
dds_presentation_access_scope_kind_DDS_PRESENTATION_GROUP,
PresentationAccessScopeKind::GROUP,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let coherent_access = true;
let ordered_access = true;
dds_qset_presentation(qos_native, kind.0, coherent_access, ordered_access);
let policy = presentation_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.access_scope, kind.1);
assert_eq!(policy.coherent_access, coherent_access);
assert_eq!(policy.ordered_access, ordered_access);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_deadline_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = Deadline { period: 1000 };
let input = Some(policy.clone());
deadline_to_qos_native(qos_native, &input.clone());
let mut period: i64 = 0;
assert!(dds_qget_deadline(qos_native, &mut period,));
assert_eq!(period, policy.period);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_deadline_from_native() {
unsafe {
let qos_native = dds_create_qos();
let period: i64 = 1000;
dds_qset_deadline(qos_native, period);
let policy = deadline_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.period, period);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_latency_budget_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = LatencyBudget { duration: 1000 };
let input = Some(policy.clone());
latency_budget_to_qos_native(qos_native, &input.clone());
let mut duration: dds_duration_t = 0;
assert!(dds_qget_latency_budget(qos_native, &mut duration,));
assert_eq!(duration, policy.duration);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_latency_budget_from_native() {
unsafe {
let qos_native = dds_create_qos();
let duration: dds_duration_t = 1000;
dds_qset_latency_budget(qos_native, duration);
let policy = latency_budget_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.duration, duration);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_ownership_to_native() {
unsafe {
let kinds = vec![
(
OwnershipKind::SHARED,
dds_ownership_kind_DDS_OWNERSHIP_SHARED,
),
(
OwnershipKind::EXCLUSIVE,
dds_ownership_kind_DDS_OWNERSHIP_EXCLUSIVE,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let input = Some(Ownership { kind: kind.0 });
ownership_to_qos_native(qos_native, &input);
let mut own_kind: dds_durability_kind_t = dds_ownership_kind_DDS_OWNERSHIP_SHARED;
assert!(dds_qget_ownership(qos_native, &mut own_kind));
assert_eq!(own_kind, kind.1);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_ownership_from_native() {
unsafe {
let kinds = vec![
(
dds_ownership_kind_DDS_OWNERSHIP_SHARED,
OwnershipKind::SHARED,
),
(
dds_ownership_kind_DDS_OWNERSHIP_EXCLUSIVE,
OwnershipKind::EXCLUSIVE,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
dds_qset_ownership(qos_native, kind.0);
let policy = ownership_from_qos_native(qos_native);
if is_default_value(&kind.1) {
assert!(policy.is_none())
} else {
assert!(policy.is_some());
assert_eq!(policy.unwrap().kind, kind.1);
}
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_ownership_strength_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = OwnershipStrength { value: 1000 };
let input = Some(policy.clone());
ownership_strength_to_qos_native(qos_native, &input.clone());
let mut value = 0;
assert!(dds_qget_ownership_strength(qos_native, &mut value,));
assert_eq!(value, policy.value);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_ownership_strength_from_native() {
unsafe {
let qos_native = dds_create_qos();
let value = 1000;
dds_qset_ownership_strength(qos_native, value);
let policy = ownership_strength_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.value, value);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_liveliness_to_native() {
unsafe {
let kinds = vec![
(
LivelinessKind::AUTOMATIC,
dds_liveliness_kind_DDS_LIVELINESS_AUTOMATIC,
),
(
LivelinessKind::MANUAL_BY_PARTICIPANT,
dds_liveliness_kind_DDS_LIVELINESS_MANUAL_BY_PARTICIPANT,
),
(
LivelinessKind::MANUAL_BY_TOPIC,
dds_liveliness_kind_DDS_LIVELINESS_MANUAL_BY_TOPIC,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let policy = Liveliness {
kind: kind.0,
lease_duration: 1000,
};
let input = Some(policy.clone());
liveliness_to_qos_native(qos_native, &input.clone());
let mut own_kind: dds_liveliness_kind_t = dds_liveliness_kind_DDS_LIVELINESS_AUTOMATIC;
let mut lease_duration: i64 = 0;
assert!(dds_qget_liveliness(
qos_native,
&mut own_kind,
&mut lease_duration,
));
assert_eq!(own_kind, kind.1);
assert_eq!(lease_duration, policy.lease_duration);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_liveliness_from_native() {
unsafe {
let kinds = vec![
(
dds_liveliness_kind_DDS_LIVELINESS_AUTOMATIC,
LivelinessKind::AUTOMATIC,
),
(
dds_liveliness_kind_DDS_LIVELINESS_MANUAL_BY_PARTICIPANT,
LivelinessKind::MANUAL_BY_PARTICIPANT,
),
(
dds_liveliness_kind_DDS_LIVELINESS_MANUAL_BY_TOPIC,
LivelinessKind::MANUAL_BY_TOPIC,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let lease_duration: i64 = 1000;
dds_qset_liveliness(qos_native, kind.0, lease_duration);
let policy = liveliness_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.kind, kind.1);
assert_eq!(policy.lease_duration, lease_duration);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_time_based_filter_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = TimeBasedFilter {
minimum_separation: 1000,
};
let input = Some(policy.clone());
time_based_filter_to_qos_native(qos_native, &input.clone());
let mut minimum_separation = 0;
assert!(dds_qget_time_based_filter(
qos_native,
&mut minimum_separation,
));
assert_eq!(minimum_separation, policy.minimum_separation);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_time_based_filter_from_native() {
unsafe {
let qos_native = dds_create_qos();
let minimum_separation: dds_duration_t = 1000;
dds_qset_time_based_filter(qos_native, minimum_separation);
let policy = time_based_filter_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.minimum_separation, minimum_separation);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_partition_to_native() {
unsafe {
let qos_native = dds_create_qos();
let mut partitions = Vec::with_capacity(2);
partitions.push(String::from("P1"));
partitions.push(String::from("P2"));
let policy = Some(partitions.clone());
partition_to_qos_native(qos_native, &policy);
let mut n: u32 = 0;
let mut ps: *mut *mut ::std::os::raw::c_char = std::ptr::null_mut();
assert!(dds_qget_partition(qos_native, &mut n, &mut ps));
assert_eq!(n, partitions.len() as u32);
for k in 0..n {
let p_offset = *(ps.offset(k as isize));
let p = CStr::from_ptr(p_offset).to_str().unwrap();
assert_eq!(String::from(p), partitions[k as usize]);
dds_free(p_offset as *mut ::std::os::raw::c_void);
}
dds_free(ps as *mut ::std::os::raw::c_void);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_partition_from_native() {
unsafe {
let qos_native = dds_create_qos();
let mut partitions = Vec::with_capacity(2);
partitions.push(CString::new("P1").unwrap());
partitions.push(CString::new("P2").unwrap());
let mut vptr: Vec<*const c_char> = Vec::with_capacity(partitions.len());
for p in &partitions {
vptr.push(p.as_ptr());
}
let (ptr, len, cap) = vec_into_raw_parts(vptr);
dds_qset_partition(qos_native, len as u32, ptr);
drop(Vec::from_raw_parts(ptr, len, cap));
let policy = partition_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.len(), partitions.len());
for k in 0..policy.len() {
assert_eq!(partitions[k].to_str().unwrap(), policy[k]);
}
dds_delete_qos(qos_native);
}
}
#[test]
fn test_reliability_to_native() {
unsafe {
let kinds = vec![
(
ReliabilityKind::BEST_EFFORT,
dds_reliability_kind_DDS_RELIABILITY_BEST_EFFORT,
),
(
ReliabilityKind::RELIABLE,
dds_reliability_kind_DDS_RELIABILITY_RELIABLE,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let policy = Reliability {
kind: kind.0,
max_blocking_time: 1000,
};
let input = Some(policy.clone());
reliability_to_qos_native(qos_native, &input.clone());
let mut reliability_kind: dds_reliability_kind_t =
dds_reliability_kind_DDS_RELIABILITY_BEST_EFFORT;
let mut max_blocking_time: i64 = 0;
assert!(dds_qget_reliability(
qos_native,
&mut reliability_kind,
&mut max_blocking_time,
));
assert_eq!(reliability_kind, kind.1);
assert_eq!(max_blocking_time, policy.max_blocking_time);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_reliability_from_native() {
unsafe {
let kinds = vec![
(
dds_reliability_kind_DDS_RELIABILITY_BEST_EFFORT,
ReliabilityKind::BEST_EFFORT,
),
(
dds_reliability_kind_DDS_RELIABILITY_RELIABLE,
ReliabilityKind::RELIABLE,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let max_blocking_time: i64 = 1000;
dds_qset_reliability(qos_native, kind.0, max_blocking_time);
let policy = reliability_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.kind, kind.1);
assert_eq!(policy.max_blocking_time, max_blocking_time);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_transport_priority_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = TransportPriority { value: 1000 };
let input = Some(policy.clone());
transport_priority_to_qos_native(qos_native, &input.clone());
let mut value = 0;
assert!(dds_qget_transport_priority(qos_native, &mut value,));
assert_eq!(value, policy.value);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_transport_priority_from_native() {
unsafe {
let qos_native = dds_create_qos();
let value = 1000;
dds_qset_transport_priority(qos_native, value);
let policy = transport_priority_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.value, value);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_lifespan_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = Lifespan { duration: 1000 };
let input = Some(policy.clone());
lifespan_to_qos_native(qos_native, &input.clone());
let mut duration = 0;
assert!(dds_qget_lifespan(qos_native, &mut duration,));
assert_eq!(duration, policy.duration);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_lifespan_from_native() {
unsafe {
let qos_native = dds_create_qos();
let duration: dds_duration_t = 1000;
dds_qset_lifespan(qos_native, duration);
let policy = lifespan_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.duration, duration);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_destination_order_to_native() {
unsafe {
let kinds = vec![
(
DestinationOrderKind::BY_RECEPTION_TIMESTAMP,
dds_destination_order_kind_DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP,
),
(
DestinationOrderKind::BY_SOURCE_TIMESTAMP,
dds_destination_order_kind_DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let policy = DestinationOrder { kind: kind.0 };
let input = Some(policy.clone());
destination_order_to_qos_native(qos_native, &input.clone());
let mut dest_kind: dds_destination_order_kind_t =
dds_destination_order_kind_DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP;
assert!(dds_qget_destination_order(qos_native, &mut dest_kind,));
assert_eq!(dest_kind, kind.1);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_destination_order_from_native() {
unsafe {
let kinds = vec![
(
dds_destination_order_kind_DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP,
DestinationOrderKind::BY_RECEPTION_TIMESTAMP,
),
(
dds_destination_order_kind_DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP,
DestinationOrderKind::BY_SOURCE_TIMESTAMP,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
dds_qset_destination_order(qos_native, kind.0);
let policy = destination_order_from_qos_native(qos_native);
if is_default_value(&kind.1) {
assert!(policy.is_none())
} else {
assert!(policy.is_some());
assert_eq!(policy.unwrap().kind, kind.1);
}
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_history_to_native() {
unsafe {
let kinds = vec![
(
HistoryKind::KEEP_LAST,
dds_history_kind_DDS_HISTORY_KEEP_LAST,
),
(HistoryKind::KEEP_ALL, dds_history_kind_DDS_HISTORY_KEEP_ALL),
];
for kind in kinds {
let qos_native = dds_create_qos();
let policy = History {
kind: kind.0,
depth: 1000,
};
let input = Some(policy.clone());
history_to_qos_native(qos_native, &input.clone());
let mut history_kind: dds_liveliness_kind_t =
dds_liveliness_kind_DDS_LIVELINESS_AUTOMATIC;
let mut depth = 0;
assert!(dds_qget_history(qos_native, &mut history_kind, &mut depth,));
assert_eq!(history_kind, kind.1);
assert_eq!(depth, policy.depth);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_history_from_native() {
unsafe {
let kinds = vec![
(
dds_history_kind_DDS_HISTORY_KEEP_LAST,
HistoryKind::KEEP_LAST,
),
(dds_history_kind_DDS_HISTORY_KEEP_ALL, HistoryKind::KEEP_ALL),
];
for kind in kinds {
let qos_native = dds_create_qos();
let depth = 1000;
dds_qset_history(qos_native, kind.0, depth);
let policy = history_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.kind, kind.1);
assert_eq!(policy.depth, depth);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_resource_limits_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = ResourceLimits {
max_samples: 1000,
max_instances: 1000,
max_samples_per_instance: 1000,
};
let input = Some(policy.clone());
resource_limits_to_qos_native(qos_native, &input.clone());
let mut max_samples = 0;
let mut max_instances = 0;
let mut max_samples_per_instance = 0;
assert!(dds_qget_resource_limits(
qos_native,
&mut max_samples,
&mut max_instances,
&mut max_samples_per_instance,
));
assert_eq!(max_samples, policy.max_samples);
assert_eq!(max_instances, policy.max_instances);
assert_eq!(max_samples_per_instance, policy.max_samples_per_instance);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_resource_limits_from_native() {
unsafe {
let qos_native = dds_create_qos();
let max_samples = 1000;
let max_instances = 1000;
let max_samples_per_instance = 1000;
dds_qset_resource_limits(
qos_native,
max_samples,
max_instances,
max_samples_per_instance,
);
let policy = resource_limits_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.max_samples, max_samples);
assert_eq!(policy.max_instances, max_instances);
assert_eq!(policy.max_samples_per_instance, max_samples_per_instance);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_writer_data_lifecycle_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = WriterDataLifecycle {
autodispose_unregistered_instances: true,
};
let input = Some(policy.clone());
writer_data_lifecycle_to_qos_native(qos_native, &input.clone());
let mut autodispose_unregistered_instances: bool = false;
assert!(dds_qget_writer_data_lifecycle(
qos_native,
&mut autodispose_unregistered_instances,
));
assert_eq!(
autodispose_unregistered_instances,
policy.autodispose_unregistered_instances
);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_writer_data_lifecycle_from_native() {
unsafe {
let qos_native = dds_create_qos();
let autodispose_unregistered_instances = false;
dds_qset_writer_data_lifecycle(qos_native, autodispose_unregistered_instances);
let policy = writer_data_lifecycle_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(
policy.autodispose_unregistered_instances,
autodispose_unregistered_instances
);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_reader_data_lifecycle_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = ReaderDataLifecycle {
autopurge_nowriter_samples_delay: 1000,
autopurge_disposed_samples_delay: 1000,
};
let input = Some(policy.clone());
reader_data_lifecycle_to_qos_native(qos_native, &input.clone());
let mut autopurge_nowriter_samples_delay: dds_duration_t = 0;
let mut autopurge_disposed_samples_delay: dds_duration_t = 0;
assert!(dds_qget_reader_data_lifecycle(
qos_native,
&mut autopurge_nowriter_samples_delay,
&mut autopurge_disposed_samples_delay,
));
assert_eq!(
autopurge_nowriter_samples_delay,
policy.autopurge_nowriter_samples_delay
);
assert_eq!(
autopurge_disposed_samples_delay,
policy.autopurge_disposed_samples_delay
);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_reader_data_lifecycle_from_native() {
unsafe {
let qos_native = dds_create_qos();
let autopurge_nowriter_samples_delay: dds_duration_t = 1000;
let autopurge_disposed_samples_delay: dds_duration_t = 1000;
dds_qset_reader_data_lifecycle(
qos_native,
autopurge_nowriter_samples_delay,
autopurge_disposed_samples_delay,
);
let policy = reader_data_lifecycle_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(
policy.autopurge_nowriter_samples_delay,
autopurge_nowriter_samples_delay
);
assert_eq!(
policy.autopurge_disposed_samples_delay,
autopurge_disposed_samples_delay
);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_writer_batching_to_native() {
unsafe {
let qos_native = dds_create_qos();
let policy = WriterBatching {
batch_updates: true,
};
let input = Some(policy.clone());
writer_batching_to_qos_native(qos_native, &input.clone());
let mut batch_updates: bool = false;
assert!(dds_qget_writer_batching(qos_native, &mut batch_updates,));
assert_eq!(batch_updates, policy.batch_updates);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_writer_batching_from_native() {
unsafe {
let qos_native = dds_create_qos();
let batch_updates = true;
dds_qset_writer_batching(qos_native, batch_updates);
let policy = writer_batching_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.batch_updates, batch_updates);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_type_consistency_to_native() {
unsafe {
let kinds = vec![
(
TypeConsistencyKind::DISALLOW_TYPE_COERCION,
dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_DISALLOW_TYPE_COERCION,
),
(
TypeConsistencyKind::ALLOW_TYPE_COERCION,
dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_ALLOW_TYPE_COERCION,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let policy = TypeConsistency {
kind: kind.0,
ignore_sequence_bounds: true,
ignore_string_bounds: true,
ignore_member_names: true,
prevent_type_widening: true,
force_type_validation: true,
};
let input = Some(policy.clone());
type_consistency_to_qos_native(qos_native, &input.clone());
let mut type_kind: dds_type_consistency_kind_t =
dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_DISALLOW_TYPE_COERCION;
let mut ignore_sequence_bounds = false;
let mut ignore_string_bounds = false;
let mut ignore_member_names = false;
let mut prevent_type_widening = false;
let mut force_type_validation = false;
assert!(dds_qget_type_consistency(
qos_native,
&mut type_kind,
&mut ignore_sequence_bounds,
&mut ignore_string_bounds,
&mut ignore_member_names,
&mut prevent_type_widening,
&mut force_type_validation,
));
assert_eq!(type_kind, kind.1);
assert_eq!(ignore_sequence_bounds, policy.ignore_sequence_bounds);
assert_eq!(ignore_string_bounds, policy.ignore_string_bounds);
assert_eq!(ignore_member_names, policy.ignore_member_names);
assert_eq!(prevent_type_widening, policy.prevent_type_widening);
assert_eq!(force_type_validation, policy.force_type_validation);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_type_consistency_from_native() {
unsafe {
let kinds = vec![
(
dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_DISALLOW_TYPE_COERCION,
TypeConsistencyKind::DISALLOW_TYPE_COERCION,
),
(
dds_type_consistency_kind_DDS_TYPE_CONSISTENCY_ALLOW_TYPE_COERCION,
TypeConsistencyKind::ALLOW_TYPE_COERCION,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let ignore_sequence_bounds = true;
let ignore_string_bounds = true;
let ignore_member_names = true;
let prevent_type_widening = true;
let force_type_validation = true;
dds_qset_type_consistency(
qos_native,
kind.0,
ignore_sequence_bounds,
ignore_string_bounds,
ignore_member_names,
prevent_type_widening,
force_type_validation,
);
let policy = type_consistency_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.kind, kind.1);
assert_eq!(policy.ignore_sequence_bounds, ignore_sequence_bounds);
assert_eq!(policy.ignore_string_bounds, ignore_string_bounds);
assert_eq!(policy.ignore_member_names, ignore_member_names);
assert_eq!(policy.prevent_type_widening, prevent_type_widening);
assert_eq!(policy.force_type_validation, force_type_validation);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_entity_name_to_native() {
unsafe {
let qos_native = dds_create_qos();
let name = Some(EntityName {
name: String::from("TEST_ENTITY_NAME"),
});
entity_name_to_qos_native(qos_native, &name);
let mut ps: *mut ::std::os::raw::c_char = std::ptr::null_mut();
assert!(dds_qget_entity_name(qos_native, &mut ps));
let p = CStr::from_ptr(ps).to_str().unwrap();
assert_eq!(p, name.unwrap().name);
dds_free(ps as *mut ::std::os::raw::c_void);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_entity_name_from_native() {
unsafe {
let qos_native = dds_create_qos();
let name = CString::new("TEST_ENTITY_NAME").unwrap();
dds_qset_entity_name(qos_native, name.as_ptr());
let policy = entity_name_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(name.to_str().unwrap(), policy.name);
dds_delete_qos(qos_native);
}
}
#[cfg(test)]
unsafe fn assert_property_is_set(qos: *const dds_qos, prop_name: &String, expected_value: &String) {
let mut pvalue: *mut ::std::os::raw::c_char = std::ptr::null_mut();
let cname = CString::new(prop_name.as_str()).unwrap();
assert!(dds_qget_prop(qos, cname.as_ptr(), &mut pvalue));
let value = CStr::from_ptr(pvalue).to_str().unwrap();
assert_eq!(value, expected_value);
dds_free(pvalue as *mut ::std::os::raw::c_void);
}
#[test]
fn test_properties_to_native() {
unsafe {
let qos_native = dds_create_qos();
let mut properties = HashMap::new();
properties.insert(String::from("PROP_1"), String::from("VALUE_1"));
properties.insert(String::from("PROP_2"), String::from("VALUE_2"));
properties.insert(String::from("PROP_3"), String::from("VALUE_3"));
let policy = Some(properties.clone());
properties_to_qos_native(qos_native, &policy);
let mut n: u32 = 0;
let mut ps: *mut *mut ::std::os::raw::c_char = std::ptr::null_mut();
assert!(dds_qget_propnames(qos_native, &mut n, &mut ps));
assert_eq!(n, properties.len() as u32);
for k in 0..n {
let p_offset = *(ps.offset(k as isize));
let p = CStr::from_ptr(p_offset).to_str().unwrap();
let name = String::from(p);
dds_free(p_offset as *mut ::std::os::raw::c_void);
let value = properties.get(&name);
assert!(value.is_some());
assert_property_is_set(qos_native, &name, value.unwrap());
}
dds_delete_qos(qos_native);
}
}
#[test]
fn test_properties_from_native() {
unsafe {
let qos_native = dds_create_qos();
let mut properties = HashMap::new();
properties.insert(String::from("PROP_1"), String::from("VALUE_1"));
properties.insert(String::from("PROP_2"), String::from("VALUE_2"));
properties.insert(String::from("PROP_3"), String::from("VALUE_3"));
for (name, value) in &properties {
let cname = CString::new(name.as_str()).unwrap();
let cvalue = CString::new(value.as_str()).unwrap();
dds_qset_prop(qos_native, cname.as_ptr(), cvalue.as_ptr());
}
let policy = properties_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.len(), properties.len());
for (name, value) in properties {
let prop_value = policy.get(&name);
assert!(prop_value.is_some());
assert_eq!(prop_value.unwrap(), &value);
}
dds_delete_qos(qos_native);
}
}
#[test]
fn test_ignore_local_to_native() {
unsafe {
let kinds = vec![
(
IgnoreLocalKind::NONE,
dds_ignorelocal_kind_DDS_IGNORELOCAL_NONE,
),
(
IgnoreLocalKind::PARTICIPANT,
dds_ignorelocal_kind_DDS_IGNORELOCAL_PARTICIPANT,
),
(
IgnoreLocalKind::PROCESS,
dds_ignorelocal_kind_DDS_IGNORELOCAL_PROCESS,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
let policy = IgnoreLocal { kind: kind.0 };
let input = Some(policy.clone());
ignore_local_to_qos_native(qos_native, &input.clone());
let mut ignore_kind: dds_ignorelocal_kind_t = dds_ignorelocal_kind_DDS_IGNORELOCAL_NONE;
assert!(dds_qget_ignorelocal(qos_native, &mut ignore_kind,));
assert_eq!(ignore_kind, kind.1);
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_ignore_local_from_native() {
unsafe {
let kinds = vec![
(
dds_ignorelocal_kind_DDS_IGNORELOCAL_NONE,
IgnoreLocalKind::NONE,
),
(
dds_ignorelocal_kind_DDS_IGNORELOCAL_PARTICIPANT,
IgnoreLocalKind::PARTICIPANT,
),
(
dds_ignorelocal_kind_DDS_IGNORELOCAL_PROCESS,
IgnoreLocalKind::PROCESS,
),
];
for kind in kinds {
let qos_native = dds_create_qos();
dds_qset_ignorelocal(qos_native, kind.0);
let policy = ignore_local_from_qos_native(qos_native);
if is_default_value(&kind.1) {
assert!(policy.is_none())
} else {
assert!(policy.is_some());
assert_eq!(policy.unwrap().kind, kind.1);
}
dds_delete_qos(qos_native);
}
}
}
#[test]
fn test_data_representation_to_native() {
unsafe {
let qos_native = dds_create_qos();
let values: Vec<dds_data_representation_id_t> = vec![
DDS_DATA_REPRESENTATION_XCDR1 as dds_data_representation_id_t,
DDS_DATA_REPRESENTATION_XCDR2 as dds_data_representation_id_t,
];
let data_representation: Option<Vec<dds_data_representation_id_t>> = Some(values.clone());
data_representation_to_qos_native(qos_native, &data_representation);
let mut n: u32 = 0;
let mut values_ptr: *mut dds_data_representation_id_t = std::ptr::null_mut();
assert!(dds_qget_data_representation(
qos_native,
&mut n,
&mut values_ptr
));
assert_eq!(n, values.len() as u32);
for k in 0..n {
let value = *values_ptr.offset(k as isize) as dds_data_representation_id_t;
assert_eq!(values[k as usize], value);
}
dds_free(values_ptr as *mut ::std::os::raw::c_void);
dds_delete_qos(qos_native);
}
}
#[test]
fn test_data_representation_from_native() {
unsafe {
let qos_native = dds_create_qos();
let values: Vec<dds_data_representation_id_t> = vec![
DDS_DATA_REPRESENTATION_XCDR1 as dds_data_representation_id_t,
DDS_DATA_REPRESENTATION_XCDR2 as dds_data_representation_id_t,
];
dds_qset_data_representation(qos_native, values.len() as u32, values.as_ptr());
let policy = data_representation_from_qos_native(qos_native);
assert!(policy.is_some());
let policy = policy.unwrap();
assert_eq!(policy.len(), values.len());
for k in 0..policy.len() {
assert_eq!(values[k], policy[k]);
}
dds_delete_qos(qos_native);
}
}
#[test]
fn test_default_qos_serialization() {
unsafe {
let qos_native = dds_create_qos();
let qos = Qos::from_qos_native(qos_native);
dds_delete_qos(qos_native);
let json = serde_json::to_string(&qos).unwrap();
println!("{json}");
let qos2 = serde_json::from_str::<Qos>(&json).unwrap();
assert!(qos == qos2);
assert_no_policies_set(&qos2);
let bincode = bincode::serialize(&qos).unwrap();
println!("len={} : {:x?}", bincode.len(), &bincode);
let qos3 = bincode::deserialize::<Qos>(&bincode).unwrap();
assert!(qos == qos3);
assert_no_policies_set(&qos3);
}
}
#[test]
fn test_fully_populated_qos_serialization() {
unsafe {
let qos_native = dds_create_qos();
let user_data = Some(create_u8_vec_for_tests());
user_data_to_qos_native(qos_native, &user_data);
let topic_data = Some(create_u8_vec_for_tests());
topic_data_to_qos_native(qos_native, &topic_data);
let group_data = Some(create_u8_vec_for_tests());
group_data_to_qos_native(qos_native, &group_data);
let durability = Some(Durability {
kind: DurabilityKind::TRANSIENT_LOCAL,
});
durability_to_qos_native(qos_native, &durability);
let durability_service = Some(DurabilityService {
history_kind: HistoryKind::KEEP_ALL,
..Default::default()
});
durability_service_to_qos_native(qos_native, &durability_service);
let presentation = Some(Presentation {
access_scope: PresentationAccessScopeKind::TOPIC,
..Default::default()
});
presentation_to_qos_native(qos_native, &presentation);
let deadline = Some(Deadline { period: 15 });
deadline_to_qos_native(qos_native, &deadline);
let latency_budget = Some(LatencyBudget { duration: 42 });
latency_budget_to_qos_native(qos_native, &latency_budget);
let ownership = Some(Ownership {
kind: OwnershipKind::EXCLUSIVE,
});
ownership_to_qos_native(qos_native, &ownership);
let ownership_strength = Some(OwnershipStrength { value: 12 });
ownership_strength_to_qos_native(qos_native, &ownership_strength);
let liveliness = Some(Liveliness {
kind: LivelinessKind::MANUAL_BY_PARTICIPANT,
lease_duration: 3,
});
liveliness_to_qos_native(qos_native, &liveliness);
let time_based_filter = Some(TimeBasedFilter {
minimum_separation: 56,
});
time_based_filter_to_qos_native(qos_native, &time_based_filter);
let mut partitions = Vec::with_capacity(2);
partitions.push(String::from("P1"));
partitions.push(String::from("P2"));
let parititons = Some(partitions);
partition_to_qos_native(qos_native, &parititons);
let reliability = Some(Reliability {
kind: ReliabilityKind::RELIABLE,
max_blocking_time: 500,
});
reliability_to_qos_native(qos_native, &reliability);
let transport_priority = Some(TransportPriority { value: 3 });
transport_priority_to_qos_native(qos_native, &transport_priority);
let lifespan = Some(Lifespan { duration: 10 });
lifespan_to_qos_native(qos_native, &lifespan);
let destination_order = Some(DestinationOrder {
kind: DestinationOrderKind::BY_SOURCE_TIMESTAMP,
});
destination_order_to_qos_native(qos_native, &destination_order);
let history = Some(History {
kind: HistoryKind::KEEP_LAST,
depth: 10,
});
history_to_qos_native(qos_native, &history);
let resource_limits = Some(ResourceLimits {
max_samples: 100,
..Default::default()
});
resource_limits_to_qos_native(qos_native, &resource_limits);
let writer_data_lifecycle = Some(WriterDataLifecycle {
autodispose_unregistered_instances: false,
});
writer_data_lifecycle_to_qos_native(qos_native, &writer_data_lifecycle);
let reader_data_lifecycle = Some(ReaderDataLifecycle {
autopurge_disposed_samples_delay: 30,
..Default::default()
});
reader_data_lifecycle_to_qos_native(qos_native, &reader_data_lifecycle);
let writer_batching = Some(WriterBatching {
batch_updates: true,
});
writer_batching_to_qos_native(qos_native, &writer_batching);
let type_consistency = Some(TypeConsistency {
kind: TypeConsistencyKind::ALLOW_TYPE_COERCION,
..Default::default()
});
type_consistency_to_qos_native(qos_native, &type_consistency);
let entity_name = Some(EntityName {
name: String::from("TEST_ENTITY_NAME"),
});
entity_name_to_qos_native(qos_native, &entity_name);
let mut properties = HashMap::new();
properties.insert(String::from("PROP_1"), String::from("VALUE_1"));
properties.insert(String::from("PROP_2"), String::from("VALUE_2"));
properties.insert(String::from("PROP_3"), String::from("VALUE_3"));
let properties = Some(properties);
properties_to_qos_native(qos_native, &properties);
let ignore_local = Some(IgnoreLocal {
kind: IgnoreLocalKind::PARTICIPANT,
});
ignore_local_to_qos_native(qos_native, &ignore_local);
let data_representation: Option<Vec<dds_data_representation_id_t>> = Some(vec![
DDS_DATA_REPRESENTATION_XCDR1 as dds_data_representation_id_t,
DDS_DATA_REPRESENTATION_XCDR2 as dds_data_representation_id_t,
]);
data_representation_to_qos_native(qos_native, &data_representation);
let qos = Qos::from_qos_native(qos_native);
dds_delete_qos(qos_native);
let json = serde_json::to_string(&qos).unwrap();
println!("{json}");
let qos2 = serde_json::from_str::<Qos>(&json).unwrap();
assert!(qos == qos2);
assert_all_policies_set(&qos2);
let bincode = bincode::serialize(&qos).unwrap();
println!("len={} : {:x?}", bincode.len(), &bincode);
let qos3 = bincode::deserialize::<Qos>(&bincode).unwrap();
assert!(qos == qos3);
assert_all_policies_set(&qos3);
}
}