string_collection.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  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 "MQTTAsync.h"
  25. #include "mqtt/types.h"
  26. #include <vector>
  27. #include <map>
  28. #include <memory>
  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) {
  129. return std::make_shared<string_collection>(str);
  130. }
  131. /**
  132. * Creates a string collection on the heap by copying a vector of
  133. * strings.
  134. * @param vec A vector of strings.
  135. */
  136. static ptr_t create(const collection_type& vec) {
  137. return std::make_shared<string_collection>(vec);
  138. }
  139. /**
  140. * Creates a string collection on the heap by copying a vector of
  141. * strings.
  142. * @param vec A vector of strings.
  143. * @return A smart/shared pointer to a string collection.
  144. */
  145. static ptr_t create(collection_type&& vec) {
  146. return std::make_shared<string_collection>(vec);
  147. }
  148. /**
  149. * Create a string collection on the heap from an initialization list of
  150. * strings.
  151. * @param sl An initialization list of strings.
  152. * @return A smart/shared pointer to a string collection.
  153. */
  154. static ptr_t create(std::initializer_list<string> sl) {
  155. return std::make_shared<string_collection>(sl);
  156. }
  157. /**
  158. * Create a string collection on the heap from an initialization list of
  159. * C string pointers.
  160. * @param sl An initialization list of C character arrays.
  161. * @return A smart/shared pointer to a string collection.
  162. */
  163. static ptr_t create(std::initializer_list<const char*> sl) {
  164. return std::make_shared<string_collection>(sl);
  165. }
  166. /**
  167. * Copy assignment.
  168. * Copy another string collection to this one.
  169. * @param coll A string collection
  170. * @return A reference to this collection.
  171. */
  172. string_collection& operator=(const string_collection& coll);
  173. /**
  174. * Move assignment.
  175. * Move another string collection to this one.
  176. * @param coll A string collection
  177. * @return A reference to this collection.
  178. */
  179. string_collection& operator=(string_collection&& coll) =default;
  180. /**
  181. * Gets a const iterator to the beginning of the collection.
  182. * @return A const iterator to the beginning of the collection.
  183. */
  184. const_iterator begin() const { return coll_.begin(); }
  185. /**
  186. * Gets a const iterator to the end of the collection.
  187. * @return A const iterator to the end of the collection.
  188. */
  189. const_iterator end() const { return coll_.end(); }
  190. /**
  191. * Gets a const iterator to the beginning of the collection.
  192. * @return A const iterator to the beginning of the collection.
  193. */
  194. const_iterator cbegin() const { return coll_.cbegin(); }
  195. /**
  196. * Gets a const iterator to the end of the collection.
  197. * @return A const iterator to the end of the collection.
  198. */
  199. const_iterator cend() const { return coll_.cend(); }
  200. /**
  201. * Determines if the collection is empty.
  202. * @return @em true if the collection is empty, @em false if not.
  203. */
  204. bool empty() const { return coll_.empty(); }
  205. /**
  206. * Gets the number of strings in the collection.
  207. * @return The number of strings in the collection.
  208. */
  209. size_t size() const { return coll_.size(); }
  210. /**
  211. * Copies a string onto the back of the collection.
  212. * @param str A string.
  213. */
  214. void push_back(const string& str);
  215. /**
  216. * Moves a string onto the back of the collection.
  217. * @param str A string.
  218. */
  219. void push_back(string&& str);
  220. /**
  221. * Removes all the strings from the collection.
  222. */
  223. void clear();
  224. /**
  225. * Gets the n'th string in the collection.
  226. * @param i Index to the desired string.
  227. * @return A const reference to the string.
  228. */
  229. const string& operator[](size_t i) const { return coll_[i]; }
  230. /**
  231. * Gets a pointer to an array of NUL-terminated C string pointers.
  232. * This is the collection type supported by the underlying Paho C
  233. * library. The returned pointer is guaranteed valid so long as the
  234. * object is not updated. The return value may change if the object is
  235. * modified, so the application should not cache the return value, but
  236. * rather request the value when needed.
  237. * @return pointer to an array of NUL-terminated C string pointers of
  238. * the C++ strings in the object.
  239. *
  240. */
  241. char* const* c_arr() const { return (char* const *) cArr_.data(); }
  242. };
  243. /////////////////////////////////////////////////////////////////////////////
  244. /** Smart/shared pointer to a string collection */
  245. using string_collection_ptr = string_collection::ptr_t;
  246. /** Smart/shared pointer to a const string_collection */
  247. using const_string_collection_ptr = string_collection::const_ptr_t;
  248. /////////////////////////////////////////////////////////////////////////////
  249. /**
  250. * A colleciton of name/value string pairs.
  251. */
  252. class name_value_collection
  253. {
  254. /** The type for the collection of name/value pairs */
  255. using collection_type = std::map<string, string>;
  256. /** The type for the C pointers to pass to Paho C */
  257. using c_arr_type = std::vector<MQTTAsync_nameValue>;
  258. /**
  259. * The name/value pairs.
  260. */
  261. collection_type map_;
  262. /**
  263. * A collection of pairs of NUL-terminated C strings.
  264. */
  265. c_arr_type cArr_;
  266. /**
  267. * Updated the cArr_ object to agree with the values in coll_
  268. * This should be called any time the coll_ variable is modified
  269. * <i>in any way</i>.
  270. */
  271. void update_c_arr();
  272. public:
  273. /** Smart/shared pointer to an object of this type */
  274. using ptr_t = std::shared_ptr<name_value_collection>;
  275. /** Smart/shared pointer to a const object of this type */
  276. using const_ptr_t = std::shared_ptr<const name_value_collection>;
  277. /** The type of the string/string pair of values */
  278. using value_type = collection_type::value_type;
  279. /**
  280. * Default constructor for an empty collection.
  281. */
  282. name_value_collection() =default;
  283. /**
  284. * Creates a name/value collection from an underlying STL collection.
  285. * @param map The collection of name/value pairs.
  286. */
  287. name_value_collection(const collection_type& map) : map_(map) {
  288. update_c_arr();
  289. }
  290. /**
  291. * Creates a name/value collection from an underlying STL collection.
  292. * @param map The collection of name/value pairs.
  293. */
  294. name_value_collection(collection_type&& map) : map_(std::move(map)) {
  295. update_c_arr();
  296. }
  297. /**
  298. * Copy constructor.
  299. * @param other Another collection of name/value pairs.
  300. */
  301. name_value_collection(const name_value_collection& other)
  302. : map_(other.map_) {
  303. update_c_arr();
  304. }
  305. /**
  306. * Move constructor.
  307. * @param other Another collection of name/value pairs
  308. */
  309. name_value_collection(name_value_collection&& other) =default;
  310. /**
  311. * Constructs the collection with an initializer list.
  312. *
  313. * This works identically to initializing a std::map<> with string/tring
  314. * pairs.
  315. *
  316. * @param init Initializer list to construct the members of the
  317. * collection.
  318. */
  319. name_value_collection(std::initializer_list<value_type> init)
  320. : map_{ init } {
  321. update_c_arr();
  322. }
  323. /**
  324. * Copy assignment.
  325. * @param other Another collection of name/value pairs.
  326. */
  327. name_value_collection& operator=(const name_value_collection& other) {
  328. map_ = other.map_;
  329. update_c_arr();
  330. return *this;
  331. }
  332. /**
  333. * Move constructor.
  334. * @param other Another collection of name/value pairs
  335. */
  336. name_value_collection& operator=(name_value_collection&& other) =default;
  337. /**
  338. * Determines if the collection is empty.
  339. * @return @em true if the container is empty, @em false if it contains
  340. * one or more items.
  341. */
  342. bool empty() const { return map_.empty(); }
  343. /**
  344. * Gets the number of name/value pairs in the collection.
  345. * @return The number of name/value pairs in the collection.
  346. */
  347. size_t size() const { return map_.size(); }
  348. /**
  349. * Removes all items from the collection.
  350. */
  351. void clear() {
  352. map_.clear();
  353. update_c_arr();
  354. }
  355. /**
  356. * Inserts a name/value pair into the collection.
  357. * @param nvpair The name/value string pair.
  358. * @return @em true if the inert happened, @em false if not.
  359. */
  360. bool insert(const value_type& nvpair) {
  361. if (map_.insert(nvpair).second) {
  362. update_c_arr();
  363. return true;
  364. }
  365. return false;
  366. }
  367. /**
  368. * Gets a pointer to an array of NUL-terminated C string pointer pairs.
  369. * This is a collection type supported by the underlying Paho C
  370. * library. The returned pointer is guaranteed valid so long as the
  371. * object is not updated. The return value may change if the object is
  372. * modified, so the application should not cache the return value, but
  373. * rather request the value when needed.
  374. * @return pointer to an array of NUL-terminated C string pointer pairs
  375. * for name/values. The array is terminated by a NULL/NULL pair.
  376. */
  377. const MQTTAsync_nameValue* c_arr() const { return cArr_.data(); }
  378. };
  379. /////////////////////////////////////////////////////////////////////////////
  380. // end namespace mqtt
  381. }
  382. #endif // __mqtt_string_collection_h