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_XTYPES_UTILS_H
7 : #define OPENDDS_DCPS_XTYPES_UTILS_H
8 :
9 : #ifndef OPENDDS_SAFETY_PROFILE
10 : # include <dds/DCPS/Serializer.h>
11 :
12 : # include <dds/DdsDynamicDataC.h>
13 :
14 : # include <cstring>
15 :
16 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
17 : namespace OpenDDS {
18 : namespace XTypes {
19 :
20 0 : inline bool dynamic_type_is_valid(DDS::DynamicType_ptr type)
21 : {
22 0 : DDS::TypeDescriptor_var td;
23 0 : return type && type->get_descriptor(td) == DDS::RETCODE_OK && td;
24 0 : }
25 :
26 : OpenDDS_Dcps_Export DDS::ReturnCode_t extensibility(
27 : DDS::DynamicType_ptr type, DCPS::Extensibility& ext);
28 : OpenDDS_Dcps_Export DDS::ReturnCode_t max_extensibility(
29 : DDS::DynamicType_ptr type, DCPS::Extensibility& ext);
30 : OpenDDS_Dcps_Export DCPS::Extensibility dds_to_opendds_ext(DDS::ExtensibilityKind ext);
31 :
32 : /**
33 : * Iterate over parts of a member name path that can be the name of a
34 : * field inside a function or an array element nested multiple levels inside a
35 : * type.
36 : *
37 : * Examples:
38 : * "member_a"
39 : * "member_b[2]"
40 : * "member_b[2].x"
41 : * "[2]" (If the DynamicData is indexed or keyed)
42 : */
43 : class OpenDDS_Dcps_Export MemberPathParser {
44 : public:
45 : size_t pos;
46 : size_t left;
47 : const char* path;
48 : bool error;
49 : bool in_subscript;
50 : DCPS::String subpath;
51 :
52 17 : MemberPathParser(const char* path)
53 17 : : pos(0)
54 17 : , left(path ? std::strlen(path) : 0)
55 17 : , path(left > 0 ? path : 0)
56 17 : , error(false)
57 17 : , in_subscript(false)
58 : {
59 17 : }
60 :
61 0 : MemberPathParser(const DCPS::String& path)
62 0 : : pos(0)
63 0 : , left(path.size())
64 0 : , path(left > 0 ? path.c_str() : 0)
65 0 : , error(false)
66 0 : , in_subscript(false)
67 : {
68 0 : }
69 :
70 : bool consume(size_t by);
71 :
72 : /**
73 : * Put the next member name or subscript value in subpath and which kind in
74 : * in_subscript. Returns false when the end of the path is reached or there
75 : * was an error in which case error is set to true.
76 : */
77 : bool get_next_subpath();
78 :
79 : bool get_index(DDS::UInt32 &index);
80 : };
81 :
82 : /**
83 : * Provides access to a specific member using MemberIds that may be nested
84 : * inside a DynamicType or DynamicData.
85 : */
86 : class OpenDDS_Dcps_Export MemberPath {
87 : public:
88 : typedef OPENDDS_VECTOR(DDS::MemberId) MemberIdVec;
89 : MemberIdVec ids;
90 :
91 83 : MemberPath()
92 83 : {
93 83 : }
94 :
95 1143 : MemberPath(const MemberPath& other, DDS::MemberId id)
96 1143 : : ids(other.ids)
97 : {
98 1143 : ids.push_back(id);
99 1143 : }
100 :
101 39 : MemberPath& id(DDS::MemberId id)
102 : {
103 39 : ids.push_back(id);
104 39 : return *this;
105 : }
106 :
107 988 : size_t level() const { return ids.size(); }
108 :
109 : DDS::ReturnCode_t resolve_string_path(
110 : DDS::DynamicType_ptr type, const DCPS::String &path);
111 :
112 : DDS::ReturnCode_t get_member_from_type(
113 : DDS::DynamicType_ptr type, DDS::DynamicTypeMember_var& member);
114 :
115 : /**
116 : * DynamicData itself holds the access methods to its members, so in order to
117 : * access them, we have to give both the containing Dynamic Data and the
118 : * member ID.
119 : */
120 : DDS::ReturnCode_t get_member_from_data(
121 : DDS::DynamicData_ptr data, DDS::DynamicData_var& container, DDS::MemberId& member_id);
122 : };
123 : typedef OPENDDS_VECTOR(MemberPath) MemberPathVec;
124 :
125 : enum Filter {
126 : Filter_All,
127 : Filter_Keys,
128 : Filter_NestedKeys,
129 : Filter_NonKeys
130 : };
131 :
132 : OpenDDS_Dcps_Export DDS::ReturnCode_t get_values(
133 : DDS::DynamicType_ptr type, MemberPathVec& paths, Filter filter);
134 : OpenDDS_Dcps_Export DDS::ReturnCode_t get_keys(DDS::DynamicType_ptr type, MemberPathVec& paths);
135 : OpenDDS_Dcps_Export bool is_key(DDS::DynamicType_ptr type, const char* field);
136 : OpenDDS_Dcps_Export DDS::ReturnCode_t key_count(DDS::DynamicType_ptr type, size_t& count);
137 :
138 : OpenDDS_Dcps_Export DDS::ReturnCode_t less_than(
139 : bool& result, DDS::DynamicData_ptr a, DDS::DynamicData_ptr b, Filter filter);
140 : OpenDDS_Dcps_Export DDS::ReturnCode_t key_less_than(
141 : bool& result, DDS::DynamicData_ptr a, DDS::DynamicData_ptr b);
142 : OpenDDS_Dcps_Export DDS::ReturnCode_t compare_members(
143 : int& result, DDS::DynamicData_ptr a, DDS::DynamicData_ptr b, DDS::MemberId id);
144 :
145 : OpenDDS_Dcps_Export DDS::ReturnCode_t get_member_type(
146 : DDS::DynamicType_var& member_type, DDS::DynamicType_ptr container_type, DDS::MemberId id);
147 :
148 1668 : inline DDS::ReturnCode_t get_member_type(
149 : DDS::DynamicType_var& member_type, DDS::DynamicData_ptr container, DDS::MemberId id)
150 : {
151 1668 : DDS::DynamicType_var container_type = container->type();
152 3336 : return get_member_type(member_type, container_type, id);
153 1668 : }
154 :
155 : OpenDDS_Dcps_Export DDS::ReturnCode_t get_uint_value(
156 : DDS::UInt64& value, DDS::DynamicData_ptr src, DDS::MemberId id, DDS::TypeKind kind);
157 : OpenDDS_Dcps_Export DDS::ReturnCode_t set_uint_value(
158 : DDS::DynamicData_ptr dest, DDS::MemberId id, DDS::TypeKind kind, DDS::UInt64 value);
159 : OpenDDS_Dcps_Export DDS::ReturnCode_t get_int_value(
160 : DDS::Int64& value, DDS::DynamicData_ptr src, DDS::MemberId id, DDS::TypeKind kind);
161 : OpenDDS_Dcps_Export DDS::ReturnCode_t set_int_value(
162 : DDS::DynamicData_ptr dest, DDS::MemberId id, DDS::TypeKind kind, DDS::Int64 value);
163 :
164 : OpenDDS_Dcps_Export DDS::UInt32 bound_total(DDS::TypeDescriptor_var descriptor);
165 :
166 : OpenDDS_Dcps_Export DDS::ReturnCode_t bitmask_bound(
167 : DDS::DynamicType_ptr type, DDS::TypeKind& bound_kind);
168 : OpenDDS_Dcps_Export DDS::ReturnCode_t get_bitmask_value(
169 : DDS::UInt64& value, DDS::DynamicType_ptr type, DDS::DynamicData_ptr src, DDS::MemberId id);
170 :
171 : OpenDDS_Dcps_Export DDS::ReturnCode_t enum_bound(DDS::DynamicType_ptr enum_type, DDS::TypeKind& bound_kind);
172 :
173 : OpenDDS_Dcps_Export DDS::ReturnCode_t get_enum_value(
174 : DDS::Int32& value, DDS::DynamicType_ptr enum_type, DDS::DynamicData_ptr src, DDS::MemberId id);
175 : inline DDS::ReturnCode_t get_enum_value(
176 : DDS::Int32& value, DDS::DynamicData_ptr src, DDS::MemberId id)
177 : {
178 : DDS::DynamicType_var enum_type;
179 : const DDS::ReturnCode_t rc = get_member_type(enum_type, src, id);
180 : if (rc != DDS::RETCODE_OK) {
181 : return rc;
182 : }
183 : return get_enum_value(value, enum_type, src, id);
184 : }
185 :
186 : OpenDDS_Dcps_Export DDS::ReturnCode_t set_enum_value(
187 : DDS::DynamicType_ptr enum_type, DDS::DynamicData_ptr dest, DDS::MemberId id, DDS::Int32 value);
188 : inline DDS::ReturnCode_t set_enum_value(
189 : DDS::DynamicData_ptr dest, DDS::MemberId id, DDS::Int32 value)
190 : {
191 : DDS::DynamicType_var enum_type;
192 : const DDS::ReturnCode_t rc = get_member_type(enum_type, dest, id);
193 : if (rc != DDS::RETCODE_OK) {
194 : return rc;
195 : }
196 : return set_enum_value(enum_type, dest, id, value);
197 : }
198 :
199 : OpenDDS_Dcps_Export DDS::ReturnCode_t set_enum_value(
200 : DDS::DynamicType_ptr enum_type, DDS::DynamicData_ptr dest, DDS::MemberId id,
201 : const char* enumeral_name);
202 : inline DDS::ReturnCode_t set_enum_value(
203 : DDS::DynamicData_ptr dest, DDS::MemberId id, const char* enumeral_name)
204 : {
205 : DDS::DynamicType_var enum_type;
206 : const DDS::ReturnCode_t rc = get_member_type(enum_type, dest, id);
207 : if (rc != DDS::RETCODE_OK) {
208 : return rc;
209 : }
210 : return set_enum_value(enum_type, dest, id, enumeral_name);
211 : }
212 :
213 : OpenDDS_Dcps_Export DDS::ReturnCode_t get_enumerator_name(
214 : DDS::String8_var& name, DDS::Int32 value, DDS::DynamicType_ptr type);
215 : OpenDDS_Dcps_Export DDS::ReturnCode_t get_enumerator_value(
216 : DDS::Int32& value, const char* name, DDS::DynamicType_ptr type);
217 :
218 : OpenDDS_Dcps_Export DDS::ReturnCode_t copy_member(
219 : DDS::DynamicData_ptr dest, DDS::MemberId dest_id,
220 : DDS::DynamicData_ptr src, DDS::MemberId src_id);
221 : OpenDDS_Dcps_Export DDS::ReturnCode_t copy(DDS::DynamicData_ptr dest, DDS::DynamicData_ptr src);
222 :
223 : } // namespace XTypes
224 : } // namespace OpenDDS
225 : OPENDDS_END_VERSIONED_NAMESPACE_DECL
226 :
227 : #endif // OPENDDS_SAFETY_PROFILE
228 : #endif
|