RTI Routing Service Version 7.7.0
TransformationForwarder.hpp
1/*
2 * (c) Copyright, Real-Time Innovations, 2017.
3 * All rights reserved.
4 *
5 * No duplications, whole or partial, manual or electronic, may be made
6 * without express written permission. Any such copies, or
7 * revisions thereof, must display this notice unaltered.
8 * This code contains trade secrets of Real-Time Innovations, Inc.
9 */
10
11#ifndef RTI_ROUTING_TRANSF_DETAIL_TRANSFORMATION_FORWARDER_HPP_
12#define RTI_ROUTING_TRANSF_DETAIL_TRANSFORMATION_FORWARDER_HPP_
13
14#include <rti/core/Exception.hpp>
15
16#include <dds/core/xtypes/DynamicData.hpp>
17#include <dds/sub/SampleInfo.hpp>
18
19#include <rti/routing/transf/Transformation.hpp>
20#include <rti/routing/TypeInfo.hpp>
21#include <rti/routing/detail/UpdatableEntityForwarder.hpp>
22#include <rti/routing/detail/ForwarderUtils.hpp>
23
24#include "rti/apputils/ServiceException.hpp"
25
26
27namespace rti { namespace routing { namespace transf { namespace detail {
28
29
30class TransformationForwarder{
31public:
32 static RTI_RoutingServiceTransformation create_native(
33 TransformationPlugin *plugin,
34 const struct RTI_RoutingServiceTypeInfo *native_input_type_info,
35 const struct RTI_RoutingServiceTypeInfo *native_output_type_info,
36 const struct RTI_RoutingServiceProperties *native_properties,
37 RTI_RoutingServiceEnvironment *environment)
38 {
39 try {
40 using rti::routing::detail::ScopedForwarder;
41
42 TypeInfo input_type_info(*native_input_type_info);
43 TypeInfo output_type_info(*native_output_type_info);
44
45 std::map<std::string, std::string> properties;
46 rti::routing::PropertyAdapter::add_properties_from_native(
47 properties,
48 native_properties);
49
50 TransformationForwarder *forwarder = new TransformationForwarder();
51 ScopedForwarder<TransformationPlugin, TransformationForwarder> scoped(
52 plugin,
53 forwarder,
54 environment);
55 forwarder->transformation_ = plugin->create_transformation(
56 input_type_info,
57 output_type_info,
58 properties);
59 RTI_ROUTING_THROW_ON_NULL(forwarder->transformation_);
60
61 scoped.release();
62 return forwarder->native();
63 } catch(const rti::apputils::FatalServiceException& ex) {
64 RTI_RoutingServiceEnvironment_fatal_error(
65 environment,
66 ex.what());
67 return NULL;
68 } catch(const std::exception& ex) {
69 RTI_RoutingServiceEnvironment_set_error(
70 environment,
71 ex.what());
72 return NULL;
73 } catch (...) {
74 RTI_RoutingServiceEnvironment_set_error(
75 environment,
76 "unexpected exception");
77 return NULL;
78 }
79
80 }
81
82 static void delete_native(
83 TransformationPlugin *plugin,
84 RTI_RoutingServiceTransformation native_transformation,
85 RTI_RoutingServiceEnvironment *environment)
86 {
87 TransformationForwarder *forwarder =
88 static_cast<TransformationForwarder*>(native_transformation);
89 try {
90 if (forwarder->transformation_ != NULL) {
91 plugin->delete_transformation(
92 forwarder->transformation_);
93 forwarder->transformation_ = NULL;
94 }
95 } catch(const rti::apputils::FatalServiceException& ex) {
96 RTI_RoutingServiceEnvironment_fatal_error(
97 environment,
98 ex.what());
99 } catch(const std::exception& ex) {
100 RTI_RoutingServiceEnvironment_set_error(
101 environment,
102 ex.what());
103 } catch (...) {
104 RTI_RoutingServiceEnvironment_set_error(
105 environment,
106 "unexpected exception");
107 }
108
109 delete forwarder;
110 }
111
112 static void transform(
113 RTI_RoutingServiceTransformation native_transformation,
114 RTI_RoutingServiceSample **out_sample_lst,
115 RTI_RoutingServiceSampleInfo **out_info_lst,
116 int *out_count,
117 RTI_RoutingServiceSample *in_sample_lst,
118 RTI_RoutingServiceSampleInfo *in_info_lst,
119 int in_count,
120 RTI_RoutingServiceEnvironment *environment)
121 {
122 TransformationForwarder *forwarder =
123 static_cast<TransformationForwarder*> (native_transformation);
124 if (forwarder->transformation_ == NULL) {
125 return;
126 }
127
128 *out_count = 0;
129 try {
130 // get native samples
131 forwarder->in_sample_seq_.resize(in_count);
132 forwarder->in_info_seq_.resize(in_count);
133 for (int i = 0; i < in_count; i++) {
134 forwarder->in_sample_seq_[i] = in_sample_lst[i];
135 if (in_info_lst != NULL) {
136 forwarder->in_info_seq_[i] = in_info_lst[i];
137 }
138 }
139
140 forwarder->transformation_->transform(
141 forwarder->out_sample_seq_,
142 forwarder->out_info_seq_,
143 forwarder->in_sample_seq_,
144 forwarder->in_info_seq_);
145 if (!forwarder->out_info_seq_.empty()
146 && (forwarder->out_info_seq_.size()
147 != forwarder->out_sample_seq_.size())) {
148 throw dds::core::PreconditionNotMetError(
149 "sample and info sequences length mismatch");
150 }
151 } catch (const rti::apputils::FatalServiceException& ex) {
152 RTI_RoutingServiceEnvironment_fatal_error(
153 environment,
154 ex.what());
155 return;
156 } catch (const std::exception& ex) {
157 RTI_RoutingServiceEnvironment_set_error(
158 environment,
159 ex.what());
160 return;
161 } catch (...) {
162 RTI_RoutingServiceEnvironment_set_error(
163 environment,
164 "unexpected exception");
165 return;
166 }
167
168 // direct mapping
169 *out_count = static_cast<int>(forwarder->out_sample_seq_.size());
170 if (*out_count > 0) {
171 *out_sample_lst = &forwarder->out_sample_seq_[0];
172 *out_info_lst = &forwarder->out_info_seq_[0];
173 }
174 }
175
176 static void return_loan(
177 RTI_RoutingServiceTransformation native_transformation,
178 RTI_RoutingServiceSample *,
179 RTI_RoutingServiceSampleInfo *,
180 int,
181 RTI_RoutingServiceEnvironment *environment)
182 {
183 TransformationForwarder *forwarder =
184 static_cast<TransformationForwarder*>(native_transformation);
185 if (forwarder->transformation_ == NULL) {
186 return;
187 }
188
189 try {
190 forwarder->transformation_->return_loan(
191 forwarder->out_sample_seq_,
192 forwarder->out_info_seq_);
193 } catch (const rti::apputils::FatalServiceException& ex) {
194 RTI_RoutingServiceEnvironment_fatal_error(
195 environment,
196 ex.what());
197 } catch (const std::exception& ex) {
198 RTI_RoutingServiceEnvironment_set_error(
199 environment,
200 ex.what());
201 } catch (...) {
202 RTI_RoutingServiceEnvironment_set_error(
203 environment,
204 "unexpected exception");
205 }
206
207 forwarder->out_sample_seq_.clear();
208 forwarder->out_info_seq_.clear();
209
210 }
211
212 static void update(
213 RTI_RoutingServiceTransformation native_stream_reader,
214 const struct RTI_RoutingServiceProperties *native_properties,
215 RTI_RoutingServiceEnvironment *environment)
216 {
217
218 TransformationForwarder *stream_reader_forwarder =
219 static_cast<TransformationForwarder*> (native_stream_reader);
220
221 rti::routing::detail::UpdatableEntityForwarder::update(
222 stream_reader_forwarder->transformation_,
223 native_properties,
224 environment);
225 }
226
227 RTI_RoutingServiceTransformation native()
228 {
229 return this;
230 }
231
232
233private:
234
235 TransformationForwarder()
236 : transformation_(NULL)
237 {
238
239 }
240
241 ~TransformationForwarder()
242 {
243 }
244
245
246private:
247
248 Transformation *transformation_;
249 std::vector<Transformation::SamplePtr> out_sample_seq_;
250 std::vector<Transformation::InfoPtr> out_info_seq_;
251 std::vector<Transformation::SamplePtr> in_sample_seq_;
252 std::vector<Transformation::InfoPtr> in_info_seq_;
253};
254
255}}}}
256
257#endif // RTI_ROUTING_TRANSF_DETAIL_TRANSFORMATION_FORWARDER_HPP_