string_collection.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /////////////////////////////////////////////////////////////////////////////
  2. /// @file string_collection.h
  3. /// Definition of the string_collection class for the Paho MQTT C++ library.
  4. /// @date April 23, 2017
  5. /// @author Frank Pagliughi
  6. /////////////////////////////////////////////////////////////////////////////
  7. /*******************************************************************************
  8. * Copyright (c) 2017-2024 Frank Pagliughi <fpagliughi@mindspring.com>
  9. *
  10. * All rights reserved. This program and the accompanying materials
  11. * are made available under the terms of the Eclipse Public License v2.0
  12. * and Eclipse Distribution License v1.0 which accompany this distribution.
  13. *
  14. * The Eclipse Public License is available at
  15. * http://www.eclipse.org/legal/epl-v20.html
  16. * and the Eclipse Distribution License is available at
  17. * http://www.eclipse.org/org/documents/edl-v10.php.
  18. *
  19. * Contributors:
  20. * Frank Pagliughi - initial implementation and documentation
  21. *******************************************************************************/
  22. #ifndef __mqtt_string_collection_h
  23. #define __mqtt_string_collection_h
  24. #include <map>
  25. #include <memory>
  26. #include <vector>
  27. #include "MQTTAsync.h"
  28. #include "mqtt/types.h"
  29. namespace mqtt {
  30. /////////////////////////////////////////////////////////////////////////////
  31. /**
  32. * Type for a collection of strings, such as MQTT topics.
  33. *
  34. * This acts like a standard collection of strings but carries an array of
  35. * pointers to the C strings for easy interactions with the Paho C library.
  36. */
  37. class string_collection
  38. {
  39. public:
  40. /** The type for the collection of strings */
  41. using collection_type = std::vector<string>;
  42. /** Iterator over const items */
  43. using const_iterator = collection_type::const_iterator;
  44. /** Smart/shared pointer to an object of this type */
  45. using ptr_t = std::shared_ptr<string_collection>;
  46. /** Smart/shared pointer to a const object of this type */
  47. using const_ptr_t = std::shared_ptr<const string_collection>;
  48. private:
  49. /** The type for the array of C pointers */
  50. using c_arr_type = std::vector<const char*>;
  51. /**
  52. * The collection of strings.
  53. */
  54. collection_type coll_;
  55. /**
  56. * A collection of pointers to NUL-terminated C strings.
  57. * This is what is required by the Paho C library, and thus the lifetime
  58. * of the pointers will remain consistent with the lifetime of the
  59. * object. The value is kept consistent with the current stringss and
  60. * updated whenever strings are added or removed.
  61. */
  62. c_arr_type cArr_;
  63. /**
  64. * Updated the cArr_ object to agree with the values in coll_
  65. * This should be called any time the coll_ variable is modified
  66. * <i>in any way</i>.
  67. */
  68. void update_c_arr();
  69. public:
  70. /**
  71. * Construct an empty string collection.
  72. */
  73. string_collection() = default;
  74. /**
  75. * Construct a collection initially containing a single string.
  76. * @param str The string
  77. */
  78. string_collection(const string& str);
  79. /**
  80. * Construct a collection initially containing a single string.
  81. * @param str The string
  82. */
  83. string_collection(string&& str);
  84. /**
  85. * Constructs a string collection by copying a vector of strings.
  86. * @param vec A vector of strings.
  87. */
  88. string_collection(const collection_type& vec);
  89. /**
  90. * Constructs a string collection by moving a vector of strings.
  91. * @param vec A vector of strings.
  92. */
  93. string_collection(collection_type&& vec);
  94. /**
  95. * Copy constructor.
  96. * @param coll An existing string collection.
  97. */
  98. string_collection(const string_collection& coll);
  99. /**
  100. * Move constructor.
  101. * @param coll An existing string collection.
  102. */
  103. string_collection(string_collection&& coll) = default;
  104. /**
  105. * Construct a string collection from an initialization list of strings.
  106. * @param sl An initialization list of strings.
  107. */
  108. string_collection(std::initializer_list<string> sl);
  109. /**
  110. * Construct a string collection from an initialization list of C string
  111. * pointers.
  112. * @param sl An initialization list of C character arrays.
  113. */
  114. string_collection(std::initializer_list<const char*> sl);
  115. /**
  116. * Create an empty string collection on the heap.
  117. * @return A smart/shared pointer to a string collection.
  118. */
  119. static ptr_t create(const string& str) {
  120. return std::make_shared<string_collection>(str);
  121. }
  122. /**
  123. * Create a string collection on the heap, initially containing a single
  124. * string.
  125. * @param str The string
  126. * @return A smart/shared pointer to a string collection.
  127. */
  128. static ptr_t create(string&& str) { return std::make_shared<string_collection>(str); }
  129. /**
  130. * Creates a string collection on the heap by copying a vector of
  131. * strings.
  132. * @param vec A vector of strings.
  133. */
  134. static ptr_t create(const collection_type& vec) {
  135. return std::make_shared<string_collection>(vec);
  136. }
  137. /**
  138. * Creates a string collection on the heap by copying a vector of
  139. * strings.
  140. * @param vec A vector of strings.
  141. * @return A smart/shared pointer to a string collection.
  142. */
  143. static ptr_t create(collection_type&& vec) {
  144. return std::make_shared<string_collection>(vec);
  145. }
  146. /**
  147. * Create a string collection on the heap from an initialization list of
  148. * strings.
  149. * @param sl An initialization list of strings.
  150. * @return A smart/shared pointer to a string collection.
  151. */
  152. static ptr_t create(std::initializer_list<string> sl) {
  153. return std::make_shared<string_collection>(sl);
  154. }
  155. /**
  156. * Create a string collection on the heap from an initialization list of
  157. * C string pointers.
  158. * @param sl An initialization list of C character arrays.
  159. * @return A smart/shared pointer to a string collection.
  160. */
  161. static ptr_t create(std::initializer_list<const char*> sl) {
  162. return std::make_shared<string_collection>(sl);
  163. }
  164. /**
  165. * Copy assignment.
  166. * Copy another string collection to this one.
  167. * @param coll A string collection
  168. * @return A reference to this collection.
  169. */
  170. string_collection& operator=(const string_collection& coll);
  171. /**
  172. * Move assignment.
  173. * Move another string collection to this one.
  174. * @param coll A string collection
  175. * @return A reference to this collection.
  176. */
  177. string_collection& operator=(string_collection&& coll) = default;
  178. /**
  179. * Gets a const iterator to the beginning of the collection.
  180. * @return A const iterator to the beginning of the collection.
  181. */
  182. const_iterator begin() const { return coll_.begin(); }
  183. /**
  184. * Gets a const iterator to the end of the collection.
  185. * @return A const iterator to the end of the collection.
  186. */
  187. const_iterator end() const { return coll_.end(); }
  188. /**
  189. * Gets a const iterator to the beginning of the collection.
  190. * @return A const iterator to the beginning of the collection.
  191. */
  192. const_iterator cbegin() const { return coll_.cbegin(); }
  193. /**
  194. * Gets a const iterator to the end of the collection.
  195. * @return A const iterator to the end of the collection.
  196. */
  197. const_iterator cend() const { return coll_.cend(); }
  198. /**
  199. * Determines if the collection is empty.
  200. * @return @em true if the collection is empty, @em false if not.
  201. */
  202. bool empty() const { return coll_.empty(); }
  203. /**
  204. * Gets the number of strings in the collection.
  205. * @return The number of strings in the collection.
  206. */
  207. size_t size() const { return coll_.size(); }
  208. /**
  209. * Copies a string onto the back of the collection.
  210. * @param str A string.
  211. */
  212. void push_back(const string& str);
  213. /**
  214. * Moves a string onto the back of the collection.
  215. * @param str A string.
  216. */
  217. void push_back(string&& str);
  218. /**
  219. * Removes all the strings from the collection.
  220. */
  221. void clear();
  222. /**
  223. * Gets the n'th string in the collection.
  224. * @param i Index to the desired string.
  225. * @return A const reference to the string.
  226. */
  227. const string& operator[](size_t i) const { return coll_[i]; }
  228. /**
  229. * Gets a pointer to an array of NUL-terminated C string pointers.
  230. * This is the collection type supported by the underlying Paho C
  231. * library. The returned pointer is guaranteed valid so long as the
  232. * object is not updated. The return value may change if the object is
  233. * modified, so the application should not cache the return value, but
  234. * rather request the value when needed.
  235. * @return pointer to an array of NUL-terminated C string pointers of
  236. * the C++ strings in the object.
  237. *
  238. */
  239. char* const* c_arr() const { return (char* const*)cArr_.data(); }
  240. };
  241. /////////////////////////////////////////////////////////////////////////////
  242. /** Smart/shared pointer to a string collection */
  243. using string_collection_ptr = string_collection::ptr_t;
  244. /** Smart/shared pointer to a const string_collection */
  245. using const_string_collection_ptr = string_collection::const_ptr_t;
  246. /////////////////////////////////////////////////////////////////////////////
  247. /**
  248. * A collection of name/value string pairs.
  249. */
  250. class name_value_collection
  251. {
  252. /** The type for the collection of name/value pairs */
  253. using collection_type = std::map<string, string>;
  254. /** The type for the C pointers to pass to Paho C */
  255. using c_arr_type = std::vector<MQTTAsync_nameValue>;
  256. /**
  257. * The name/value pairs.
  258. */
  259. collection_type map_;
  260. /**
  261. * A collection of pairs of NUL-terminated C strings.
  262. */
  263. c_arr_type cArr_;
  264. /**
  265. * Updated the cArr_ object to agree with the values in coll_
  266. * This should be called any time the coll_ variable is modified
  267. * <i>in any way</i>.
  268. */
  269. void update_c_arr();
  270. public:
  271. /** Smart/shared pointer to an object of this type */
  272. using ptr_t = std::shared_ptr<name_value_collection>;
  273. /** Smart/shared pointer to a const object of this type */
  274. using const_ptr_t = std::shared_ptr<const name_value_collection>;
  275. /** The type of the string/string pair of values */
  276. using value_type = collection_type::value_type;
  277. /**
  278. * Default constructor for an empty collection.
  279. */
  280. name_value_collection() = default;
  281. /**
  282. * Creates a name/value collection from an underlying STL collection.
  283. * @param map The collection of name/value pairs.
  284. */
  285. name_value_collection(const collection_type& map) : map_(map) { update_c_arr(); }
  286. /**
  287. * Creates a name/value collection from an underlying STL collection.
  288. * @param map The collection of name/value pairs.
  289. */
  290. name_value_collection(collection_type&& map) : map_(std::move(map)) { update_c_arr(); }
  291. /**
  292. * Copy constructor.
  293. * @param other Another collection of name/value pairs.
  294. */
  295. name_value_collection(const name_value_collection& other) : map_(other.map_) {
  296. update_c_arr();
  297. }
  298. /**
  299. * Move constructor.
  300. * @param other Another collection of name/value pairs
  301. */
  302. name_value_collection(name_value_collection&& other) = default;
  303. /**
  304. * Constructs the collection with an initializer list.
  305. *
  306. * This works identically to initializing a std::map<> with string/tring
  307. * pairs.
  308. *
  309. * @param init Initializer list to construct the members of the
  310. * collection.
  311. */
  312. name_value_collection(std::initializer_list<value_type> init) : map_{init} {
  313. update_c_arr();
  314. }
  315. /**
  316. * Copy assignment.
  317. * @param other Another collection of name/value pairs.
  318. */
  319. name_value_collection& operator=(const name_value_collection& other) {
  320. map_ = other.map_;
  321. update_c_arr();
  322. return *this;
  323. }
  324. /**
  325. * Move constructor.
  326. * @param other Another collection of name/value pairs
  327. */
  328. name_value_collection& operator=(name_value_collection&& other) = default;
  329. /**
  330. * Determines if the collection is empty.
  331. * @return @em true if the container is empty, @em false if it contains
  332. * one or more items.
  333. */
  334. bool empty() const { return map_.empty(); }
  335. /**
  336. * Gets the number of name/value pairs in the collection.
  337. * @return The number of name/value pairs in the collection.
  338. */
  339. size_t size() const { return map_.size(); }
  340. /**
  341. * Removes all items from the collection.
  342. */
  343. void clear() {
  344. map_.clear();
  345. update_c_arr();
  346. }
  347. /**
  348. * Inserts a name/value pair into the collection.
  349. * @param nvpair The name/value string pair.
  350. * @return @em true if the inert happened, @em false if not.
  351. */
  352. bool insert(const value_type& nvpair) {
  353. if (map_.insert(nvpair).second) {
  354. update_c_arr();
  355. return true;
  356. }
  357. return false;
  358. }
  359. /**
  360. * Gets a pointer to an array of NUL-terminated C string pointer pairs.
  361. * This is a collection type supported by the underlying Paho C
  362. * library. The returned pointer is guaranteed valid so long as the
  363. * object is not updated. The return value may change if the object is
  364. * modified, so the application should not cache the return value, but
  365. * rather request the value when needed.
  366. * @return pointer to an array of NUL-terminated C string pointer pairs
  367. * for name/values. The array is terminated by a NULL/NULL pair.
  368. */
  369. const MQTTAsync_nameValue* c_arr() const { return cArr_.data(); }
  370. };
  371. /////////////////////////////////////////////////////////////////////////////
  372. } // namespace mqtt
  373. #endif // __mqtt_string_collection_h