iceoryx2
C++ Language Bindings
Loading...
Searching...
No Matches
sample.hpp
Go to the documentation of this file.
1// Copyright (c) 2024 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13#ifndef IOX2_SAMPLE_HPP
14#define IOX2_SAMPLE_HPP
15
16#include "iox2/bb/slice.hpp"
18#include "iox2/iceoryx2_cxx_deployment.hpp"
20#include "iox2/marker.hpp"
21#include "iox2/payload_info.hpp"
22#include "iox2/service_type.hpp"
24
25#include <type_traits>
26
27#if IOX2_FEATURE_FLATBUFFERS
28#include <cstdint>
29#include <flatbuffers/flatbuffers.h>
30#endif
31
32namespace iox2 {
33
45template <ServiceType, typename Payload, typename UserHeader>
46// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) 'm_sample' is not used directly but only via the initialized 'm_handle'; furthermore, it will be initialized on the call site
47class Sample {
48 using ValueType = typename PayloadInfo<Payload>::ValueType;
49
50 public:
51 Sample(Sample&& rhs) noexcept;
52 auto operator=(Sample&& rhs) noexcept -> Sample&;
53 ~Sample();
54
55 Sample(const Sample&) = delete;
56 auto operator=(const Sample&) -> Sample& = delete;
57
59 template <typename T = Payload,
60 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
61 auto payload() const -> const ValueType&;
62
64 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
65 auto payload() const -> bb::ImmutableSlice<ValueType>;
66
67#if IOX2_FEATURE_FLATBUFFERS
69 template <typename T = Payload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
70 auto payload_bytes() const -> bb::ImmutableSlice<uint8_t>;
71
73 template <typename T = Payload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
74 auto payload_root() const -> const typename T::ValueType*;
75#endif // IOX2_FEATURE_FLATBUFFERS
76
78 template <typename T = UserHeader, typename = std::enable_if_t<!std::is_same<void, UserHeader>::value, T>>
79 auto user_header() const -> const T&;
80
82 auto header() const -> HeaderPublishSubscribe;
83
85 auto origin() const -> UniquePublisherId;
86
87 private:
88 template <ServiceType, typename, typename>
89 friend class Subscriber;
90
91 // The sample is defaulted since both members are initialized in Subscriber::receive
92 explicit Sample() = default;
93 void drop();
94
95 iox2_sample_t m_sample;
96 iox2_sample_h m_handle = nullptr;
97};
98
99template <ServiceType S, typename Payload, typename UserHeader>
100inline void Sample<S, Payload, UserHeader>::drop() {
101 if (m_handle != nullptr) {
102 iox2_sample_drop(m_handle);
103 m_handle = nullptr;
104 }
105}
106
107// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) m_sample will be initialized in the move assignment operator
108template <ServiceType S, typename Payload, typename UserHeader>
110 *this = std::move(rhs);
111}
112
113namespace internal {
114extern "C" {
115void iox2_sample_move(iox2_sample_t*, iox2_sample_t*, iox2_sample_h*);
116}
117} // namespace internal
118
119template <ServiceType S, typename Payload, typename UserHeader>
121 if (this != &rhs) {
122 drop();
123
124 internal::iox2_sample_move(&rhs.m_sample, &m_sample, &m_handle);
125 rhs.m_handle = nullptr;
126 }
127
128 return *this;
129}
130
131template <ServiceType S, typename Payload, typename UserHeader>
133 drop();
134}
135
136template <ServiceType S, typename Payload, typename UserHeader>
137template <typename T, typename>
138inline auto Sample<S, Payload, UserHeader>::payload() const -> const ValueType& {
139 const void* ptr = nullptr;
140
141 iox2_sample_payload(&m_handle, &ptr, nullptr);
142
143 return *static_cast<const ValueType*>(ptr);
144}
145
146template <ServiceType S, typename Payload, typename UserHeader>
147template <typename T, typename>
148inline auto Sample<S, Payload, UserHeader>::payload() const -> bb::ImmutableSlice<ValueType> {
149 const void* ptr = nullptr;
150 size_t number_of_elements = 0;
151
152 iox2_sample_payload(&m_handle, &ptr, &number_of_elements);
153
154 // for the custom payload marker, the slice length is the
155 // runtime payload byte size
156 auto length = number_of_elements;
157 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
158 length = iox2_sample_payload_number_of_bytes(&m_handle);
159 }
160
161 return bb::ImmutableSlice<ValueType>(static_cast<const ValueType*>(ptr), length);
162}
163
164#if IOX2_FEATURE_FLATBUFFERS
165
166template <ServiceType S, typename Payload, typename UserHeader>
167template <typename T, typename>
168inline auto Sample<S, Payload, UserHeader>::payload_bytes() const -> bb::ImmutableSlice<uint8_t> {
169 const void* ptr = nullptr;
170 size_t number_of_elements = 0;
171
172 iox2_sample_payload(&m_handle, &ptr, &number_of_elements);
173 auto payload_offset = header().payload_offset();
174 auto payload_len = header().number_of_elements();
175
176 return bb::ImmutableSlice<uint8_t>(static_cast<const uint8_t*>(ptr) + payload_offset, payload_len - payload_offset);
177}
178
179template <ServiceType S, typename Payload, typename UserHeader>
180template <typename T, typename>
181auto Sample<S, Payload, UserHeader>::payload_root() const -> const typename T::ValueType* {
182 return flatbuffers::GetRoot<typename T::ValueType>(payload_bytes().data());
183}
184
185#endif // IOX2_FEATURE_FLATBUFFERS
186
187template <ServiceType S, typename Payload, typename UserHeader>
188template <typename T, typename>
189inline auto Sample<S, Payload, UserHeader>::user_header() const -> const T& {
190 const void* header_ptr = nullptr;
191
192 iox2_sample_user_header(&m_handle, &header_ptr);
193
194 return *static_cast<const T*>(header_ptr);
195}
196
197template <ServiceType S, typename Payload, typename UserHeader>
199 iox2_publish_subscribe_header_h header_handle = nullptr;
200 iox2_sample_header(&m_handle, nullptr, &header_handle);
201
202 return HeaderPublishSubscribe { header_handle };
203}
204
205template <ServiceType S, typename Payload, typename UserHeader>
207 return header().publisher_id();
208}
209
210} // namespace iox2
211
212#endif
Sample header used by [MessagingPattern::PublishSubscribe].
auto header() const -> HeaderPublishSubscribe
Returns a reference to the [Header] of the [Sample].
Definition sample.hpp:198
auto payload() const -> const ValueType &
Returns a reference to the payload of the [Sample].
Definition sample.hpp:138
auto origin() const -> UniquePublisherId
Returns the [UniquePublisherId] of the [Publisher](crate::port::publisher::Publisher)
Definition sample.hpp:206
auto operator=(Sample &&rhs) noexcept -> Sample &
Definition sample.hpp:120
auto user_header() const -> const T &
Returns a reference to the user_header of the [Sample].
Definition sample.hpp:189
Sample(const Sample &)=delete
auto operator=(const Sample &) -> Sample &=delete
The receiving endpoint of a publish-subscribe communication.
The system-wide unique id of a [Publisher].
constexpr auto has_flatbuffer_marker() -> bool
Definition marker.hpp:49