Locator.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. // Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @file Locator.h
  16. */
  17. #ifndef _FASTDDS_RTPS_ELEM_LOCATOR_H_
  18. #define _FASTDDS_RTPS_ELEM_LOCATOR_H_
  19. #include <fastrtps/fastrtps_dll.h>
  20. #include <fastdds/rtps/common/Types.h>
  21. #include <sstream>
  22. #include <vector>
  23. #include <cstdint>
  24. #include <cstring>
  25. #include <iomanip>
  26. #include <algorithm>
  27. namespace eprosima {
  28. namespace fastrtps {
  29. namespace rtps {
  30. #define LOCATOR_INVALID(loc) {loc.kind=LOCATOR_KIND_INVALID;loc.port= LOCATOR_PORT_INVALID;LOCATOR_ADDRESS_INVALID(loc.address);}
  31. #define LOCATOR_KIND_INVALID -1
  32. #define LOCATOR_ADDRESS_INVALID(a) {std::memset(a,0x00,16*sizeof(octet));}
  33. #define LOCATOR_PORT_INVALID 0
  34. #define LOCATOR_KIND_RESERVED 0
  35. #define LOCATOR_KIND_UDPv4 1
  36. #define LOCATOR_KIND_UDPv6 2
  37. #define LOCATOR_KIND_TCPv4 4
  38. #define LOCATOR_KIND_TCPv6 8
  39. #define LOCATOR_KIND_SHM 16
  40. //!@brief Class Locator_t, uniquely identifies a communication channel for a particular transport.
  41. //For example, an address+port combination in the case of UDP.
  42. //!@ingroup COMMON_MODULE
  43. class RTPS_DllAPI Locator_t
  44. {
  45. public:
  46. /*!
  47. * @brief Specifies the locator type. Valid values are:
  48. * LOCATOR_KIND_UDPv4
  49. * LOCATOR_KIND_UDPv6
  50. * LOCATOR_KIND_TCPv4
  51. * LOCATOR_KIND_TCPv6
  52. * LOCATOR_KIND_SHM
  53. */
  54. int32_t kind;
  55. uint32_t port;
  56. octet address[16];
  57. //!Default constructor
  58. Locator_t()
  59. : kind(LOCATOR_KIND_UDPv4)
  60. {
  61. port = 0;
  62. LOCATOR_ADDRESS_INVALID(address);
  63. }
  64. //!Move constructor
  65. Locator_t(Locator_t&& loc)
  66. : kind(loc.kind)
  67. {
  68. port = loc.port;
  69. std::memcpy(address, loc.address, 16 * sizeof(octet));
  70. }
  71. //!Copy constructor
  72. Locator_t(const Locator_t& loc)
  73. : kind(loc.kind)
  74. {
  75. port = loc.port;
  76. std::memcpy(address, loc.address, 16 * sizeof(octet));
  77. }
  78. //!Port constructor
  79. Locator_t(uint32_t portin)
  80. : kind(LOCATOR_KIND_UDPv4)
  81. {
  82. port = portin;
  83. LOCATOR_ADDRESS_INVALID(address);
  84. }
  85. //!Kind and port constructor
  86. Locator_t(
  87. int32_t kindin,
  88. uint32_t portin)
  89. : kind(kindin)
  90. {
  91. port = portin;
  92. LOCATOR_ADDRESS_INVALID(address);
  93. }
  94. Locator_t& operator=(const Locator_t& loc)
  95. {
  96. kind = loc.kind;
  97. port = loc.port;
  98. std::memcpy(address, loc.address, 16 * sizeof(octet));
  99. return *this;
  100. }
  101. bool set_address(const Locator_t &other)
  102. {
  103. memcpy(address, other.address, sizeof(octet) * 16);
  104. return true;
  105. }
  106. octet* get_address()
  107. {
  108. return address;
  109. }
  110. octet get_address(uint16_t field) const
  111. {
  112. return address[field];
  113. }
  114. void set_Invalid_Address()
  115. {
  116. LOCATOR_ADDRESS_INVALID(address);
  117. }
  118. };
  119. inline bool IsAddressDefined(const Locator_t& loc)
  120. {
  121. if (loc.kind == LOCATOR_KIND_UDPv4 || loc.kind == LOCATOR_KIND_TCPv4) // WAN addr in TCPv4 is optional, isn't?
  122. {
  123. for (uint8_t i = 12; i < 16; ++i)
  124. {
  125. if (loc.address[i] != 0)
  126. return true;
  127. }
  128. }
  129. else if (loc.kind == LOCATOR_KIND_UDPv6 || loc.kind == LOCATOR_KIND_TCPv6)
  130. {
  131. for (uint8_t i = 0; i < 16; ++i)
  132. {
  133. if (loc.address[i] != 0)
  134. return true;
  135. }
  136. }
  137. return false;
  138. }
  139. inline bool IsLocatorValid(const Locator_t&loc)
  140. {
  141. return (0 <= loc.kind);
  142. }
  143. inline bool operator<(const Locator_t &loc1, const Locator_t &loc2)
  144. {
  145. return memcmp(&loc1, &loc2, sizeof(Locator_t)) < 0;
  146. }
  147. inline bool operator==(const Locator_t&loc1, const Locator_t& loc2)
  148. {
  149. if (loc1.kind != loc2.kind)
  150. return false;
  151. if (loc1.port != loc2.port)
  152. return false;
  153. if (!std::equal(loc1.address, loc1.address + 16, loc2.address))
  154. return false;
  155. return true;
  156. }
  157. inline bool operator!=(const Locator_t&loc1, const Locator_t& loc2)
  158. {
  159. return !(loc1 == loc2);
  160. }
  161. inline std::ostream& operator<<(std::ostream& output, const Locator_t& loc)
  162. {
  163. if (loc.kind == LOCATOR_KIND_UDPv4 || loc.kind == LOCATOR_KIND_TCPv4)
  164. {
  165. output << (int)loc.address[12] << "." << (int)loc.address[13]
  166. << "." << (int)loc.address[14] << "." << (int)loc.address[15]
  167. << ":" << loc.port;
  168. }
  169. else if (loc.kind == LOCATOR_KIND_UDPv6 || loc.kind == LOCATOR_KIND_TCPv6)
  170. {
  171. for (uint8_t i = 0; i < 16; ++i)
  172. {
  173. output << (int)loc.address[i];
  174. if (i < 15)
  175. output << ".";
  176. }
  177. output << ":" << loc.port;
  178. }
  179. else if (loc.kind == LOCATOR_KIND_SHM)
  180. {
  181. if (loc.address[0] == 'M')
  182. {
  183. output << "SHM:M" << loc.port;
  184. }
  185. else
  186. {
  187. output << "SHM:" << loc.port;
  188. }
  189. }
  190. return output;
  191. }
  192. typedef std::vector<Locator_t>::iterator LocatorListIterator;
  193. typedef std::vector<Locator_t>::const_iterator LocatorListConstIterator;
  194. /**
  195. * Provides a Locator's iterator interface that can be used by different Locator's
  196. * containers
  197. */
  198. class LocatorsIterator
  199. {
  200. public:
  201. virtual LocatorsIterator& operator++() = 0;
  202. virtual bool operator==(
  203. const LocatorsIterator& other) const = 0;
  204. virtual bool operator!=(
  205. const LocatorsIterator& other) const = 0;
  206. virtual const Locator_t& operator*() const = 0;
  207. };
  208. /**
  209. * Adapter class that provides a LocatorsIterator interface from a LocatorListConstIterator
  210. */
  211. class Locators : public LocatorsIterator
  212. {
  213. public:
  214. Locators(
  215. const LocatorListConstIterator& it)
  216. : it_(it)
  217. {
  218. }
  219. Locators(
  220. const Locators& other)
  221. : it_(other.it_)
  222. {
  223. }
  224. LocatorsIterator& operator++()
  225. {
  226. ++it_;
  227. return *this;
  228. }
  229. bool operator==(
  230. const LocatorsIterator& other) const
  231. {
  232. return it_ == static_cast<const Locators&>(other).it_;
  233. }
  234. bool operator!=(
  235. const LocatorsIterator& other) const
  236. {
  237. return it_ != static_cast<const Locators&>(other).it_;
  238. }
  239. const Locator_t& operator*() const
  240. {
  241. return (*it_);
  242. }
  243. private:
  244. LocatorListConstIterator it_;
  245. };
  246. /**
  247. * Class LocatorList_t, a Locator_t vector that doesn't avoid duplicates.
  248. * @ingroup COMMON_MODULE
  249. */
  250. class LocatorList_t
  251. {
  252. public:
  253. RTPS_DllAPI LocatorList_t() {};
  254. RTPS_DllAPI ~LocatorList_t() {};
  255. RTPS_DllAPI LocatorList_t(const LocatorList_t& list) : m_locators(list.m_locators) {}
  256. RTPS_DllAPI LocatorList_t(LocatorList_t&& list) : m_locators(std::move(list.m_locators)) {}
  257. RTPS_DllAPI LocatorList_t& operator=(const LocatorList_t& list)
  258. {
  259. m_locators = list.m_locators;
  260. return *this;
  261. }
  262. RTPS_DllAPI LocatorList_t& operator=(LocatorList_t&& list)
  263. {
  264. m_locators = std::move(list.m_locators);
  265. return *this;
  266. }
  267. RTPS_DllAPI bool operator==(const LocatorList_t& locator_list) const
  268. {
  269. if (locator_list.m_locators.size() == m_locators.size())
  270. {
  271. bool returnedValue = true;
  272. for (auto it = locator_list.m_locators.begin(); returnedValue &&
  273. it != locator_list.m_locators.end(); ++it)
  274. {
  275. returnedValue = false;
  276. for (auto it2 = m_locators.begin(); !returnedValue && it2 != m_locators.end(); ++it2)
  277. {
  278. if (*it == *it2)
  279. returnedValue = true;
  280. }
  281. }
  282. return returnedValue;
  283. }
  284. return false;
  285. }
  286. RTPS_DllAPI LocatorListIterator begin() {
  287. return m_locators.begin();
  288. }
  289. RTPS_DllAPI LocatorListIterator end() {
  290. return m_locators.end();
  291. }
  292. RTPS_DllAPI LocatorListConstIterator begin() const {
  293. return m_locators.begin();
  294. }
  295. RTPS_DllAPI LocatorListConstIterator end() const {
  296. return m_locators.end();
  297. }
  298. RTPS_DllAPI size_t size() const {
  299. return m_locators.size();
  300. }
  301. RTPS_DllAPI LocatorList_t& assign(const LocatorList_t& list)
  302. {
  303. if (!(*this == list))
  304. {
  305. m_locators = list.m_locators;
  306. }
  307. return *this;
  308. }
  309. RTPS_DllAPI void clear(){ return m_locators.clear(); }
  310. RTPS_DllAPI void reserve(size_t num) { return m_locators.reserve(num); }
  311. RTPS_DllAPI void resize(size_t num) { return m_locators.resize(num); }
  312. RTPS_DllAPI void push_back(const Locator_t& loc)
  313. {
  314. bool already = false;
  315. for (LocatorListIterator it = this->begin(); it != this->end(); ++it)
  316. {
  317. if (loc == *it)
  318. {
  319. already = true;
  320. break;
  321. }
  322. }
  323. if (!already)
  324. m_locators.push_back(loc);
  325. }
  326. RTPS_DllAPI void push_back(const LocatorList_t& locList)
  327. {
  328. for (auto it = locList.m_locators.begin(); it != locList.m_locators.end(); ++it)
  329. {
  330. this->push_back(*it);
  331. }
  332. }
  333. RTPS_DllAPI bool empty() const {
  334. return m_locators.empty();
  335. }
  336. RTPS_DllAPI void erase(const Locator_t& loc)
  337. {
  338. auto it = std::find(m_locators.begin(), m_locators.end(), loc);
  339. if (it != m_locators.end())
  340. {
  341. m_locators.erase(it);
  342. }
  343. }
  344. RTPS_DllAPI bool contains(const Locator_t& loc)
  345. {
  346. for (LocatorListIterator it = this->begin(); it != this->end(); ++it)
  347. {
  348. if (IsAddressDefined(*it))
  349. {
  350. if (loc == *it)
  351. return true;
  352. }
  353. else
  354. {
  355. if (loc.kind == (*it).kind && loc.port == (*it).port)
  356. return true;
  357. }
  358. }
  359. return false;
  360. }
  361. RTPS_DllAPI bool isValid() const
  362. {
  363. for (LocatorListConstIterator it = this->begin(); it != this->end(); ++it)
  364. {
  365. if (!IsLocatorValid(*it))
  366. return false;
  367. }
  368. return true;
  369. }
  370. RTPS_DllAPI void swap(LocatorList_t& locatorList)
  371. {
  372. this->m_locators.swap(locatorList.m_locators);
  373. }
  374. friend std::ostream& operator <<(std::ostream& output, const LocatorList_t& loc);
  375. private:
  376. std::vector<Locator_t> m_locators;
  377. };
  378. inline std::ostream& operator<<(std::ostream& output, const LocatorList_t& locList)
  379. {
  380. for (auto it = locList.m_locators.begin(); it != locList.m_locators.end(); ++it)
  381. {
  382. output << *it << ",";
  383. }
  384. return output;
  385. }
  386. }
  387. }
  388. }
  389. #endif /* _FASTDDS_RTPS_ELEM_LOCATOR_H_ */