RTI Routing Service  Version 6.0.1
 All Data Structures Files Functions Typedefs Enumerations Enumerator Groups Pages
EntityId.hpp
1 /*
2  * (c) Copyright, Real-Time Innovations, 2017-.
3  * All rights reserved.
4  * No duplications, whole or partial, manual or electronic, may be made
5  * without express written permission. Any such copies, or
6  * revisions thereof, must display this notice unaltered.
7  * This code contains trade secrets of Real-Time Innovations, Inc.
8  *
9  */
10 
11 #ifndef HPP_SERVICE_ENTITY_ID_HPP_
12 #define HPP_SERVICE_ENTITY_ID_HPP_
13 
14 #include "rtixmlutils/rtixmlutils_object.h"
15 
16 #include <rti/service/log/LogConfig.hpp>
17 
18 namespace rti { namespace service {
19 
20 class EntityFullNameIterator {
21 public:
22 
23  EntityFullNameIterator(const std::string& full_name)
24  : full_name_(full_name), substring_pos_(0), next_substring_pos_(0)
25  {
26  next();
27  }
28 
29  ~EntityFullNameIterator()
30  {
31  }
32 
33  bool is_end() const
34  {
35  return substring_pos_ == full_name_.length();
36  }
37 
38  EntityFullNameIterator& end()
39  {
40  substring_pos_ = full_name_.length();
41  next_substring_pos_ = substring_pos_;
42 
43  return *this;
44  }
45 
46  EntityFullNameIterator& last()
47  {
48  next_substring_pos_ = full_name_.length();
49  substring_pos_ = next_substring_pos_;
50 
51  for (; substring_pos_ > 0; --substring_pos_) {
52  if (full_name_[substring_pos_] == '\"') {
53  size_t opening_quotes = full_name_.rfind(
54  "\"",
55  substring_pos_ - 1);
56  if (opening_quotes == std::string::npos) {
57  SERVICELog_warn(
58  &RTI_LOG_ANY_s,
59  "detected unbalanced escaped name. Missing closing '\"'?");
60  } else {
61  // skip all characters in escaped name
62  substring_pos_ = opening_quotes;
63  }
64  } else if (full_name_.find(
65  RTIXMLUTILS_OBJECT_NAME_SEPARATOR,
66  substring_pos_) == substring_pos_) {
67  substring_pos_ += strlen(RTIXMLUTILS_OBJECT_NAME_SEPARATOR);
68  break;
69  }
70  }
71 
72  return *this;
73  }
74 
75  std::string parent()
76  {
77  size_t parent_length = (substring_pos_ == 0)
78  ? 0
79  : substring_pos_ - strlen(RTIXMLUTILS_OBJECT_NAME_SEPARATOR);
80  return full_name_.substr(0, parent_length);
81  }
82 
83  std::string operator*() const
84  {
85  size_t substring_pos = substring_pos_;
86  size_t name_length = next_substring_pos_ - substring_pos_;
87  if (name_length > 1
88  && full_name_[substring_pos_ + name_length - 1] == '\"'
89  && full_name_[substring_pos_] == '\"') {
90  name_length -= 2;
91  ++substring_pos;
92 
93  }
94  return full_name_.substr(substring_pos, name_length);
95  }
96 
97  EntityFullNameIterator& operator++()
98  {
99  next();
100  return *this;
101  }
102 
103  std::string escaped()
104  {
105  size_t substring_pos = substring_pos_;
106  size_t name_length = next_substring_pos_ - substring_pos_;
107 
108  return full_name_.substr(substring_pos, name_length);
109  }
110 
111  friend bool operator==(
112  const EntityFullNameIterator &s1,
113  const EntityFullNameIterator &s2)
114  {
115  return s1.substring_pos_ == s2.substring_pos_
116  && s1.next_substring_pos_ == s2.next_substring_pos_
117  && s1.full_name_.c_str() == s2.full_name_.c_str();
118  }
119 
120  friend bool operator!=(
121  const EntityFullNameIterator &s1,
122  const EntityFullNameIterator &s2)
123  {
124  return !(s1 == s2);
125  }
126 
127 
128 private:
129 
130  void next()
131  {
132  if (full_name_.find(
133  RTIXMLUTILS_OBJECT_NAME_SEPARATOR,
134  next_substring_pos_) == next_substring_pos_) {
135  next_substring_pos_ += strlen(RTIXMLUTILS_OBJECT_NAME_SEPARATOR);
136  }
137 
138  substring_pos_ = next_substring_pos_;
139 
140  for (; next_substring_pos_ < full_name_.length(); ++next_substring_pos_) {
141  if (full_name_[next_substring_pos_] == '\"') {
142  size_t closing_quotes = full_name_.find(
143  "\"",
144  next_substring_pos_ + 1);
145  if (closing_quotes == std::string::npos) {
146  SERVICELog_warn(
147  &RTI_LOG_ANY_s,
148  "detected unbalanced escaped name. Missing closing '\"'?");
149  } else {
150  // skip all characters in escaped name
151  next_substring_pos_ = closing_quotes;
152  }
153  } else if (full_name_.find(
154  RTIXMLUTILS_OBJECT_NAME_SEPARATOR,
155  next_substring_pos_) == next_substring_pos_) {
156  break;
157  }
158  }
159  }
160 
161 private:
162  const std::string& full_name_;
163  size_t substring_pos_;
164  size_t next_substring_pos_;
165 };
166 
167 template<typename ENTITY_KIND_TYPE>
168 class EntityId {
169 public:
170  typedef EntityFullNameIterator name_iterator;
171 
172 public:
173 
174  EntityId(const std::string& the_full_name, ENTITY_KIND_TYPE the_kind)
175  : full_name_(the_full_name), kind_(the_kind)
176  {
177  }
178 
179  bool is_nil() const
180  {
181  return kind_ == ENTITY_KIND_TYPE::count_;
182  }
183 
184  name_iterator begin() const
185  {
186  return EntityFullNameIterator(full_name_);
187  }
188 
189  name_iterator end() const
190  {
191  return EntityFullNameIterator(full_name_).end();
192  }
193 
194  const std::string& full_name() const
195  {
196  return full_name_;
197  }
198 
199  const std::string name() const
200  {
201  return (*EntityFullNameIterator(full_name_).last());
202  }
203 
204  const std::string parent_name() const
205  {
206  return EntityFullNameIterator(full_name_).last().parent();
207  }
208 
209  const ENTITY_KIND_TYPE& kind() const
210  {
211  return kind_;
212  }
213 
214  static EntityId<ENTITY_KIND_TYPE> nil()
215  {
216  static EntityId<ENTITY_KIND_TYPE> nil(
217  "",
218  ENTITY_KIND_TYPE::count_);
219 
220  return nil;
221  }
222 
223  friend bool operator==(
224  const EntityId<ENTITY_KIND_TYPE>& left,
225  const EntityId<ENTITY_KIND_TYPE>& right)
226  {
227  return left.kind_ == right.kind_
228  && left.full_name_ == right.full_name_;
229  }
230 
231 private:
232  std::string full_name_;
233  ENTITY_KIND_TYPE kind_;
234 };
235 
236 } } /* namespace rti::rservice */
237 
238 
239 #endif //HPP_SERVICE_ENTITY_ID_HPP_
240 

RTI Routing Service Version 6.0.1 Copyright © Sun Nov 17 2019 Real-Time Innovations, Inc