OpenDDS  Snapshot(2023/04/28-20:55)
topic_keys.cpp
Go to the documentation of this file.
1 #include "topic_keys.h"
2 
3 #include "be_extern.h"
4 #include "dds_generator.h"
5 
6 #include <idl_defines.h>
7 #include <ast_structure.h>
8 #include <ast_field.h>
9 #include <utl_identifier.h>
10 #include <ast_union.h>
11 #include <ast_array.h>
12 
13 #include <string>
14 
16 {
17  if (!type) {
18  return InvalidType;
19  }
20  switch (type->unaliased_type()->node_type()) {
21  case AST_Decl::NT_pre_defined:
22  case AST_Decl::NT_string:
23  case AST_Decl::NT_wstring:
24  case AST_Decl::NT_enum:
25  return PrimitiveType;
26  case AST_Decl::NT_struct:
27  return StructureType;
28  case AST_Decl::NT_union:
29  return UnionType;
30  case AST_Decl::NT_array:
31  return ArrayType;
32  case AST_Decl::NT_sequence:
33  return SequenceType;
34  default:
35  return InvalidType;
36  }
37 }
38 
40  : node_(0)
41 {
42 }
43 
44 TopicKeys::Error::Error(AST_Decl* node, const std::string& message)
45  : node_(node)
46  , message_(message)
47 {
48 }
49 
51 {
52 }
53 
55 {
56  node_ = error.node_;
57  message_ = error.message_;
58  return *this;
59 }
60 
61 const char* TopicKeys::Error::what() const throw()
62 {
63  return message_.c_str();
64 }
65 
67  return node_;
68 }
69 
71  : parent_(0)
72  , pos_(0)
73  , child_(0)
74  , current_value_(0)
75  , root_(0)
77  , level_(0)
78  , recursive_(false)
79  , element_count_(0)
80  , implied_keys_(false)
81 {
82 }
83 
85  : parent_(0)
86  , pos_(0)
87  , child_(0)
88  , current_value_(0)
89  , level_(0)
90  , recursive_(parent.recursive())
91  , element_count_(0)
92  , implied_keys_(false)
93 {
94  root_ = parent.root();
95  root_type_ = parent.root_type();
96  ++*this;
97 }
98 
100  : parent_(parent)
101  , pos_(0)
102  , child_(0)
103  , current_value_(0)
104  , level_(parent->level() + 1)
105  , recursive_(parent->recursive_)
106  , element_count_(0)
107  , implied_keys_(false)
108 {
110  root_ = root;
111  ++(*this);
112 }
113 
115  : parent_(parent)
116  , pos_(0)
117  , child_(0)
118  , current_value_(0)
119  , level_(parent->level() + 1)
120  , recursive_(parent->recursive_)
121  , element_count_(0)
122  , implied_keys_(false)
123 {
124  AST_Type* type = root->field_type()->unaliased_type();
126  if (root_type_ == PrimitiveType) {
127  root_ = root;
128  } else {
129  root_ = type;
130  }
131  ++(*this);
132 }
133 
135  : pos_(0)
136  , child_(0)
137  , current_value_(0)
138  , root_(0)
140  , level_(0)
141  , recursive_(false)
142  , element_count_(0)
143  , implied_keys_(false)
144 {
145  *this = other;
146 }
147 
149 {
150  cleanup();
151 }
152 
154 {
155  cleanup();
156  parent_ = other.parent_;
157  pos_ = other.pos_;
159  root_ = other.root_;
160  root_type_ = other.root_type_;
161  level_ = other.level_;
162  recursive_ = other.recursive_;
163  dimensions_ = other.dimensions_;
164  child_ = other.child_ ? new Iterator(*other.child_) : 0;
166  return *this;
167 }
168 
170 {
171  // Nop if we are a invalid iterator of any type
172  if (!root_ || root_type_ == InvalidType) {
173  return *this;
174  }
175 
176  // If we have a child iterator, ask it for the next value
177  if (child_) {
178  Iterator& child = *child_;
179  ++child;
180  if (child == end_value()) {
181  delete child_;
182  child_ = 0;
183  pos_++;
184  } else {
186  return *this;
187  }
188  }
189 
190  if (root_type_ == StructureType) {
191  // If we are recursive and at a structure, look for key fields
192  if (recursive_ || level_ == 0) {
193  AST_Structure* struct_root = dynamic_cast<AST_Structure*>(root_);
194  if (!struct_root) {
195  throw Error(root_, "Invalid Key Iterator");
196  }
197  const Fields fields(struct_root);
198  const Fields::Iterator fields_end = fields.end();
199 
200  // If a nested struct marked as a key has no keys, all the fields are
201  // implied to be keys (expect those marked with @key(FALSE)).
202  if (pos_ == 0) {
203  if (level_ > 0) {
204  implied_keys_ = true;
205  for (Fields::Iterator i = fields.begin(); i != fields_end && implied_keys_; ++i) {
206  bool key_annotation_value;
207  const bool has_key_annotation = be_global->check_key(*i, key_annotation_value);
208  if (has_key_annotation && key_annotation_value) {
209  implied_keys_ = false;
210  }
211  }
212  } else {
213  implied_keys_ = false;
214  }
215  }
216 
217  for (Fields::Iterator i = fields[pos_]; i != fields_end; ++i) {
218  bool key_annotation_value;
219  const bool has_key_annotation = be_global->check_key(*i, key_annotation_value);
220  const bool implied_key = implied_keys_ && !(has_key_annotation && !key_annotation_value);
221  if (key_annotation_value || implied_key) {
222  child_ = new Iterator(*i, this);
223  Iterator& child = *child_;
224  if (child == end_value()) {
225  delete child_;
226  child_ = 0;
227  throw Error(*i, std::string("field is ") + (implied_key ? "implicitly" : "explicitly") +
228  " marked as key, but does not contain any keys.");
229  } else {
231  pos_ = i.pos();
232  return *this;
233  }
234  }
235  }
236  } else if (pos_ == 0) { // Else return "this" once
237  pos_ = 1;
239  return *this;
240  }
241 
242  // If we are an array, use the base type and repeat for every element
243  } else if (root_type_ == ArrayType) {
244  AST_Array* array_node = dynamic_cast<AST_Array*>(root_);
245  if (!array_node) {
246  throw Error(root_, "Invalid Key Iterator");
247  }
248  if (element_count_ == 0) {
249  element_count_ = 1;
250  ACE_CDR::ULong array_dimension_count = array_node->n_dims();
251  for (unsigned i = 0; i < array_dimension_count; i++) {
252  ACE_CDR::ULong dimension = array_node->dims()[i]->ev()->u.ulval;
253  dimensions_.push_back(dimension);
254  element_count_ *= dimension;
255  }
256  }
257  AST_Type* type_node = array_node->base_type();
258  AST_Type* unaliased_type_node = type_node->unaliased_type();
259  if (pos_ < element_count_) {
260  child_ = new Iterator(unaliased_type_node, this);
261  Iterator& child = *child_;
262  if (child == Iterator()) {
263  delete child_;
264  child_ = 0;
265  throw Error(array_node, "array type is marked as key, but its base type "
266  "does not contain any keys.");
267  }
269  return *this;
270  }
271 
272  // If we are a union, use self if we have a key
273  } else if (root_type_ == UnionType) {
274  if (pos_ == 0) { // Only Allow One Iteration
275  pos_ = 1;
276  AST_Union* union_node = dynamic_cast<AST_Union*>(root_);
277  if (level_ > 0 || be_global->union_discriminator_is_key(union_node)) {
279  return *this;
280  }
281  }
282 
283  } else if (root_type_ == SequenceType) {
284  throw Error(root_, "sequence types are not supported as keys");
285 
286  // If we are a primitive type, use self
287  } else if (root_type_ == PrimitiveType) {
288  if (pos_ == 0) { // Only Allow One Iteration
289  pos_ = 1;
291  return *this;
292  }
293  }
294 
295  // Nothing left to do, set this to null
296  *this = end_value();
297 
298  return *this;
299 }
300 
302 {
303  Iterator prev(*this);
304  ++(*this);
305  return prev;
306 }
307 
309 {
310  return current_value_;
311 }
312 
314 {
315  return
316  parent_ == other.parent_ &&
317  root_ == other.root_ &&
318  root_type_ == other.root_type_ &&
319  pos_ == other.pos_ &&
320  current_value_ == other.current_value_ &&
321  level_ == other.level_ &&
322  recursive_ == other.recursive_ &&
323  dimensions_ == other.dimensions_ &&
324  element_count_ == other.element_count_ &&
325  (
326  (child_ && other.child_) ? *child_ == *other.child_ : child_ == other.child_
327  );
328 }
329 
331 {
332  return !(*this == other);
333 }
334 
336 {
337  std::stringstream ss;
338  path_i(ss);
339  return ss.str();
340 }
341 
343 {
344  std::stringstream ss;
345  path_i(ss, true);
346  return ss.str();
347 }
348 
349 void TopicKeys::Iterator::path_i(std::stringstream& ss, bool canonical)
350 {
351  const char* error_msg = "Can't get path for invalid topic key iterator!";
352  if (root_type_ == StructureType) {
353  AST_Structure* struct_root = dynamic_cast<AST_Structure*>(root_);
354  if (!struct_root) {
355  throw Error(root_, error_msg);
356  }
357  AST_Field* field = *Fields(struct_root)[child_ ? pos_ : pos_ - 1];
358  ss << (level_ ? "." : "");
359  if (canonical) {
360  ss << canonical_name(field);
361  } else {
362  ss << field->local_name()->get_string();
363  }
364  } else if (root_type_ == UnionType) {
365  // Nothing
366  } else if (root_type_ == ArrayType) {
367  // Figure out what the vector version of the scalar pos_ is
368  std::vector<size_t>::reverse_iterator di, dfinished = dimensions_.rend();
369  size_t acc = pos_;
370  size_t div = 1;
371  std::vector<size_t> results;
372  for (di = dimensions_.rbegin(); di != dfinished; ++di) {
373  acc /= div;
374  results.push_back(acc % *di);
375  div = *di;
376  }
377 
378  std::vector<size_t>::reverse_iterator
379  ri = results.rbegin(),
380  rfinished = results.rend();
381  for (; ri != rfinished; ++ri) {
382  ss << '[' << *ri << ']';
383  }
384  } else if (root_type_ != PrimitiveType) {
385  throw Error(root_, error_msg);
386  }
387  if (child_ && recursive_) {
388  child_->path_i(ss, canonical);
389  }
390 }
391 
393 {
394  delete child_;
395 }
396 
398 {
399  return child_ ? child_->root_type() : root_type_;
400 }
401 
403 {
405 }
406 
408 {
409  return child_ ? child_->level() : level_;
410 }
411 
413 {
414  AST_Field* field = 0;
415  switch (root_type()) {
416  case UnionType:
417  return dynamic_cast<AST_Type*>(current_value_);
418  case StructureType:
419  if (level_ > 0) {
420  if (!recursive_) {
421  return dynamic_cast<AST_Type*>(current_value_);
422  }
423  } else {
424  return child_->get_ast_type();
425  }
426  break;
427  default:
428  break;
429  }
430  switch (parents_root_type()) {
431  case StructureType:
432  field = dynamic_cast<AST_Field*>(current_value_);
433  if (field) {
434  return field->field_type();
435  }
436  break;
437  case ArrayType:
438  return dynamic_cast<AST_Type*>(current_value_);
439  case SequenceType:
440  return dynamic_cast<AST_Type*>(current_value_);
441  default:
442  break;
443  }
444  return 0;
445 }
446 
448  : root_(0),
450  counted_(false),
451  count_(0),
452  recursive_(false)
453 {
454 }
455 
457 {
458  *this = other;
459 }
460 
461 TopicKeys::TopicKeys(AST_Structure* root, bool recursive)
462  : root_(root),
464  counted_(false),
465  count_(0),
466  recursive_(recursive)
467 {
468  root_ = root;
469 }
470 
472  : root_(root),
474  counted_(false),
475  count_(0),
476  recursive_(false)
477 {
478  root_ = root;
479 }
480 
482 {
483 }
484 
486 {
487  root_ = other.root_;
488  root_type_ = other.root_type_;
489  counted_ = other.counted_;
490  count_ = other.count_;
491  recursive_ = other.recursive_;
492  return *this;
493 }
494 
496 {
497  return Iterator(*this);
498 }
499 
501 {
502  return Iterator::end_value();
503 }
504 
505 AST_Decl* TopicKeys::root() const
506 {
507  return root_;
508 }
509 
511 {
512  return root_type_;
513 }
514 
516 {
517  if (!counted_) {
518  count_ = 0;
519  Iterator finished = end();
520  for (Iterator i = begin(); i != finished; ++i) {
521  count_++;
522  }
523  counted_ = true;
524  }
525  return count_;
526 }
527 
529 {
530  return recursive_;
531 }
532 
534 {
535  static Iterator end;
536  return end;
537 }
RootType root_type() const
Definition: topic_keys.cpp:397
AST_Decl * node_
Definition: topic_keys.h:64
Iterator end()
Definition: topic_keys.cpp:500
size_t element_count_
Element Count in the Array.
Definition: topic_keys.h:157
bool operator==(const Iterator &other) const
Definition: topic_keys.cpp:313
Iterator & operator++()
Definition: topic_keys.cpp:169
Iterator begin() const
size_t level() const
Definition: topic_keys.cpp:407
static RootType root_type(AST_Type *type)
Definition: topic_keys.cpp:15
virtual const char * what() const
Definition: topic_keys.cpp:61
std::string path()
Definition: topic_keys.cpp:335
AST_Decl * current_value_
Current value of the entire iterator stack.
Definition: topic_keys.h:149
Iterator & operator=(const Iterator &other)
Definition: topic_keys.cpp:153
AST_Decl * operator*() const
Definition: topic_keys.cpp:308
static FilterEvaluator::AstNodeWrapper child(const FilterEvaluator::AstNodeWrapper &node, size_t idx)
RootType root_type_
Definition: topic_keys.h:195
bool operator!=(const Iterator &other) const
Definition: topic_keys.cpp:330
AST_Type * get_ast_type() const
Definition: topic_keys.cpp:412
bool implied_keys_
Used in struct field key iteration.
Definition: topic_keys.h:160
std::string canonical_name(UTL_ScopedName *sn)
AST_Decl * root_
Definition: topic_keys.h:194
Iterator end() const
static Iterator end_value()
Definition: topic_keys.cpp:533
size_t count()
Definition: topic_keys.cpp:515
size_t count_
Definition: topic_keys.h:200
Iterator * parent_
Definition: topic_keys.h:145
RootType parents_root_type() const
Definition: topic_keys.cpp:402
ACE_UINT32 ULong
std::string message_
Definition: topic_keys.h:65
std::vector< size_t > dimensions_
The Dimensions of the Array.
Definition: topic_keys.h:155
void path_i(std::stringstream &ss, bool canonical=false)
Definition: topic_keys.cpp:349
Error & operator=(const Error &error)
Definition: topic_keys.cpp:54
virtual ~Error()
Definition: topic_keys.cpp:50
std::string canonical_path()
Definition: topic_keys.cpp:342
bool recursive() const
Definition: topic_keys.cpp:528
AST_Decl * node()
Definition: topic_keys.cpp:66
AST_Decl * root() const
Definition: topic_keys.cpp:505
Iterator begin()
Definition: topic_keys.cpp:495
BE_GlobalData * be_global
Definition: be_global.cpp:44
bool recursive_
}
Definition: topic_keys.h:204
Iterator * child_
Definition: topic_keys.h:147
AST_Decl * root_
Definition: topic_keys.h:150
bool counted_
Definition: topic_keys.h:199
TopicKeys & operator=(const TopicKeys &other)
Definition: topic_keys.cpp:485
RootType root_type() const
Definition: topic_keys.cpp:510