iceoryx2
C++ Bindings
Loading...
Searching...
No Matches
response_mut.hpp
Go to the documentation of this file.
1// Copyright (c) 2025 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_RESPONSE_MUT_HPP
14#define IOX2_RESPONSE_MUT_HPP
15
16#include "iox2/bb/expected.hpp"
17#include "iox2/bb/slice.hpp"
18#include "iox2/deployment/iceoryx2_cxx_feature_flags.hpp"
20#include "iox2/marker.hpp"
21#include "iox2/payload_info.hpp"
22#include "iox2/port_error.hpp"
23#include "iox2/service_type.hpp"
24
25#if IOX2_FEATURE_FLATBUFFERS
26#include <flatbuffers/flatbuffers.h>
27#endif // IOX2_FEATURE_FLATBUFFERS
28
29#include <type_traits>
30
31namespace iox2 {
32
41template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
42// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) 'm_response' is not used directly but only via the initialized 'm_handle'; furthermore, it will be initialized on the call site
44 using ValueType = typename PayloadInfo<ResponsePayload>::ValueType;
45
46 public:
47 ResponseMut(ResponseMut&& rhs) noexcept;
48 auto operator=(ResponseMut&& rhs) noexcept -> ResponseMut&;
49 ~ResponseMut() noexcept;
50
51 ResponseMut(const ResponseMut&) = delete;
52 auto operator=(const ResponseMut&) -> ResponseMut& = delete;
53
55 auto header() const -> ResponseHeader;
56
58 template <typename T = ResponseUserHeader,
59 typename = std::enable_if_t<!std::is_same<void, ResponseUserHeader>::value, T>>
60 auto user_header() const -> const T&;
61
63 template <typename T = ResponseUserHeader,
64 typename = std::enable_if_t<!std::is_same<void, ResponseUserHeader>::value, T>>
65 auto user_header_mut() -> T&;
66
68 template <typename T = ResponsePayload,
69 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
70 auto payload() const -> const ResponsePayload&;
71
73 template <typename T = ResponsePayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
74 auto payload() const -> bb::ImmutableSlice<ValueType>;
75
77 template <typename T = ResponsePayload,
78 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
79 auto payload_mut() -> ResponsePayload&;
80
82 template <typename T = ResponsePayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
83 auto payload_mut() -> bb::MutableSlice<ValueType>;
84
85#if IOX2_FEATURE_FLATBUFFERS
87 template <typename T = ResponsePayload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
88 auto payload_bytes() const -> bb::ImmutableSlice<uint8_t>;
89
91 template <typename T = ResponsePayload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
92 auto payload_root() const -> const typename T::ValueType*;
93#endif // IOX2_FEATURE_FLATBUFFERS
94
95 private:
96 template <ServiceType, typename, typename>
97 friend class ResponseMutUninit;
98 template <ServiceType, typename, typename, typename, typename>
99 friend class ActiveRequest;
100
103 template <ServiceType S, typename ResponsePayloadT, typename ResponseUserHeaderT>
105
106 explicit ResponseMut() = default;
107 void drop();
108
109 iox2_response_mut_t m_response;
110 iox2_response_mut_h m_handle = nullptr;
111};
112
113// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) m_response will be initialized in the move assignment operator
114template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
116 *this = std::move(rhs);
117}
118
119namespace internal {
120extern "C" {
121void iox2_response_mut_move(iox2_response_mut_t*, iox2_response_mut_t*, iox2_response_mut_h*);
122}
123} // namespace internal
124
125template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
127 -> ResponseMut& {
128 if (this != &rhs) {
129 drop();
130
131 internal::iox2_response_mut_move(&rhs.m_response, &m_response, &m_handle);
132 rhs.m_handle = nullptr;
133 }
134
135 return *this;
136}
137
138template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
142
143#if IOX2_FEATURE_FLATBUFFERS
144template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
145template <typename T, typename>
147 -> bb::ImmutableSlice<uint8_t> {
148 const void* ptr = nullptr;
149 size_t number_of_elements = 0;
150
151 iox2_response_mut_payload(&m_handle, &ptr, &number_of_elements);
152 auto payload_offset = header().payload_offset();
153 auto payload_len = header().number_of_elements();
154
155 return bb::ImmutableSlice<uint8_t>(static_cast<const uint8_t*>(ptr) + payload_offset, payload_len - payload_offset);
156}
157
158template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
159template <typename T, typename>
161 typename T::ValueType* {
162 return flatbuffers::GetRoot<typename T::ValueType>(payload_bytes().data());
163}
164#endif // IOX2_FEATURE_FLATBUFFERS
165
166template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
168 iox2_response_header_h header_handle = nullptr;
169 iox2_response_mut_header(&m_handle, nullptr, &header_handle);
170 return ResponseHeader { header_handle };
171}
172
173template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
174template <typename T, typename>
176 const void* ptr = nullptr;
177 iox2_response_mut_user_header(&m_handle, &ptr);
178 return *static_cast<const T*>(ptr);
179}
180
181template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
182template <typename T, typename>
184 void* ptr = nullptr;
185 iox2_response_mut_user_header_mut(&m_handle, &ptr);
186 return *static_cast<T*>(ptr);
187}
188
189template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
190template <typename T, typename>
191inline auto ResponseMut<Service, ResponsePayload, ResponseUserHeader>::payload() const -> const ResponsePayload& {
192 const void* ptr = nullptr;
193 iox2_response_mut_payload(&m_handle, &ptr, nullptr);
194 return *static_cast<const T*>(ptr);
195}
196
197template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
198template <typename T, typename>
200 -> bb::ImmutableSlice<ValueType> {
201 const void* ptr = nullptr;
202 size_t number_of_elements = 0;
203 iox2_response_mut_payload(&m_handle, &ptr, &number_of_elements);
204
205 // for the custom payload marker, the slice length is the
206 // runtime payload byte size
207 auto length = number_of_elements;
208 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
209 length = iox2_response_mut_payload_number_of_bytes(&m_handle);
210 }
211
212 return bb::ImmutableSlice<ValueType>(static_cast<const ValueType*>(ptr), length);
213}
214
215template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
216template <typename T, typename>
218 void* ptr = nullptr;
219 iox2_response_mut_payload_mut(&m_handle, &ptr, nullptr);
220 return *static_cast<ResponsePayload*>(ptr);
221}
222
223template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
224template <typename T, typename>
226 void* ptr = nullptr;
227 size_t number_of_elements = 0;
228 iox2_response_mut_payload_mut(&m_handle, &ptr, &number_of_elements);
229
230 // for the custom payload marker, the slice length is the
231 // runtime payload byte size
232 auto length = number_of_elements;
233 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
234 length = iox2_response_mut_payload_number_of_bytes(&m_handle);
235 }
236
237 return bb::MutableSlice<ValueType>(static_cast<ValueType*>(ptr), length);
238}
239
240
241template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
244 auto result = iox2_response_mut_send(response.m_handle);
245 response.m_handle = nullptr;
246
247 if (result == IOX2_OK) {
248 return {};
249 }
250 return bb::err(bb::into<SendError>(result));
251}
252
253template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
254inline void ResponseMut<Service, ResponsePayload, ResponseUserHeader>::drop() {
255 if (m_handle != nullptr) {
256 iox2_response_mut_drop(m_handle);
257 m_handle = nullptr;
258 }
259}
260
261} // namespace iox2
262
263#endif
Response header used by [MessagingPattern::RequestResponse].
auto payload_root() const -> const typename T::ValueType *
Returns the root of the flatbuffer.
friend auto send(ResponseMut< S, ResponsePayloadT, ResponseUserHeaderT > &&response) -> bb::Expected< void, SendError >
auto header() const -> ResponseHeader
Returns a reference to the [ResponseHeader].
auto payload_bytes() const -> bb::ImmutableSlice< uint8_t >
Returns the serialized flatbuffer data as bytes.
auto user_header() const -> const T &
Returns a reference to the user header of the response.
auto user_header_mut() -> T &
Returns a mutable reference to the user header of the response.
auto operator=(ResponseMut &&rhs) noexcept -> ResponseMut &
~ResponseMut() noexcept
auto payload_mut() -> ResponsePayload &
Returns a mutable reference to the payload of the response.
ResponseMut(const ResponseMut &)=delete
auto operator=(const ResponseMut &) -> ResponseMut &=delete
auto payload() const -> const ResponsePayload &
Returns a reference to the payload of the response.
A class representing a slice of contiguous elements of type T.
Definition slice.hpp:31
constexpr auto err(const E &error) -> Unexpected< E >
Definition expected.hpp:33
iox2::bb::variation::Expected< T, E > Expected
Definition expected.hpp:22
constexpr auto has_flatbuffer_marker() -> bool
Definition marker.hpp:53
auto send(RequestMut< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader > &&request) -> bb::Expected< PendingResponse< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >, RequestSendError >