Line data Source code
1 : /*
2 : * Distributed under the OpenDDS License.
3 : * See: http://www.opendds.org/license.html
4 : */
5 :
6 : #ifndef OPENDDS_DCPS_SAMPLE_H
7 : #define OPENDDS_DCPS_SAMPLE_H
8 :
9 : #include "Serializer.h"
10 : #include "TypeSupportImpl.h"
11 : #include "RcHandle_T.h"
12 : #include "FilterEvaluator.h"
13 :
14 : #include <dds/DdsDynamicDataC.h>
15 :
16 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
17 :
18 : namespace OpenDDS {
19 :
20 : #ifndef OPENDDS_SAFETY_PROFILE
21 : namespace XTypes {
22 : // These are here because including DynamicDataAdapter.h creates a include loop.
23 : template <typename T, typename Tag>
24 : DDS::DynamicData_ptr get_dynamic_data_adapter(DDS::DynamicType_ptr type, const T& value);
25 :
26 : template <typename T, typename Tag>
27 : DDS::DynamicData_ptr get_dynamic_data_adapter(DDS::DynamicType_ptr type, T& value);
28 : }
29 : #endif
30 :
31 : namespace DCPS {
32 :
33 : class Sample;
34 : typedef RcHandle<Sample> Sample_rch;
35 : typedef RcHandle<const Sample> ConstSample_rch;
36 :
37 : /**
38 : * Represents a sample that can either be an instance of a C++ generated type
39 : * from opendds_idl or a DynamicData. This is meant to be used by
40 : * DataReaderImpl and DataWriterImpl.
41 : */
42 : class OpenDDS_Dcps_Export Sample : public RcObject {
43 : public:
44 : enum Mutability {
45 : Mutable,
46 : ReadOnly
47 : };
48 :
49 : enum Extent {
50 : Full,
51 : KeyOnly,
52 : NestedKeyOnly
53 : };
54 :
55 : Sample()
56 : : mutability_(Mutable)
57 : , extent_(Full)
58 : {
59 : }
60 :
61 0 : Sample(Mutability mutability, Extent extent)
62 0 : : mutability_(mutability)
63 0 : , extent_(extent)
64 : {
65 0 : OPENDDS_ASSERT(extent != NestedKeyOnly);
66 0 : }
67 :
68 0 : virtual ~Sample() {}
69 :
70 0 : bool read_only() const
71 : {
72 0 : return mutability_ == ReadOnly;
73 : }
74 :
75 0 : bool key_only() const
76 : {
77 0 : return extent_ == KeyOnly;
78 : }
79 :
80 : virtual bool serialize(Serializer& ser) const = 0;
81 : virtual bool deserialize(Serializer& ser) = 0;
82 : virtual size_t serialized_size(const Encoding& enc) const = 0;
83 : virtual bool compare(const Sample& other) const = 0;
84 : virtual bool to_message_block(ACE_Message_Block& mb) const = 0;
85 : virtual bool from_message_block(const ACE_Message_Block& mb) = 0;
86 : virtual Sample_rch copy(Mutability mutability, Extent extent) const = 0;
87 :
88 0 : Sample_rch copy(Mutability mutability) const
89 : {
90 0 : return copy(mutability, extent_);
91 : }
92 :
93 : #ifndef OPENDDS_SAFETY_PROFILE
94 : virtual DDS::DynamicData_var get_dynamic_data(DDS::DynamicType_ptr type) const = 0;
95 : #endif
96 :
97 : virtual const void* native_data() const = 0;
98 :
99 : #ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE
100 : virtual bool eval(FilterEvaluator& evaluator, const DDS::StringSeq& params) const = 0;
101 : #endif
102 :
103 : protected:
104 : Mutability mutability_;
105 : Extent extent_;
106 : };
107 :
108 : struct OpenDDS_Dcps_Export SampleRchCmp {
109 0 : bool operator()(const Sample_rch& lhs, const Sample_rch& rhs) const
110 : {
111 0 : return lhs->compare(*rhs);
112 : }
113 : };
114 :
115 : template <typename NativeType>
116 : class Sample_T : public Sample {
117 : public:
118 : typedef DDSTraits<NativeType> TraitsType;
119 : typedef MarshalTraits<NativeType> MarshalTraitsType;
120 : typedef RcHandle<Sample_T<NativeType> > Rch;
121 : typedef DCPS::KeyOnly<const NativeType> KeyOnlyType;
122 : typedef DCPS::KeyOnly<NativeType> MutableKeyOnlyType;
123 :
124 0 : explicit Sample_T(const NativeType& data, Extent extent = Full)
125 : : Sample(ReadOnly, extent)
126 0 : , owns_data_(false)
127 0 : , data_(&data)
128 : #if OPENDDS_HAS_DYNAMIC_DATA_ADAPTER
129 0 : , dynamic_data_(0)
130 : #endif
131 : {
132 0 : }
133 :
134 0 : explicit Sample_T(const NativeType* data, Extent extent = Full)
135 : : Sample(ReadOnly, extent)
136 0 : , owns_data_(true)
137 0 : , data_(data)
138 : #if OPENDDS_HAS_DYNAMIC_DATA_ADAPTER
139 0 : , dynamic_data_(0)
140 : #endif
141 : {
142 0 : }
143 :
144 : explicit Sample_T(NativeType& data, Extent extent = Full)
145 : : Sample(Mutable, extent)
146 : , owns_data_(false)
147 : , data_(&data)
148 : #if OPENDDS_HAS_DYNAMIC_DATA_ADAPTER
149 : , dynamic_data_(0)
150 : #endif
151 : {
152 : }
153 :
154 0 : explicit Sample_T(NativeType* data, Extent extent = Full)
155 : : Sample(Mutable, extent)
156 0 : , owns_data_(true)
157 0 : , data_(data)
158 : #if OPENDDS_HAS_DYNAMIC_DATA_ADAPTER
159 0 : , dynamic_data_(0)
160 : #endif
161 : {
162 0 : }
163 :
164 0 : virtual ~Sample_T()
165 : {
166 0 : if (owns_data_) {
167 0 : delete data_;
168 : }
169 0 : }
170 :
171 0 : const NativeType& data() const
172 : {
173 0 : return *data_;
174 : }
175 :
176 0 : NativeType& mutable_data() const
177 : {
178 0 : OPENDDS_ASSERT(!read_only());
179 0 : return *const_cast<NativeType*>(data_);
180 : }
181 :
182 0 : KeyOnlyType key_only_data() const
183 : {
184 0 : return KeyOnlyType(*data_);
185 : }
186 :
187 0 : MutableKeyOnlyType mutable_key_only_data() const
188 : {
189 0 : return MutableKeyOnlyType(mutable_data());
190 : }
191 :
192 0 : bool serialize(Serializer& ser) const
193 : {
194 0 : if (key_only()) {
195 0 : return ser << key_only_data();
196 : } else {
197 0 : return ser << data();
198 : }
199 : }
200 :
201 0 : bool deserialize(Serializer& ser)
202 : {
203 0 : if (key_only()) {
204 0 : return ser >> mutable_key_only_data();
205 : } else {
206 0 : return ser >> mutable_data();
207 : }
208 : }
209 :
210 0 : size_t serialized_size(const Encoding& enc) const
211 : {
212 0 : if (key_only()) {
213 0 : return OpenDDS::DCPS::serialized_size(enc, key_only_data());
214 : } else {
215 0 : return OpenDDS::DCPS::serialized_size(enc, data());
216 : }
217 : }
218 :
219 0 : bool compare(const Sample& other) const
220 : {
221 0 : const Sample_T<NativeType>* const other_same_kind =
222 0 : dynamic_cast<const Sample_T<NativeType>*>(&other);
223 0 : OPENDDS_ASSERT(other_same_kind);
224 0 : return typename TraitsType::LessThanType()(*data_, *other_same_kind->data_);
225 : }
226 :
227 0 : bool to_message_block(ACE_Message_Block& mb) const
228 : {
229 0 : return MarshalTraitsType::to_message_block(mb, data());
230 : }
231 :
232 0 : bool from_message_block(const ACE_Message_Block& mb)
233 : {
234 0 : return MarshalTraitsType::from_message_block(mutable_data(), mb);
235 : }
236 :
237 0 : Sample_rch copy(Mutability mutability, Extent extent) const
238 : {
239 0 : NativeType* new_data = new NativeType;
240 0 : *new_data = *data_;
241 0 : return dynamic_rchandle_cast<Sample>(mutability == ReadOnly ?
242 0 : make_rch<Sample_T<NativeType> >(const_cast<const NativeType*>(new_data), extent) :
243 0 : make_rch<Sample_T<NativeType> >(new_data, extent));
244 : }
245 :
246 : #ifndef OPENDDS_SAFETY_PROFILE
247 0 : DDS::DynamicData_var get_dynamic_data(DDS::DynamicType_ptr type) const
248 : {
249 : # if OPENDDS_HAS_DYNAMIC_DATA_ADAPTER
250 0 : if (!dynamic_data_ && data_) {
251 0 : dynamic_data_ = read_only() ?
252 0 : XTypes::get_dynamic_data_adapter<NativeType, NativeType>(type, *data_) :
253 0 : XTypes::get_dynamic_data_adapter<NativeType, NativeType>(type, mutable_data());
254 : }
255 0 : return dynamic_data_;
256 : # else
257 : ACE_UNUSED_ARG(type);
258 : return 0;
259 : # endif
260 : }
261 : #endif
262 :
263 0 : const void* native_data() const
264 : {
265 0 : return data_;
266 : }
267 :
268 : #ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE
269 0 : bool eval(FilterEvaluator& evaluator, const DDS::StringSeq& params) const
270 : {
271 0 : return evaluator.eval(*data_, params);
272 : }
273 : #endif
274 :
275 : private:
276 : const bool owns_data_;
277 : const NativeType* data_;
278 : #if OPENDDS_HAS_DYNAMIC_DATA_ADAPTER
279 : mutable DDS::DynamicData_var dynamic_data_;
280 : #endif
281 : };
282 :
283 : } // namespace DCPS
284 : } // namespace OpenDDS
285 :
286 : OPENDDS_END_VERSIONED_NAMESPACE_DECL
287 :
288 : #endif
|