11#ifndef RTI_ROUTING_ADAPTER_DETAIL_STREAM_READER_FORWARDER_HPP_
12#define RTI_ROUTING_ADAPTER_DETAIL_STREAM_READER_FORWARDER_HPP_
16#include <rti/core/Exception.hpp>
18#include <rti/apputils/ServiceException.hpp>
20#include <rti/routing/adapter/StreamReader.hpp>
21#include <rti/routing/StreamInfo.hpp>
22#include <rti/routing/detail/UpdatableEntityForwarder.hpp>
23#include <rti/routing/detail/ForwarderUtils.hpp>
24#include <rti/routing/adapter/detail/DiscoveryStreamReaderForwarder.hpp>
27namespace rti {
namespace routing {
namespace adapter {
namespace detail {
29template <
bool ReadOrTake,
bool HasSelector>
struct read_or_take;
33struct read_or_take<false, false> {
37 std::vector<StreamReader::SamplePtr>& sample_seq,
38 std::vector<StreamReader::InfoPtr>& info_seq,
39 const struct RTI_RoutingServiceSelectorState *)
41 stream_reader.
take(sample_seq, info_seq);
46struct read_or_take<true, false> {
50 std::vector<StreamReader::SamplePtr>& sample_seq,
51 std::vector<StreamReader::InfoPtr>& info_seq,
52 const struct RTI_RoutingServiceSelectorState *)
54 stream_reader.
read(sample_seq, info_seq);
59struct read_or_take<false, true> {
63 std::vector<StreamReader::SamplePtr>& sample_seq,
64 std::vector<StreamReader::InfoPtr>& info_seq,
65 const struct RTI_RoutingServiceSelectorState *native_selector)
70 SelectorState(*native_selector));
76struct read_or_take<true, true> {
80 std::vector<StreamReader::SamplePtr>& sample_seq,
81 std::vector<StreamReader::InfoPtr>& info_seq,
82 const struct RTI_RoutingServiceSelectorState *native_selector)
87 SelectorState(*native_selector));
99 std::vector<StreamReader::SamplePtr> sample_seq_;
100 std::vector<StreamReader::InfoPtr> info_seq_;
103class StreamReaderForwarder {
105 static RTI_RoutingServiceStreamReaderExt* create_native(
106 Connection *connection,
108 const struct RTI_RoutingServiceStreamInfo *native_stream_info,
109 const struct RTI_RoutingServiceProperties *native_properties,
110 const struct RTI_RoutingServiceStreamReaderListenerExt *native_listener,
111 RTI_RoutingServiceEnvironment *environment)
115 using rti::routing::detail::ScopedForwarder;
117 StreamInfo stream_info(*native_stream_info);
119 std::map<std::string, std::string> properties;
120 rti::routing::PropertyAdapter::add_properties_from_native(
124 StreamReaderForwarder *forwarder =
new StreamReaderForwarder(
126 ScopedForwarder<Connection, StreamReaderForwarder> scoped(
130 forwarder->stream_reader_ = connection->create_stream_reader(
134 &forwarder->listener_);
135 RTI_ROUTING_THROW_ON_NULL(forwarder->stream_reader_);
144 return forwarder->native();
145 }
catch(
const rti::apputils::FatalServiceException& ex) {
146 RTI_RoutingServiceEnvironment_fatal_error(
150 }
catch(
const std::exception& ex) {
151 RTI_RoutingServiceEnvironment_set_error(
156 RTI_RoutingServiceEnvironment_set_error(
158 "unexpected exception");
165 static void delete_native(
166 Connection *connection,
167 RTI_RoutingServiceStreamReaderExt *native_stream_reader,
168 RTI_RoutingServiceEnvironment *environment)
170 StreamReaderForwarder *stream_reader_forwarder =
171 from_native(native_stream_reader);
173 if (stream_reader_forwarder->stream_reader_ != NULL) {
174 connection->delete_stream_reader(
175 stream_reader_forwarder->stream_reader_);
176 stream_reader_forwarder->stream_reader_ = NULL;
178 }
catch(
const rti::apputils::FatalServiceException& ex) {
179 RTI_RoutingServiceEnvironment_fatal_error(
182 }
catch(
const std::exception& ex) {
183 RTI_RoutingServiceEnvironment_set_error(
187 RTI_RoutingServiceEnvironment_set_error(
189 "unexpected exception");
192 delete stream_reader_forwarder;
196 RTI_RoutingServiceStreamReaderExt* native()
198 return &this->native_;
204 StreamReaderForwarder(
205 const RTI_RoutingServiceStreamReaderListenerExt *native_listener) :
206 stream_reader_(NULL),
207 listener_(native_listener)
209 RTIOsapiMemory_zero(&native_,
sizeof(native_));
210 native_.stream_reader_data =
211 static_cast<void *
>(
this);
213 StreamReaderForwarder::take;
215 StreamReaderForwarder::read;
216 native_.take_w_selector =
217 StreamReaderForwarder::take_with_selector;
218 native_.read_w_selector =
219 StreamReaderForwarder::read_with_selector;
220 native_.return_loan =
221 StreamReaderForwarder::return_loan;
222 native_.create_content_query =
223 StreamReaderForwarder::create_content_query;
224 native_.delete_content_query =
225 StreamReaderForwarder::delete_content_query;
227 StreamReaderForwarder::update;
230 ~StreamReaderForwarder()
233 for (std::list<SamplesHolder*>::iterator it = holder_pool_.begin();
234 it != holder_pool_.end();
242 void *native_stream_reader_data,
243 RTI_RoutingServiceSample **sample_array,
244 RTI_RoutingServiceSampleInfo **sample_info_array,
246 RTI_RoutingServiceEnvironment *environment)
248 proxy_read<false, false>(
249 native_stream_reader_data,
258 void *native_stream_reader_data,
259 RTI_RoutingServiceSample **sample_array,
260 RTI_RoutingServiceSampleInfo **sample_info_array,
262 RTI_RoutingServiceEnvironment *environment)
264 proxy_read<true, false>(
265 native_stream_reader_data,
273 static void take_with_selector(
274 void *native_stream_reader_data,
275 RTI_RoutingServiceSample **sample_array,
276 RTI_RoutingServiceSampleInfo **sample_info_array,
278 const struct RTI_RoutingServiceSelectorState *native_selector,
279 RTI_RoutingServiceEnvironment *environment)
281 proxy_read<false, true>(
282 native_stream_reader_data,
290 static void read_with_selector(
291 void *native_stream_reader_data,
292 RTI_RoutingServiceSample **sample_array,
293 RTI_RoutingServiceSampleInfo **sample_info_array,
295 const struct RTI_RoutingServiceSelectorState *native_selector,
296 RTI_RoutingServiceEnvironment *environment)
298 proxy_read<true, true>(
299 native_stream_reader_data,
307 static void return_loan(
308 void *native_stream_reader_data,
309 RTI_RoutingServiceSample *native_samples,
310 RTI_RoutingServiceSampleInfo *,
312 RTI_RoutingServiceEnvironment *environment)
314 StreamReaderForwarder *forwarder =
315 static_cast<StreamReaderForwarder*
>(native_stream_reader_data);
316 assert(forwarder != NULL);
318 SamplesHolder *holder =
static_cast<SamplesHolder*
>(
319 native_samples[count]);
320 assert(holder != NULL);
324 forwarder->stream_reader_->return_loan(
327 }
catch (
const rti::apputils::FatalServiceException& ex) {
328 RTI_RoutingServiceEnvironment_fatal_error(
331 }
catch (
const std::exception& ex) {
332 RTI_RoutingServiceEnvironment_set_error(
336 RTI_RoutingServiceEnvironment_set_error(
338 "unexpected exception");
341 forwarder->return_holder(holder);
345 void *native_stream_reader_data,
346 const struct RTI_RoutingServiceProperties * native_properties,
347 RTI_RoutingServiceEnvironment * environment)
350 StreamReaderForwarder *stream_reader_forwarder =
351 static_cast<StreamReaderForwarder*
>(native_stream_reader_data);
353 rti::routing::detail::UpdatableEntityForwarder::update(
354 stream_reader_forwarder->stream_reader_,
359 static void* create_content_query(
360 void *native_stream_reader_data,
361 RTI_RoutingServiceSelectorStateQueryData old_query_data,
362 const struct RTI_RoutingServiceSelectorContent *content,
363 RTI_RoutingServiceEnvironment *environment)
365 StreamReaderForwarder *forwarder =
366 static_cast<StreamReaderForwarder*
>(native_stream_reader_data);
368 void *query_data = NULL;
370 dds::topic::Filter filter(
371 content->expression == NULL ?
"" : content->expression,
372 rti::core::native_conversions::from_native<std::string>(
373 content->expression_parameters));
374 query_data = forwarder->stream_reader_->create_content_query(
377 }
catch (
const rti::apputils::FatalServiceException& ex) {
378 RTI_RoutingServiceEnvironment_fatal_error(
381 }
catch (
const std::exception& ex) {
382 RTI_RoutingServiceEnvironment_set_error(
386 RTI_RoutingServiceEnvironment_set_error(
388 "unexpected exception");
394 static void delete_content_query(
395 void *native_stream_reader_data,
396 RTI_RoutingServiceSelectorStateQueryData query_data,
397 RTI_RoutingServiceEnvironment *environment)
399 StreamReaderForwarder *forwarder =
400 static_cast<StreamReaderForwarder*
>(native_stream_reader_data);
402 forwarder->stream_reader_->delete_content_query(query_data);
403 }
catch (
const std::exception& ex) {
404 RTI_RoutingServiceEnvironment_set_error(
409 RTI_RoutingServiceEnvironment_set_error(
411 "unexpected exception");
415 static StreamReaderForwarder* from_native(
416 RTI_RoutingServiceStreamReaderExt *native)
418 return static_cast<StreamReaderForwarder*
>(native->stream_reader_data);
421 template <
bool ReadOrTake,
bool HasSelector>
422 static void proxy_read(
423 void *native_stream_reader_data,
424 RTI_RoutingServiceSample **sample_array,
425 RTI_RoutingServiceSampleInfo **sample_info_array,
427 const struct RTI_RoutingServiceSelectorState *native_selector,
428 RTI_RoutingServiceEnvironment *environment)
430 StreamReaderForwarder *forwarder =
431 static_cast<StreamReaderForwarder*
>(native_stream_reader_data);
432 assert(forwarder != NULL);
434 SamplesHolder *holder = forwarder->get_holder();
438 read_or_take<ReadOrTake, HasSelector>::read(
439 *forwarder->stream_reader_,
443 if (!holder->info_seq_.empty()
444 && (holder->info_seq_.size() != holder->sample_seq_.size())) {
445 throw dds::core::PreconditionNotMetError(
446 "sample and info sequences length mismatch");
457 if (holder->sample_seq_.size() + 1
458 >= holder->sample_seq_.capacity()) {
459 holder->sample_seq_.reserve(
460 holder->sample_seq_.capacity() == 0
462 : 2 * holder->sample_seq_.capacity());
464 *(holder->sample_seq_.data() + holder->sample_seq_.size()) = holder;
465 }
catch (
const rti::apputils::FatalServiceException& ex) {
466 RTI_RoutingServiceEnvironment_fatal_error(
469 forwarder->return_holder(holder);
471 }
catch (
const std::exception& ex) {
472 RTI_RoutingServiceEnvironment_set_error(
475 forwarder->return_holder(holder);
478 RTI_RoutingServiceEnvironment_set_error(
480 "unexpected exception");
481 forwarder->return_holder(holder);
486 *array_length =
static_cast<int>(holder->sample_seq_.size());
487 *sample_array = holder->sample_seq_.data();
488 if (holder->info_seq_.empty()) {
489 *sample_info_array = NULL;
491 *sample_info_array = &holder->info_seq_[0];
495 SamplesHolder* get_holder()
497 if (holder_pool_.size() == 0) {
498 return new SamplesHolder();
501 SamplesHolder *holder = holder_pool_.front();
502 holder_pool_.pop_front();
507 void return_holder(SamplesHolder *holder)
509 holder->sample_seq_.clear();
510 holder->info_seq_.clear();
511 holder_pool_.push_front(holder);
516 RTI_RoutingServiceStreamReaderExt native_;
517 StreamReader *stream_reader_;
519 std::list<SamplesHolder*> holder_pool_;
Listener representation used by StreamReader to notify RTI Routing Service when new data is available...
Provides a way to read samples of a specific type from a data domain. In the XML configuration file,...
Definition: StreamReader.hpp:45
virtual void take(std::vector< SamplePtr > &sample_seq, std::vector< InfoPtr > &info_seq)=0
Takes a collection of all data samples and info samples available from an input stream.
virtual void read(std::vector< SamplePtr > &sample_seq, std::vector< InfoPtr > &info_seq)=0
Variation of StreamReader::take where the returned samples will remain in the StreamReader's cache,...