zmq.hpp 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631
  1. /*
  2. Copyright (c) 2016-2017 ZeroMQ community
  3. Copyright (c) 2009-2011 250bpm s.r.o.
  4. Copyright (c) 2011 Botond Ballo
  5. Copyright (c) 2007-2009 iMatix Corporation
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to
  8. deal in the Software without restriction, including without limitation the
  9. rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. sell copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. IN THE SOFTWARE.
  21. */
  22. #ifndef __ZMQ_HPP_INCLUDED__
  23. #define __ZMQ_HPP_INCLUDED__
  24. #ifdef _WIN32
  25. #ifndef NOMINMAX
  26. #define NOMINMAX
  27. #endif
  28. #endif
  29. // macros defined if has a specific standard or greater
  30. #if (defined(__cplusplus) && __cplusplus >= 201103L) \
  31. || (defined(_MSC_VER) && _MSC_VER >= 1900)
  32. #define ZMQ_CPP11
  33. #endif
  34. #if (defined(__cplusplus) && __cplusplus >= 201402L) \
  35. || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) \
  36. || (defined(_HAS_CXX17) \
  37. && _HAS_CXX17 \
  38. == 1) // _HAS_CXX14 might not be defined when using C++17 on MSVC
  39. #define ZMQ_CPP14
  40. #endif
  41. #if (defined(__cplusplus) && __cplusplus >= 201703L) \
  42. || (defined(_HAS_CXX17) && _HAS_CXX17 == 1)
  43. #define ZMQ_CPP17
  44. #endif
  45. #if defined(ZMQ_CPP14)
  46. #define ZMQ_DEPRECATED(msg) [[deprecated(msg)]]
  47. #elif defined(_MSC_VER)
  48. #define ZMQ_DEPRECATED(msg) __declspec(deprecated(msg))
  49. #elif defined(__GNUC__)
  50. #define ZMQ_DEPRECATED(msg) __attribute__((deprecated(msg)))
  51. #endif
  52. #if defined(ZMQ_CPP17)
  53. #define ZMQ_NODISCARD [[nodiscard]]
  54. #else
  55. #define ZMQ_NODISCARD
  56. #endif
  57. #if defined(ZMQ_CPP11)
  58. #define ZMQ_NOTHROW noexcept
  59. #define ZMQ_EXPLICIT explicit
  60. #define ZMQ_OVERRIDE override
  61. #define ZMQ_NULLPTR nullptr
  62. #define ZMQ_CONSTEXPR_FN constexpr
  63. #define ZMQ_CONSTEXPR_VAR constexpr
  64. #define ZMQ_CPP11_DEPRECATED(msg) ZMQ_DEPRECATED(msg)
  65. #else
  66. #define ZMQ_NOTHROW throw()
  67. #define ZMQ_EXPLICIT
  68. #define ZMQ_OVERRIDE
  69. #define ZMQ_NULLPTR 0
  70. #define ZMQ_CONSTEXPR_FN
  71. #define ZMQ_CONSTEXPR_VAR const
  72. #define ZMQ_CPP11_DEPRECATED(msg)
  73. #endif
  74. #if defined(ZMQ_CPP17)
  75. #define ZMQ_INLINE_VAR inline
  76. #else
  77. #define ZMQ_INLINE_VAR
  78. #endif
  79. #include <zmq.h>
  80. #include <cassert>
  81. #include <cstring>
  82. #include <algorithm>
  83. #include <exception>
  84. #include <iomanip>
  85. #include <sstream>
  86. #include <string>
  87. #include <vector>
  88. #ifdef ZMQ_CPP11
  89. #include <array>
  90. #include <chrono>
  91. #include <tuple>
  92. #include <memory>
  93. #endif
  94. #if defined(__has_include) && defined(ZMQ_CPP17)
  95. #define CPPZMQ_HAS_INCLUDE_CPP17(X) __has_include(X)
  96. #else
  97. #define CPPZMQ_HAS_INCLUDE_CPP17(X) 0
  98. #endif
  99. #if CPPZMQ_HAS_INCLUDE_CPP17(<optional>) && !defined(CPPZMQ_HAS_OPTIONAL)
  100. #define CPPZMQ_HAS_OPTIONAL 1
  101. #endif
  102. #ifndef CPPZMQ_HAS_OPTIONAL
  103. #define CPPZMQ_HAS_OPTIONAL 0
  104. #elif CPPZMQ_HAS_OPTIONAL
  105. #include <optional>
  106. #endif
  107. #if CPPZMQ_HAS_INCLUDE_CPP17(<string_view>) && !defined(CPPZMQ_HAS_STRING_VIEW)
  108. #define CPPZMQ_HAS_STRING_VIEW 1
  109. #endif
  110. #ifndef CPPZMQ_HAS_STRING_VIEW
  111. #define CPPZMQ_HAS_STRING_VIEW 0
  112. #elif CPPZMQ_HAS_STRING_VIEW
  113. #include <string_view>
  114. #endif
  115. /* Version macros for compile-time API version detection */
  116. #define CPPZMQ_VERSION_MAJOR 4
  117. #define CPPZMQ_VERSION_MINOR 7
  118. #define CPPZMQ_VERSION_PATCH 0
  119. #define CPPZMQ_VERSION \
  120. ZMQ_MAKE_VERSION(CPPZMQ_VERSION_MAJOR, CPPZMQ_VERSION_MINOR, \
  121. CPPZMQ_VERSION_PATCH)
  122. // Detect whether the compiler supports C++11 rvalue references.
  123. #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) \
  124. && defined(__GXX_EXPERIMENTAL_CXX0X__))
  125. #define ZMQ_HAS_RVALUE_REFS
  126. #define ZMQ_DELETED_FUNCTION = delete
  127. #elif defined(__clang__)
  128. #if __has_feature(cxx_rvalue_references)
  129. #define ZMQ_HAS_RVALUE_REFS
  130. #endif
  131. #if __has_feature(cxx_deleted_functions)
  132. #define ZMQ_DELETED_FUNCTION = delete
  133. #else
  134. #define ZMQ_DELETED_FUNCTION
  135. #endif
  136. #elif defined(_MSC_VER) && (_MSC_VER >= 1900)
  137. #define ZMQ_HAS_RVALUE_REFS
  138. #define ZMQ_DELETED_FUNCTION = delete
  139. #elif defined(_MSC_VER) && (_MSC_VER >= 1600)
  140. #define ZMQ_HAS_RVALUE_REFS
  141. #define ZMQ_DELETED_FUNCTION
  142. #else
  143. #define ZMQ_DELETED_FUNCTION
  144. #endif
  145. #if defined(ZMQ_CPP11) && !defined(__llvm__) && !defined(__INTEL_COMPILER) \
  146. && defined(__GNUC__) && __GNUC__ < 5
  147. #define ZMQ_CPP11_PARTIAL
  148. #elif defined(__GLIBCXX__) && __GLIBCXX__ < 20160805
  149. //the date here is the last date of gcc 4.9.4, which
  150. // effectively means libstdc++ from gcc 5.5 and higher won't trigger this branch
  151. #define ZMQ_CPP11_PARTIAL
  152. #endif
  153. #ifdef ZMQ_CPP11
  154. #ifdef ZMQ_CPP11_PARTIAL
  155. #define ZMQ_IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T)
  156. #else
  157. #include <type_traits>
  158. #define ZMQ_IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable<T>::value
  159. #endif
  160. #endif
  161. #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 3, 0)
  162. #define ZMQ_NEW_MONITOR_EVENT_LAYOUT
  163. #endif
  164. #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0)
  165. #define ZMQ_HAS_PROXY_STEERABLE
  166. /* Socket event data */
  167. typedef struct
  168. {
  169. uint16_t event; // id of the event as bitfield
  170. int32_t value; // value is either error code, fd or reconnect interval
  171. } zmq_event_t;
  172. #endif
  173. // Avoid using deprecated message receive function when possible
  174. #if ZMQ_VERSION < ZMQ_MAKE_VERSION(3, 2, 0)
  175. #define zmq_msg_recv(msg, socket, flags) zmq_recvmsg(socket, msg, flags)
  176. #endif
  177. // In order to prevent unused variable warnings when building in non-debug
  178. // mode use this macro to make assertions.
  179. #ifndef NDEBUG
  180. #define ZMQ_ASSERT(expression) assert(expression)
  181. #else
  182. #define ZMQ_ASSERT(expression) (void) (expression)
  183. #endif
  184. namespace zmq
  185. {
  186. #ifdef ZMQ_CPP11
  187. namespace detail
  188. {
  189. namespace ranges
  190. {
  191. using std::begin;
  192. using std::end;
  193. template<class T> auto begin(T &&r) -> decltype(begin(std::forward<T>(r)))
  194. {
  195. return begin(std::forward<T>(r));
  196. }
  197. template<class T> auto end(T &&r) -> decltype(end(std::forward<T>(r)))
  198. {
  199. return end(std::forward<T>(r));
  200. }
  201. } // namespace ranges
  202. template<class T> using void_t = void;
  203. template<class Iter>
  204. using iter_value_t = typename std::iterator_traits<Iter>::value_type;
  205. template<class Range>
  206. using range_iter_t = decltype(
  207. ranges::begin(std::declval<typename std::remove_reference<Range>::type &>()));
  208. template<class Range> using range_value_t = iter_value_t<range_iter_t<Range>>;
  209. template<class T, class = void> struct is_range : std::false_type
  210. {
  211. };
  212. template<class T>
  213. struct is_range<
  214. T,
  215. void_t<decltype(
  216. ranges::begin(std::declval<typename std::remove_reference<T>::type &>())
  217. == ranges::end(std::declval<typename std::remove_reference<T>::type &>()))>>
  218. : std::true_type
  219. {
  220. };
  221. } // namespace detail
  222. #endif
  223. typedef zmq_free_fn free_fn;
  224. typedef zmq_pollitem_t pollitem_t;
  225. class error_t : public std::exception
  226. {
  227. public:
  228. error_t() : errnum(zmq_errno()) {}
  229. virtual const char *what() const ZMQ_NOTHROW ZMQ_OVERRIDE
  230. {
  231. return zmq_strerror(errnum);
  232. }
  233. int num() const { return errnum; }
  234. private:
  235. int errnum;
  236. };
  237. inline int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_ = -1)
  238. {
  239. int rc = zmq_poll(items_, static_cast<int>(nitems_), timeout_);
  240. if (rc < 0)
  241. throw error_t();
  242. return rc;
  243. }
  244. ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items")
  245. inline int poll(zmq_pollitem_t const *items_, size_t nitems_, long timeout_ = -1)
  246. {
  247. return poll(const_cast<zmq_pollitem_t *>(items_), nitems_, timeout_);
  248. }
  249. #ifdef ZMQ_CPP11
  250. ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items")
  251. inline int
  252. poll(zmq_pollitem_t const *items, size_t nitems, std::chrono::milliseconds timeout)
  253. {
  254. return poll(const_cast<zmq_pollitem_t *>(items), nitems,
  255. static_cast<long>(timeout.count()));
  256. }
  257. ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items")
  258. inline int poll(std::vector<zmq_pollitem_t> const &items,
  259. std::chrono::milliseconds timeout)
  260. {
  261. return poll(const_cast<zmq_pollitem_t *>(items.data()), items.size(),
  262. static_cast<long>(timeout.count()));
  263. }
  264. ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items")
  265. inline int poll(std::vector<zmq_pollitem_t> const &items, long timeout_ = -1)
  266. {
  267. return poll(const_cast<zmq_pollitem_t *>(items.data()), items.size(), timeout_);
  268. }
  269. inline int
  270. poll(zmq_pollitem_t *items, size_t nitems, std::chrono::milliseconds timeout)
  271. {
  272. return poll(items, nitems, static_cast<long>(timeout.count()));
  273. }
  274. inline int poll(std::vector<zmq_pollitem_t> &items,
  275. std::chrono::milliseconds timeout)
  276. {
  277. return poll(items.data(), items.size(), static_cast<long>(timeout.count()));
  278. }
  279. ZMQ_DEPRECATED("from 4.3.1, use poll taking std::chrono instead of long")
  280. inline int poll(std::vector<zmq_pollitem_t> &items, long timeout_ = -1)
  281. {
  282. return poll(items.data(), items.size(), timeout_);
  283. }
  284. template<std::size_t SIZE>
  285. inline int poll(std::array<zmq_pollitem_t, SIZE>& items,
  286. std::chrono::milliseconds timeout)
  287. {
  288. return poll(items.data(), items.size(), static_cast<long>(timeout.count()));
  289. }
  290. #endif
  291. inline void version(int *major_, int *minor_, int *patch_)
  292. {
  293. zmq_version(major_, minor_, patch_);
  294. }
  295. #ifdef ZMQ_CPP11
  296. inline std::tuple<int, int, int> version()
  297. {
  298. std::tuple<int, int, int> v;
  299. zmq_version(&std::get<0>(v), &std::get<1>(v), &std::get<2>(v));
  300. return v;
  301. }
  302. #endif
  303. class message_t
  304. {
  305. public:
  306. message_t() ZMQ_NOTHROW
  307. {
  308. int rc = zmq_msg_init(&msg);
  309. ZMQ_ASSERT(rc == 0);
  310. }
  311. explicit message_t(size_t size_)
  312. {
  313. int rc = zmq_msg_init_size(&msg, size_);
  314. if (rc != 0)
  315. throw error_t();
  316. }
  317. template<class ForwardIter> message_t(ForwardIter first, ForwardIter last)
  318. {
  319. typedef typename std::iterator_traits<ForwardIter>::value_type value_t;
  320. assert(std::distance(first, last) >= 0);
  321. size_t const size_ =
  322. static_cast<size_t>(std::distance(first, last)) * sizeof(value_t);
  323. int const rc = zmq_msg_init_size(&msg, size_);
  324. if (rc != 0)
  325. throw error_t();
  326. std::copy(first, last, data<value_t>());
  327. }
  328. message_t(const void *data_, size_t size_)
  329. {
  330. int rc = zmq_msg_init_size(&msg, size_);
  331. if (rc != 0)
  332. throw error_t();
  333. if (size_)
  334. {
  335. // this constructor allows (nullptr, 0),
  336. // memcpy with a null pointer is UB
  337. memcpy(data(), data_, size_);
  338. }
  339. }
  340. message_t(void *data_, size_t size_, free_fn *ffn_, void *hint_ = ZMQ_NULLPTR)
  341. {
  342. int rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_);
  343. if (rc != 0)
  344. throw error_t();
  345. }
  346. #if defined(ZMQ_CPP11) && !defined(ZMQ_CPP11_PARTIAL)
  347. template<class Range,
  348. typename = typename std::enable_if<
  349. detail::is_range<Range>::value
  350. && ZMQ_IS_TRIVIALLY_COPYABLE(detail::range_value_t<Range>)
  351. && !std::is_same<Range, message_t>::value>::type>
  352. explicit message_t(const Range &rng) :
  353. message_t(detail::ranges::begin(rng), detail::ranges::end(rng))
  354. {
  355. }
  356. #endif
  357. #ifdef ZMQ_HAS_RVALUE_REFS
  358. message_t(message_t &&rhs) ZMQ_NOTHROW : msg(rhs.msg)
  359. {
  360. int rc = zmq_msg_init(&rhs.msg);
  361. ZMQ_ASSERT(rc == 0);
  362. }
  363. message_t &operator=(message_t &&rhs) ZMQ_NOTHROW
  364. {
  365. std::swap(msg, rhs.msg);
  366. return *this;
  367. }
  368. #endif
  369. ~message_t() ZMQ_NOTHROW
  370. {
  371. int rc = zmq_msg_close(&msg);
  372. ZMQ_ASSERT(rc == 0);
  373. }
  374. void rebuild()
  375. {
  376. int rc = zmq_msg_close(&msg);
  377. if (rc != 0)
  378. throw error_t();
  379. rc = zmq_msg_init(&msg);
  380. ZMQ_ASSERT(rc == 0);
  381. }
  382. void rebuild(size_t size_)
  383. {
  384. int rc = zmq_msg_close(&msg);
  385. if (rc != 0)
  386. throw error_t();
  387. rc = zmq_msg_init_size(&msg, size_);
  388. if (rc != 0)
  389. throw error_t();
  390. }
  391. void rebuild(const void *data_, size_t size_)
  392. {
  393. int rc = zmq_msg_close(&msg);
  394. if (rc != 0)
  395. throw error_t();
  396. rc = zmq_msg_init_size(&msg, size_);
  397. if (rc != 0)
  398. throw error_t();
  399. memcpy(data(), data_, size_);
  400. }
  401. void rebuild(void *data_, size_t size_, free_fn *ffn_, void *hint_ = ZMQ_NULLPTR)
  402. {
  403. int rc = zmq_msg_close(&msg);
  404. if (rc != 0)
  405. throw error_t();
  406. rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_);
  407. if (rc != 0)
  408. throw error_t();
  409. }
  410. ZMQ_DEPRECATED("from 4.3.1, use move taking non-const reference instead")
  411. void move(message_t const *msg_)
  412. {
  413. int rc = zmq_msg_move(&msg, const_cast<zmq_msg_t *>(msg_->handle()));
  414. if (rc != 0)
  415. throw error_t();
  416. }
  417. void move(message_t &msg_)
  418. {
  419. int rc = zmq_msg_move(&msg, msg_.handle());
  420. if (rc != 0)
  421. throw error_t();
  422. }
  423. ZMQ_DEPRECATED("from 4.3.1, use copy taking non-const reference instead")
  424. void copy(message_t const *msg_)
  425. {
  426. int rc = zmq_msg_copy(&msg, const_cast<zmq_msg_t *>(msg_->handle()));
  427. if (rc != 0)
  428. throw error_t();
  429. }
  430. void copy(message_t &msg_)
  431. {
  432. int rc = zmq_msg_copy(&msg, msg_.handle());
  433. if (rc != 0)
  434. throw error_t();
  435. }
  436. bool more() const ZMQ_NOTHROW
  437. {
  438. int rc = zmq_msg_more(const_cast<zmq_msg_t *>(&msg));
  439. return rc != 0;
  440. }
  441. void *data() ZMQ_NOTHROW { return zmq_msg_data(&msg); }
  442. const void *data() const ZMQ_NOTHROW
  443. {
  444. return zmq_msg_data(const_cast<zmq_msg_t *>(&msg));
  445. }
  446. size_t size() const ZMQ_NOTHROW
  447. {
  448. return zmq_msg_size(const_cast<zmq_msg_t *>(&msg));
  449. }
  450. ZMQ_NODISCARD bool empty() const ZMQ_NOTHROW { return size() == 0u; }
  451. template<typename T> T *data() ZMQ_NOTHROW { return static_cast<T *>(data()); }
  452. template<typename T> T const *data() const ZMQ_NOTHROW
  453. {
  454. return static_cast<T const *>(data());
  455. }
  456. ZMQ_DEPRECATED("from 4.3.0, use operator== instead")
  457. bool equal(const message_t *other) const ZMQ_NOTHROW { return *this == *other; }
  458. bool operator==(const message_t &other) const ZMQ_NOTHROW
  459. {
  460. const size_t my_size = size();
  461. return my_size == other.size() && 0 == memcmp(data(), other.data(), my_size);
  462. }
  463. bool operator!=(const message_t &other) const ZMQ_NOTHROW
  464. {
  465. return !(*this == other);
  466. }
  467. #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 2, 0)
  468. int get(int property_)
  469. {
  470. int value = zmq_msg_get(&msg, property_);
  471. if (value == -1)
  472. throw error_t();
  473. return value;
  474. }
  475. #endif
  476. #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0)
  477. const char *gets(const char *property_)
  478. {
  479. const char *value = zmq_msg_gets(&msg, property_);
  480. if (value == ZMQ_NULLPTR)
  481. throw error_t();
  482. return value;
  483. }
  484. #endif
  485. #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0)
  486. uint32_t routing_id() const
  487. {
  488. return zmq_msg_routing_id(const_cast<zmq_msg_t *>(&msg));
  489. }
  490. void set_routing_id(uint32_t routing_id)
  491. {
  492. int rc = zmq_msg_set_routing_id(&msg, routing_id);
  493. if (rc != 0)
  494. throw error_t();
  495. }
  496. const char *group() const
  497. {
  498. return zmq_msg_group(const_cast<zmq_msg_t *>(&msg));
  499. }
  500. void set_group(const char *group)
  501. {
  502. int rc = zmq_msg_set_group(&msg, group);
  503. if (rc != 0)
  504. throw error_t();
  505. }
  506. #endif
  507. // interpret message content as a string
  508. std::string to_string() const
  509. {
  510. return std::string(static_cast<const char *>(data()), size());
  511. }
  512. #if CPPZMQ_HAS_STRING_VIEW
  513. // interpret message content as a string
  514. std::string_view to_string_view() const noexcept
  515. {
  516. return std::string_view(static_cast<const char *>(data()), size());
  517. }
  518. #endif
  519. /** Dump content to string for debugging.
  520. * Ascii chars are readable, the rest is printed as hex.
  521. * Probably ridiculously slow.
  522. * Use to_string() or to_string_view() for
  523. * interpreting the message as a string.
  524. */
  525. std::string str() const
  526. {
  527. // Partly mutuated from the same method in zmq::multipart_t
  528. std::stringstream os;
  529. const unsigned char *msg_data = this->data<unsigned char>();
  530. unsigned char byte;
  531. size_t size = this->size();
  532. int is_ascii[2] = {0, 0};
  533. os << "zmq::message_t [size " << std::dec << std::setw(3)
  534. << std::setfill('0') << size << "] (";
  535. // Totally arbitrary
  536. if (size >= 1000) {
  537. os << "... too big to print)";
  538. } else {
  539. while (size--) {
  540. byte = *msg_data++;
  541. is_ascii[1] = (byte >= 32 && byte < 127);
  542. if (is_ascii[1] != is_ascii[0])
  543. os << " "; // Separate text/non text
  544. if (is_ascii[1]) {
  545. os << byte;
  546. } else {
  547. os << std::hex << std::uppercase << std::setw(2)
  548. << std::setfill('0') << static_cast<short>(byte);
  549. }
  550. is_ascii[0] = is_ascii[1];
  551. }
  552. os << ")";
  553. }
  554. return os.str();
  555. }
  556. void swap(message_t &other) ZMQ_NOTHROW
  557. {
  558. // this assumes zmq::msg_t from libzmq is trivially relocatable
  559. std::swap(msg, other.msg);
  560. }
  561. ZMQ_NODISCARD zmq_msg_t *handle() ZMQ_NOTHROW { return &msg; }
  562. ZMQ_NODISCARD const zmq_msg_t *handle() const ZMQ_NOTHROW { return &msg; }
  563. private:
  564. // The underlying message
  565. zmq_msg_t msg;
  566. // Disable implicit message copying, so that users won't use shared
  567. // messages (less efficient) without being aware of the fact.
  568. message_t(const message_t &) ZMQ_DELETED_FUNCTION;
  569. void operator=(const message_t &) ZMQ_DELETED_FUNCTION;
  570. };
  571. inline void swap(message_t &a, message_t &b) ZMQ_NOTHROW
  572. {
  573. a.swap(b);
  574. }
  575. #ifdef ZMQ_CPP11
  576. enum class ctxopt
  577. {
  578. #ifdef ZMQ_BLOCKY
  579. blocky = ZMQ_BLOCKY,
  580. #endif
  581. #ifdef ZMQ_IO_THREADS
  582. io_threads = ZMQ_IO_THREADS,
  583. #endif
  584. #ifdef ZMQ_THREAD_SCHED_POLICY
  585. thread_sched_policy = ZMQ_THREAD_SCHED_POLICY,
  586. #endif
  587. #ifdef ZMQ_THREAD_PRIORITY
  588. thread_priority = ZMQ_THREAD_PRIORITY,
  589. #endif
  590. #ifdef ZMQ_THREAD_AFFINITY_CPU_ADD
  591. thread_affinity_cpu_add = ZMQ_THREAD_AFFINITY_CPU_ADD,
  592. #endif
  593. #ifdef ZMQ_THREAD_AFFINITY_CPU_REMOVE
  594. thread_affinity_cpu_remove = ZMQ_THREAD_AFFINITY_CPU_REMOVE,
  595. #endif
  596. #ifdef ZMQ_THREAD_NAME_PREFIX
  597. thread_name_prefix = ZMQ_THREAD_NAME_PREFIX,
  598. #endif
  599. #ifdef ZMQ_MAX_MSGSZ
  600. max_msgsz = ZMQ_MAX_MSGSZ,
  601. #endif
  602. #ifdef ZMQ_ZERO_COPY_RECV
  603. zero_copy_recv = ZMQ_ZERO_COPY_RECV,
  604. #endif
  605. #ifdef ZMQ_MAX_SOCKETS
  606. max_sockets = ZMQ_MAX_SOCKETS,
  607. #endif
  608. #ifdef ZMQ_SOCKET_LIMIT
  609. socket_limit = ZMQ_SOCKET_LIMIT,
  610. #endif
  611. #ifdef ZMQ_IPV6
  612. ipv6 = ZMQ_IPV6,
  613. #endif
  614. #ifdef ZMQ_MSG_T_SIZE
  615. msg_t_size = ZMQ_MSG_T_SIZE
  616. #endif
  617. };
  618. #endif
  619. class context_t
  620. {
  621. public:
  622. context_t()
  623. {
  624. ptr = zmq_ctx_new();
  625. if (ptr == ZMQ_NULLPTR)
  626. throw error_t();
  627. }
  628. explicit context_t(int io_threads_, int max_sockets_ = ZMQ_MAX_SOCKETS_DFLT)
  629. {
  630. ptr = zmq_ctx_new();
  631. if (ptr == ZMQ_NULLPTR)
  632. throw error_t();
  633. int rc = zmq_ctx_set(ptr, ZMQ_IO_THREADS, io_threads_);
  634. ZMQ_ASSERT(rc == 0);
  635. rc = zmq_ctx_set(ptr, ZMQ_MAX_SOCKETS, max_sockets_);
  636. ZMQ_ASSERT(rc == 0);
  637. }
  638. #ifdef ZMQ_HAS_RVALUE_REFS
  639. context_t(context_t &&rhs) ZMQ_NOTHROW : ptr(rhs.ptr) { rhs.ptr = ZMQ_NULLPTR; }
  640. context_t &operator=(context_t &&rhs) ZMQ_NOTHROW
  641. {
  642. close();
  643. std::swap(ptr, rhs.ptr);
  644. return *this;
  645. }
  646. #endif
  647. ~context_t() ZMQ_NOTHROW { close(); }
  648. ZMQ_CPP11_DEPRECATED("from 4.7.0, use set taking zmq::ctxopt instead")
  649. int setctxopt(int option_, int optval_)
  650. {
  651. int rc = zmq_ctx_set(ptr, option_, optval_);
  652. ZMQ_ASSERT(rc == 0);
  653. return rc;
  654. }
  655. ZMQ_CPP11_DEPRECATED("from 4.7.0, use get taking zmq::ctxopt instead")
  656. int getctxopt(int option_) { return zmq_ctx_get(ptr, option_); }
  657. #ifdef ZMQ_CPP11
  658. void set(ctxopt option, int optval)
  659. {
  660. int rc = zmq_ctx_set(ptr, static_cast<int>(option), optval);
  661. if (rc == -1)
  662. throw error_t();
  663. }
  664. ZMQ_NODISCARD int get(ctxopt option)
  665. {
  666. int rc = zmq_ctx_get(ptr, static_cast<int>(option));
  667. // some options have a default value of -1
  668. // which is unfortunate, and may result in errors
  669. // that don't make sense
  670. if (rc == -1)
  671. throw error_t();
  672. return rc;
  673. }
  674. #endif
  675. // Terminates context (see also shutdown()).
  676. void close() ZMQ_NOTHROW
  677. {
  678. if (ptr == ZMQ_NULLPTR)
  679. return;
  680. int rc;
  681. do {
  682. rc = zmq_ctx_destroy(ptr);
  683. } while (rc == -1 && errno == EINTR);
  684. ZMQ_ASSERT(rc == 0);
  685. ptr = ZMQ_NULLPTR;
  686. }
  687. // Shutdown context in preparation for termination (close()).
  688. // Causes all blocking socket operations and any further
  689. // socket operations to return with ETERM.
  690. void shutdown() ZMQ_NOTHROW
  691. {
  692. if (ptr == ZMQ_NULLPTR)
  693. return;
  694. int rc = zmq_ctx_shutdown(ptr);
  695. ZMQ_ASSERT(rc == 0);
  696. }
  697. // Be careful with this, it's probably only useful for
  698. // using the C api together with an existing C++ api.
  699. // Normally you should never need to use this.
  700. ZMQ_EXPLICIT operator void *() ZMQ_NOTHROW { return ptr; }
  701. ZMQ_EXPLICIT operator void const *() const ZMQ_NOTHROW { return ptr; }
  702. ZMQ_NODISCARD void *handle() ZMQ_NOTHROW { return ptr; }
  703. ZMQ_DEPRECATED("from 4.7.0, use handle() != nullptr instead")
  704. operator bool() const ZMQ_NOTHROW { return ptr != ZMQ_NULLPTR; }
  705. void swap(context_t &other) ZMQ_NOTHROW { std::swap(ptr, other.ptr); }
  706. private:
  707. void *ptr;
  708. context_t(const context_t &) ZMQ_DELETED_FUNCTION;
  709. void operator=(const context_t &) ZMQ_DELETED_FUNCTION;
  710. };
  711. inline void swap(context_t &a, context_t &b) ZMQ_NOTHROW
  712. {
  713. a.swap(b);
  714. }
  715. #ifdef ZMQ_CPP11
  716. struct recv_buffer_size
  717. {
  718. size_t size; // number of bytes written to buffer
  719. size_t untruncated_size; // untruncated message size in bytes
  720. ZMQ_NODISCARD bool truncated() const noexcept
  721. {
  722. return size != untruncated_size;
  723. }
  724. };
  725. #if CPPZMQ_HAS_OPTIONAL
  726. using send_result_t = std::optional<size_t>;
  727. using recv_result_t = std::optional<size_t>;
  728. using recv_buffer_result_t = std::optional<recv_buffer_size>;
  729. #else
  730. namespace detail
  731. {
  732. // A C++11 type emulating the most basic
  733. // operations of std::optional for trivial types
  734. template<class T> class trivial_optional
  735. {
  736. public:
  737. static_assert(std::is_trivial<T>::value, "T must be trivial");
  738. using value_type = T;
  739. trivial_optional() = default;
  740. trivial_optional(T value) noexcept : _value(value), _has_value(true) {}
  741. const T *operator->() const noexcept
  742. {
  743. assert(_has_value);
  744. return &_value;
  745. }
  746. T *operator->() noexcept
  747. {
  748. assert(_has_value);
  749. return &_value;
  750. }
  751. const T &operator*() const noexcept
  752. {
  753. assert(_has_value);
  754. return _value;
  755. }
  756. T &operator*() noexcept
  757. {
  758. assert(_has_value);
  759. return _value;
  760. }
  761. T &value()
  762. {
  763. if (!_has_value)
  764. throw std::exception();
  765. return _value;
  766. }
  767. const T &value() const
  768. {
  769. if (!_has_value)
  770. throw std::exception();
  771. return _value;
  772. }
  773. explicit operator bool() const noexcept { return _has_value; }
  774. bool has_value() const noexcept { return _has_value; }
  775. private:
  776. T _value{};
  777. bool _has_value{false};
  778. };
  779. } // namespace detail
  780. using send_result_t = detail::trivial_optional<size_t>;
  781. using recv_result_t = detail::trivial_optional<size_t>;
  782. using recv_buffer_result_t = detail::trivial_optional<recv_buffer_size>;
  783. #endif
  784. namespace detail
  785. {
  786. template<class T> constexpr T enum_bit_or(T a, T b) noexcept
  787. {
  788. static_assert(std::is_enum<T>::value, "must be enum");
  789. using U = typename std::underlying_type<T>::type;
  790. return static_cast<T>(static_cast<U>(a) | static_cast<U>(b));
  791. }
  792. template<class T> constexpr T enum_bit_and(T a, T b) noexcept
  793. {
  794. static_assert(std::is_enum<T>::value, "must be enum");
  795. using U = typename std::underlying_type<T>::type;
  796. return static_cast<T>(static_cast<U>(a) & static_cast<U>(b));
  797. }
  798. template<class T> constexpr T enum_bit_xor(T a, T b) noexcept
  799. {
  800. static_assert(std::is_enum<T>::value, "must be enum");
  801. using U = typename std::underlying_type<T>::type;
  802. return static_cast<T>(static_cast<U>(a) ^ static_cast<U>(b));
  803. }
  804. template<class T> constexpr T enum_bit_not(T a) noexcept
  805. {
  806. static_assert(std::is_enum<T>::value, "must be enum");
  807. using U = typename std::underlying_type<T>::type;
  808. return static_cast<T>(~static_cast<U>(a));
  809. }
  810. } // namespace detail
  811. // partially satisfies named requirement BitmaskType
  812. enum class send_flags : int
  813. {
  814. none = 0,
  815. dontwait = ZMQ_DONTWAIT,
  816. sndmore = ZMQ_SNDMORE
  817. };
  818. constexpr send_flags operator|(send_flags a, send_flags b) noexcept
  819. {
  820. return detail::enum_bit_or(a, b);
  821. }
  822. constexpr send_flags operator&(send_flags a, send_flags b) noexcept
  823. {
  824. return detail::enum_bit_and(a, b);
  825. }
  826. constexpr send_flags operator^(send_flags a, send_flags b) noexcept
  827. {
  828. return detail::enum_bit_xor(a, b);
  829. }
  830. constexpr send_flags operator~(send_flags a) noexcept
  831. {
  832. return detail::enum_bit_not(a);
  833. }
  834. // partially satisfies named requirement BitmaskType
  835. enum class recv_flags : int
  836. {
  837. none = 0,
  838. dontwait = ZMQ_DONTWAIT
  839. };
  840. constexpr recv_flags operator|(recv_flags a, recv_flags b) noexcept
  841. {
  842. return detail::enum_bit_or(a, b);
  843. }
  844. constexpr recv_flags operator&(recv_flags a, recv_flags b) noexcept
  845. {
  846. return detail::enum_bit_and(a, b);
  847. }
  848. constexpr recv_flags operator^(recv_flags a, recv_flags b) noexcept
  849. {
  850. return detail::enum_bit_xor(a, b);
  851. }
  852. constexpr recv_flags operator~(recv_flags a) noexcept
  853. {
  854. return detail::enum_bit_not(a);
  855. }
  856. // mutable_buffer, const_buffer and buffer are based on
  857. // the Networking TS specification, draft:
  858. // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf
  859. class mutable_buffer
  860. {
  861. public:
  862. constexpr mutable_buffer() noexcept : _data(nullptr), _size(0) {}
  863. constexpr mutable_buffer(void *p, size_t n) noexcept : _data(p), _size(n)
  864. {
  865. #ifdef ZMQ_CPP14
  866. assert(p != nullptr || n == 0);
  867. #endif
  868. }
  869. constexpr void *data() const noexcept { return _data; }
  870. constexpr size_t size() const noexcept { return _size; }
  871. mutable_buffer &operator+=(size_t n) noexcept
  872. {
  873. // (std::min) is a workaround for when a min macro is defined
  874. const auto shift = (std::min)(n, _size);
  875. _data = static_cast<char *>(_data) + shift;
  876. _size -= shift;
  877. return *this;
  878. }
  879. private:
  880. void *_data;
  881. size_t _size;
  882. };
  883. inline mutable_buffer operator+(const mutable_buffer &mb, size_t n) noexcept
  884. {
  885. return mutable_buffer(static_cast<char *>(mb.data()) + (std::min)(n, mb.size()),
  886. mb.size() - (std::min)(n, mb.size()));
  887. }
  888. inline mutable_buffer operator+(size_t n, const mutable_buffer &mb) noexcept
  889. {
  890. return mb + n;
  891. }
  892. class const_buffer
  893. {
  894. public:
  895. constexpr const_buffer() noexcept : _data(nullptr), _size(0) {}
  896. constexpr const_buffer(const void *p, size_t n) noexcept : _data(p), _size(n)
  897. {
  898. #ifdef ZMQ_CPP14
  899. assert(p != nullptr || n == 0);
  900. #endif
  901. }
  902. constexpr const_buffer(const mutable_buffer &mb) noexcept :
  903. _data(mb.data()), _size(mb.size())
  904. {
  905. }
  906. constexpr const void *data() const noexcept { return _data; }
  907. constexpr size_t size() const noexcept { return _size; }
  908. const_buffer &operator+=(size_t n) noexcept
  909. {
  910. const auto shift = (std::min)(n, _size);
  911. _data = static_cast<const char *>(_data) + shift;
  912. _size -= shift;
  913. return *this;
  914. }
  915. private:
  916. const void *_data;
  917. size_t _size;
  918. };
  919. inline const_buffer operator+(const const_buffer &cb, size_t n) noexcept
  920. {
  921. return const_buffer(static_cast<const char *>(cb.data())
  922. + (std::min)(n, cb.size()),
  923. cb.size() - (std::min)(n, cb.size()));
  924. }
  925. inline const_buffer operator+(size_t n, const const_buffer &cb) noexcept
  926. {
  927. return cb + n;
  928. }
  929. // buffer creation
  930. constexpr mutable_buffer buffer(void *p, size_t n) noexcept
  931. {
  932. return mutable_buffer(p, n);
  933. }
  934. constexpr const_buffer buffer(const void *p, size_t n) noexcept
  935. {
  936. return const_buffer(p, n);
  937. }
  938. constexpr mutable_buffer buffer(const mutable_buffer &mb) noexcept
  939. {
  940. return mb;
  941. }
  942. inline mutable_buffer buffer(const mutable_buffer &mb, size_t n) noexcept
  943. {
  944. return mutable_buffer(mb.data(), (std::min)(mb.size(), n));
  945. }
  946. constexpr const_buffer buffer(const const_buffer &cb) noexcept
  947. {
  948. return cb;
  949. }
  950. inline const_buffer buffer(const const_buffer &cb, size_t n) noexcept
  951. {
  952. return const_buffer(cb.data(), (std::min)(cb.size(), n));
  953. }
  954. namespace detail
  955. {
  956. template<class T> struct is_buffer
  957. {
  958. static constexpr bool value =
  959. std::is_same<T, const_buffer>::value || std::is_same<T, mutable_buffer>::value;
  960. };
  961. template<class T> struct is_pod_like
  962. {
  963. // NOTE: The networking draft N4771 section 16.11 requires
  964. // T in the buffer functions below to be
  965. // trivially copyable OR standard layout.
  966. // Here we decide to be conservative and require both.
  967. static constexpr bool value =
  968. ZMQ_IS_TRIVIALLY_COPYABLE(T) && std::is_standard_layout<T>::value;
  969. };
  970. template<class C> constexpr auto seq_size(const C &c) noexcept -> decltype(c.size())
  971. {
  972. return c.size();
  973. }
  974. template<class T, size_t N>
  975. constexpr size_t seq_size(const T (&/*array*/)[N]) noexcept
  976. {
  977. return N;
  978. }
  979. template<class Seq>
  980. auto buffer_contiguous_sequence(Seq &&seq) noexcept
  981. -> decltype(buffer(std::addressof(*std::begin(seq)), size_t{}))
  982. {
  983. using T = typename std::remove_cv<
  984. typename std::remove_reference<decltype(*std::begin(seq))>::type>::type;
  985. static_assert(detail::is_pod_like<T>::value, "T must be POD");
  986. const auto size = seq_size(seq);
  987. return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr,
  988. size * sizeof(T));
  989. }
  990. template<class Seq>
  991. auto buffer_contiguous_sequence(Seq &&seq, size_t n_bytes) noexcept
  992. -> decltype(buffer_contiguous_sequence(seq))
  993. {
  994. using T = typename std::remove_cv<
  995. typename std::remove_reference<decltype(*std::begin(seq))>::type>::type;
  996. static_assert(detail::is_pod_like<T>::value, "T must be POD");
  997. const auto size = seq_size(seq);
  998. return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr,
  999. (std::min)(size * sizeof(T), n_bytes));
  1000. }
  1001. } // namespace detail
  1002. // C array
  1003. template<class T, size_t N> mutable_buffer buffer(T (&data)[N]) noexcept
  1004. {
  1005. return detail::buffer_contiguous_sequence(data);
  1006. }
  1007. template<class T, size_t N>
  1008. mutable_buffer buffer(T (&data)[N], size_t n_bytes) noexcept
  1009. {
  1010. return detail::buffer_contiguous_sequence(data, n_bytes);
  1011. }
  1012. template<class T, size_t N> const_buffer buffer(const T (&data)[N]) noexcept
  1013. {
  1014. return detail::buffer_contiguous_sequence(data);
  1015. }
  1016. template<class T, size_t N>
  1017. const_buffer buffer(const T (&data)[N], size_t n_bytes) noexcept
  1018. {
  1019. return detail::buffer_contiguous_sequence(data, n_bytes);
  1020. }
  1021. // std::array
  1022. template<class T, size_t N> mutable_buffer buffer(std::array<T, N> &data) noexcept
  1023. {
  1024. return detail::buffer_contiguous_sequence(data);
  1025. }
  1026. template<class T, size_t N>
  1027. mutable_buffer buffer(std::array<T, N> &data, size_t n_bytes) noexcept
  1028. {
  1029. return detail::buffer_contiguous_sequence(data, n_bytes);
  1030. }
  1031. template<class T, size_t N>
  1032. const_buffer buffer(std::array<const T, N> &data) noexcept
  1033. {
  1034. return detail::buffer_contiguous_sequence(data);
  1035. }
  1036. template<class T, size_t N>
  1037. const_buffer buffer(std::array<const T, N> &data, size_t n_bytes) noexcept
  1038. {
  1039. return detail::buffer_contiguous_sequence(data, n_bytes);
  1040. }
  1041. template<class T, size_t N>
  1042. const_buffer buffer(const std::array<T, N> &data) noexcept
  1043. {
  1044. return detail::buffer_contiguous_sequence(data);
  1045. }
  1046. template<class T, size_t N>
  1047. const_buffer buffer(const std::array<T, N> &data, size_t n_bytes) noexcept
  1048. {
  1049. return detail::buffer_contiguous_sequence(data, n_bytes);
  1050. }
  1051. // std::vector
  1052. template<class T, class Allocator>
  1053. mutable_buffer buffer(std::vector<T, Allocator> &data) noexcept
  1054. {
  1055. return detail::buffer_contiguous_sequence(data);
  1056. }
  1057. template<class T, class Allocator>
  1058. mutable_buffer buffer(std::vector<T, Allocator> &data, size_t n_bytes) noexcept
  1059. {
  1060. return detail::buffer_contiguous_sequence(data, n_bytes);
  1061. }
  1062. template<class T, class Allocator>
  1063. const_buffer buffer(const std::vector<T, Allocator> &data) noexcept
  1064. {
  1065. return detail::buffer_contiguous_sequence(data);
  1066. }
  1067. template<class T, class Allocator>
  1068. const_buffer buffer(const std::vector<T, Allocator> &data, size_t n_bytes) noexcept
  1069. {
  1070. return detail::buffer_contiguous_sequence(data, n_bytes);
  1071. }
  1072. // std::basic_string
  1073. template<class T, class Traits, class Allocator>
  1074. mutable_buffer buffer(std::basic_string<T, Traits, Allocator> &data) noexcept
  1075. {
  1076. return detail::buffer_contiguous_sequence(data);
  1077. }
  1078. template<class T, class Traits, class Allocator>
  1079. mutable_buffer buffer(std::basic_string<T, Traits, Allocator> &data,
  1080. size_t n_bytes) noexcept
  1081. {
  1082. return detail::buffer_contiguous_sequence(data, n_bytes);
  1083. }
  1084. template<class T, class Traits, class Allocator>
  1085. const_buffer buffer(const std::basic_string<T, Traits, Allocator> &data) noexcept
  1086. {
  1087. return detail::buffer_contiguous_sequence(data);
  1088. }
  1089. template<class T, class Traits, class Allocator>
  1090. const_buffer buffer(const std::basic_string<T, Traits, Allocator> &data,
  1091. size_t n_bytes) noexcept
  1092. {
  1093. return detail::buffer_contiguous_sequence(data, n_bytes);
  1094. }
  1095. #if CPPZMQ_HAS_STRING_VIEW
  1096. // std::basic_string_view
  1097. template<class T, class Traits>
  1098. const_buffer buffer(std::basic_string_view<T, Traits> data) noexcept
  1099. {
  1100. return detail::buffer_contiguous_sequence(data);
  1101. }
  1102. template<class T, class Traits>
  1103. const_buffer buffer(std::basic_string_view<T, Traits> data, size_t n_bytes) noexcept
  1104. {
  1105. return detail::buffer_contiguous_sequence(data, n_bytes);
  1106. }
  1107. #endif
  1108. // Buffer for a string literal (null terminated)
  1109. // where the buffer size excludes the terminating character.
  1110. // Equivalent to zmq::buffer(std::string_view("...")).
  1111. template<class Char, size_t N>
  1112. constexpr const_buffer str_buffer(const Char (&data)[N]) noexcept
  1113. {
  1114. static_assert(detail::is_pod_like<Char>::value, "Char must be POD");
  1115. #ifdef ZMQ_CPP14
  1116. assert(data[N - 1] == Char{0});
  1117. #endif
  1118. return const_buffer(static_cast<const Char *>(data), (N - 1) * sizeof(Char));
  1119. }
  1120. namespace literals
  1121. {
  1122. constexpr const_buffer operator"" _zbuf(const char *str, size_t len) noexcept
  1123. {
  1124. return const_buffer(str, len * sizeof(char));
  1125. }
  1126. constexpr const_buffer operator"" _zbuf(const wchar_t *str, size_t len) noexcept
  1127. {
  1128. return const_buffer(str, len * sizeof(wchar_t));
  1129. }
  1130. constexpr const_buffer operator"" _zbuf(const char16_t *str, size_t len) noexcept
  1131. {
  1132. return const_buffer(str, len * sizeof(char16_t));
  1133. }
  1134. constexpr const_buffer operator"" _zbuf(const char32_t *str, size_t len) noexcept
  1135. {
  1136. return const_buffer(str, len * sizeof(char32_t));
  1137. }
  1138. }
  1139. #endif // ZMQ_CPP11
  1140. #ifdef ZMQ_CPP11
  1141. namespace sockopt
  1142. {
  1143. // There are two types of options,
  1144. // integral type with known compiler time size (int, bool, int64_t, uint64_t)
  1145. // and arrays with dynamic size (strings, binary data).
  1146. // BoolUnit: if true accepts values of type bool (but passed as T into libzmq)
  1147. template<int Opt, class T, bool BoolUnit = false> struct integral_option
  1148. {
  1149. };
  1150. // NullTerm:
  1151. // 0: binary data
  1152. // 1: null-terminated string (`getsockopt` size includes null)
  1153. // 2: binary (size 32) or Z85 encoder string of size 41 (null included)
  1154. template<int Opt, int NullTerm = 1> struct array_option
  1155. {
  1156. };
  1157. #define ZMQ_DEFINE_INTEGRAL_OPT(OPT, NAME, TYPE) \
  1158. using NAME##_t = integral_option<OPT, TYPE, false>; \
  1159. ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME{}
  1160. #define ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(OPT, NAME, TYPE) \
  1161. using NAME##_t = integral_option<OPT, TYPE, true>; \
  1162. ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME{}
  1163. #define ZMQ_DEFINE_ARRAY_OPT(OPT, NAME) \
  1164. using NAME##_t = array_option<OPT>; \
  1165. ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME{}
  1166. #define ZMQ_DEFINE_ARRAY_OPT_BINARY(OPT, NAME) \
  1167. using NAME##_t = array_option<OPT, 0>; \
  1168. ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME{}
  1169. #define ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(OPT, NAME) \
  1170. using NAME##_t = array_option<OPT, 2>; \
  1171. ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME{}
  1172. // duplicate definition from libzmq 4.3.3
  1173. #if defined _WIN32
  1174. #if defined _WIN64
  1175. typedef unsigned __int64 cppzmq_fd_t;
  1176. #else
  1177. typedef unsigned int cppzmq_fd_t;
  1178. #endif
  1179. #else
  1180. typedef int cppzmq_fd_t;
  1181. #endif
  1182. #ifdef ZMQ_AFFINITY
  1183. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_AFFINITY, affinity, uint64_t);
  1184. #endif
  1185. #ifdef ZMQ_BACKLOG
  1186. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_BACKLOG, backlog, int);
  1187. #endif
  1188. #ifdef ZMQ_BINDTODEVICE
  1189. ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_BINDTODEVICE, bindtodevice);
  1190. #endif
  1191. #ifdef ZMQ_CONFLATE
  1192. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CONFLATE, conflate, int);
  1193. #endif
  1194. #ifdef ZMQ_CONNECT_ROUTING_ID
  1195. ZMQ_DEFINE_ARRAY_OPT(ZMQ_CONNECT_ROUTING_ID, connect_routing_id);
  1196. #endif
  1197. #ifdef ZMQ_CONNECT_TIMEOUT
  1198. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_CONNECT_TIMEOUT, connect_timeout, int);
  1199. #endif
  1200. #ifdef ZMQ_CURVE_PUBLICKEY
  1201. ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_PUBLICKEY, curve_publickey);
  1202. #endif
  1203. #ifdef ZMQ_CURVE_SECRETKEY
  1204. ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SECRETKEY, curve_secretkey);
  1205. #endif
  1206. #ifdef ZMQ_CURVE_SERVER
  1207. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CURVE_SERVER, curve_server, int);
  1208. #endif
  1209. #ifdef ZMQ_CURVE_SERVERKEY
  1210. ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SERVERKEY, curve_serverkey);
  1211. #endif
  1212. #ifdef ZMQ_EVENTS
  1213. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_EVENTS, events, int);
  1214. #endif
  1215. #ifdef ZMQ_FD
  1216. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_FD, fd, cppzmq_fd_t);
  1217. #endif
  1218. #ifdef ZMQ_GSSAPI_PLAINTEXT
  1219. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_PLAINTEXT, gssapi_plaintext, int);
  1220. #endif
  1221. #ifdef ZMQ_GSSAPI_SERVER
  1222. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_SERVER, gssapi_server, int);
  1223. #endif
  1224. #ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL
  1225. ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL, gssapi_service_principal);
  1226. #endif
  1227. #ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE
  1228. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE,
  1229. gssapi_service_principal_nametype,
  1230. int);
  1231. #endif
  1232. #ifdef ZMQ_GSSAPI_PRINCIPAL
  1233. ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_PRINCIPAL, gssapi_principal);
  1234. #endif
  1235. #ifdef ZMQ_GSSAPI_PRINCIPAL_NAMETYPE
  1236. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_PRINCIPAL_NAMETYPE,
  1237. gssapi_principal_nametype,
  1238. int);
  1239. #endif
  1240. #ifdef ZMQ_HANDSHAKE_IVL
  1241. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HANDSHAKE_IVL, handshake_ivl, int);
  1242. #endif
  1243. #ifdef ZMQ_HEARTBEAT_IVL
  1244. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_IVL, heartbeat_ivl, int);
  1245. #endif
  1246. #ifdef ZMQ_HEARTBEAT_TIMEOUT
  1247. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TIMEOUT, heartbeat_timeout, int);
  1248. #endif
  1249. #ifdef ZMQ_HEARTBEAT_TTL
  1250. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TTL, heartbeat_ttl, int);
  1251. #endif
  1252. #ifdef ZMQ_IMMEDIATE
  1253. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IMMEDIATE, immediate, int);
  1254. #endif
  1255. #ifdef ZMQ_INVERT_MATCHING
  1256. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_INVERT_MATCHING, invert_matching, int);
  1257. #endif
  1258. #ifdef ZMQ_IPV6
  1259. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IPV6, ipv6, int);
  1260. #endif
  1261. #ifdef ZMQ_LAST_ENDPOINT
  1262. ZMQ_DEFINE_ARRAY_OPT(ZMQ_LAST_ENDPOINT, last_endpoint);
  1263. #endif
  1264. #ifdef ZMQ_LINGER
  1265. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_LINGER, linger, int);
  1266. #endif
  1267. #ifdef ZMQ_MAXMSGSIZE
  1268. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MAXMSGSIZE, maxmsgsize, int64_t);
  1269. #endif
  1270. #ifdef ZMQ_MECHANISM
  1271. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MECHANISM, mechanism, int);
  1272. #endif
  1273. #ifdef ZMQ_METADATA
  1274. ZMQ_DEFINE_ARRAY_OPT(ZMQ_METADATA, metadata);
  1275. #endif
  1276. #ifdef ZMQ_MULTICAST_HOPS
  1277. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_HOPS, multicast_hops, int);
  1278. #endif
  1279. #ifdef ZMQ_MULTICAST_LOOP
  1280. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_MULTICAST_LOOP, multicast_loop, int);
  1281. #endif
  1282. #ifdef ZMQ_MULTICAST_MAXTPDU
  1283. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_MAXTPDU, multicast_maxtpdu, int);
  1284. #endif
  1285. #ifdef ZMQ_PLAIN_SERVER
  1286. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PLAIN_SERVER, plain_server, int);
  1287. #endif
  1288. #ifdef ZMQ_PLAIN_PASSWORD
  1289. ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_PASSWORD, plain_password);
  1290. #endif
  1291. #ifdef ZMQ_PLAIN_USERNAME
  1292. ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_USERNAME, plain_username);
  1293. #endif
  1294. #ifdef ZMQ_USE_FD
  1295. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_USE_FD, use_fd, int);
  1296. #endif
  1297. #ifdef ZMQ_PROBE_ROUTER
  1298. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PROBE_ROUTER, probe_router, int);
  1299. #endif
  1300. #ifdef ZMQ_RATE
  1301. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RATE, rate, int);
  1302. #endif
  1303. #ifdef ZMQ_RCVBUF
  1304. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVBUF, rcvbuf, int);
  1305. #endif
  1306. #ifdef ZMQ_RCVHWM
  1307. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVHWM, rcvhwm, int);
  1308. #endif
  1309. #ifdef ZMQ_RCVMORE
  1310. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_RCVMORE, rcvmore, int);
  1311. #endif
  1312. #ifdef ZMQ_RCVTIMEO
  1313. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVTIMEO, rcvtimeo, int);
  1314. #endif
  1315. #ifdef ZMQ_RECONNECT_IVL
  1316. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL, reconnect_ivl, int);
  1317. #endif
  1318. #ifdef ZMQ_RECONNECT_IVL_MAX
  1319. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL_MAX, reconnect_ivl_max, int);
  1320. #endif
  1321. #ifdef ZMQ_RECOVERY_IVL
  1322. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECOVERY_IVL, recovery_ivl, int);
  1323. #endif
  1324. #ifdef ZMQ_REQ_CORRELATE
  1325. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_CORRELATE, req_correlate, int);
  1326. #endif
  1327. #ifdef ZMQ_REQ_RELAXED
  1328. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_RELAXED, req_relaxed, int);
  1329. #endif
  1330. #ifdef ZMQ_ROUTER_HANDOVER
  1331. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_HANDOVER, router_handover, int);
  1332. #endif
  1333. #ifdef ZMQ_ROUTER_MANDATORY
  1334. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_MANDATORY, router_mandatory, int);
  1335. #endif
  1336. #ifdef ZMQ_ROUTER_NOTIFY
  1337. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_ROUTER_NOTIFY, router_notify, int);
  1338. #endif
  1339. #ifdef ZMQ_ROUTING_ID
  1340. ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_ROUTING_ID, routing_id);
  1341. #endif
  1342. #ifdef ZMQ_SNDBUF
  1343. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDBUF, sndbuf, int);
  1344. #endif
  1345. #ifdef ZMQ_SNDHWM
  1346. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDHWM, sndhwm, int);
  1347. #endif
  1348. #ifdef ZMQ_SNDTIMEO
  1349. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDTIMEO, sndtimeo, int);
  1350. #endif
  1351. #ifdef ZMQ_SOCKS_PROXY
  1352. ZMQ_DEFINE_ARRAY_OPT(ZMQ_SOCKS_PROXY, socks_proxy);
  1353. #endif
  1354. #ifdef ZMQ_STREAM_NOTIFY
  1355. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_STREAM_NOTIFY, stream_notify, int);
  1356. #endif
  1357. #ifdef ZMQ_SUBSCRIBE
  1358. ZMQ_DEFINE_ARRAY_OPT(ZMQ_SUBSCRIBE, subscribe);
  1359. #endif
  1360. #ifdef ZMQ_TCP_KEEPALIVE
  1361. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE, tcp_keepalive, int);
  1362. #endif
  1363. #ifdef ZMQ_TCP_KEEPALIVE_CNT
  1364. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_CNT, tcp_keepalive_cnt, int);
  1365. #endif
  1366. #ifdef ZMQ_TCP_KEEPALIVE_IDLE
  1367. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_IDLE, tcp_keepalive_idle, int);
  1368. #endif
  1369. #ifdef ZMQ_TCP_KEEPALIVE_INTVL
  1370. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_INTVL, tcp_keepalive_intvl, int);
  1371. #endif
  1372. #ifdef ZMQ_TCP_MAXRT
  1373. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_MAXRT, tcp_maxrt, int);
  1374. #endif
  1375. #ifdef ZMQ_THREAD_SAFE
  1376. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_THREAD_SAFE, thread_safe, int);
  1377. #endif
  1378. #ifdef ZMQ_TOS
  1379. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TOS, tos, int);
  1380. #endif
  1381. #ifdef ZMQ_TYPE
  1382. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TYPE, type, int);
  1383. #endif
  1384. #ifdef ZMQ_UNSUBSCRIBE
  1385. ZMQ_DEFINE_ARRAY_OPT(ZMQ_UNSUBSCRIBE, unsubscribe);
  1386. #endif
  1387. #ifdef ZMQ_VMCI_BUFFER_SIZE
  1388. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_SIZE, vmci_buffer_size, uint64_t);
  1389. #endif
  1390. #ifdef ZMQ_VMCI_BUFFER_MIN_SIZE
  1391. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MIN_SIZE, vmci_buffer_min_size, uint64_t);
  1392. #endif
  1393. #ifdef ZMQ_VMCI_BUFFER_MAX_SIZE
  1394. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MAX_SIZE, vmci_buffer_max_size, uint64_t);
  1395. #endif
  1396. #ifdef ZMQ_VMCI_CONNECT_TIMEOUT
  1397. ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_CONNECT_TIMEOUT, vmci_connect_timeout, int);
  1398. #endif
  1399. #ifdef ZMQ_XPUB_VERBOSE
  1400. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSE, xpub_verbose, int);
  1401. #endif
  1402. #ifdef ZMQ_XPUB_VERBOSER
  1403. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSER, xpub_verboser, int);
  1404. #endif
  1405. #ifdef ZMQ_XPUB_MANUAL
  1406. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_MANUAL, xpub_manual, int);
  1407. #endif
  1408. #ifdef ZMQ_XPUB_NODROP
  1409. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_NODROP, xpub_nodrop, int);
  1410. #endif
  1411. #ifdef ZMQ_XPUB_WELCOME_MSG
  1412. ZMQ_DEFINE_ARRAY_OPT(ZMQ_XPUB_WELCOME_MSG, xpub_welcome_msg);
  1413. #endif
  1414. #ifdef ZMQ_ZAP_ENFORCE_DOMAIN
  1415. ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ZAP_ENFORCE_DOMAIN, zap_enforce_domain, int);
  1416. #endif
  1417. #ifdef ZMQ_ZAP_DOMAIN
  1418. ZMQ_DEFINE_ARRAY_OPT(ZMQ_ZAP_DOMAIN, zap_domain);
  1419. #endif
  1420. } // namespace sockopt
  1421. #endif // ZMQ_CPP11
  1422. namespace detail
  1423. {
  1424. class socket_base
  1425. {
  1426. public:
  1427. socket_base() ZMQ_NOTHROW : _handle(ZMQ_NULLPTR) {}
  1428. ZMQ_EXPLICIT socket_base(void *handle) ZMQ_NOTHROW : _handle(handle) {}
  1429. template<typename T>
  1430. ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt")
  1431. void setsockopt(int option_, T const &optval)
  1432. {
  1433. setsockopt(option_, &optval, sizeof(T));
  1434. }
  1435. ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt")
  1436. void setsockopt(int option_, const void *optval_, size_t optvallen_)
  1437. {
  1438. int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_);
  1439. if (rc != 0)
  1440. throw error_t();
  1441. }
  1442. ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt")
  1443. void getsockopt(int option_, void *optval_, size_t *optvallen_) const
  1444. {
  1445. int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_);
  1446. if (rc != 0)
  1447. throw error_t();
  1448. }
  1449. template<typename T>
  1450. ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt")
  1451. T getsockopt(int option_) const
  1452. {
  1453. T optval;
  1454. size_t optlen = sizeof(T);
  1455. getsockopt(option_, &optval, &optlen);
  1456. return optval;
  1457. }
  1458. #ifdef ZMQ_CPP11
  1459. // Set integral socket option, e.g.
  1460. // `socket.set(zmq::sockopt::linger, 0)`
  1461. template<int Opt, class T, bool BoolUnit>
  1462. void set(sockopt::integral_option<Opt, T, BoolUnit>, const T &val)
  1463. {
  1464. static_assert(std::is_integral<T>::value, "T must be integral");
  1465. set_option(Opt, &val, sizeof val);
  1466. }
  1467. // Set integral socket option from boolean, e.g.
  1468. // `socket.set(zmq::sockopt::immediate, false)`
  1469. template<int Opt, class T>
  1470. void set(sockopt::integral_option<Opt, T, true>, bool val)
  1471. {
  1472. static_assert(std::is_integral<T>::value, "T must be integral");
  1473. T rep_val = val;
  1474. set_option(Opt, &rep_val, sizeof rep_val);
  1475. }
  1476. // Set array socket option, e.g.
  1477. // `socket.set(zmq::sockopt::plain_username, "foo123")`
  1478. template<int Opt, int NullTerm>
  1479. void set(sockopt::array_option<Opt, NullTerm>, const char *buf)
  1480. {
  1481. set_option(Opt, buf, std::strlen(buf));
  1482. }
  1483. // Set array socket option, e.g.
  1484. // `socket.set(zmq::sockopt::routing_id, zmq::buffer(id))`
  1485. template<int Opt, int NullTerm>
  1486. void set(sockopt::array_option<Opt, NullTerm>, const_buffer buf)
  1487. {
  1488. set_option(Opt, buf.data(), buf.size());
  1489. }
  1490. // Set array socket option, e.g.
  1491. // `socket.set(zmq::sockopt::routing_id, id_str)`
  1492. template<int Opt, int NullTerm>
  1493. void set(sockopt::array_option<Opt, NullTerm>, const std::string &buf)
  1494. {
  1495. set_option(Opt, buf.data(), buf.size());
  1496. }
  1497. #if CPPZMQ_HAS_STRING_VIEW
  1498. // Set array socket option, e.g.
  1499. // `socket.set(zmq::sockopt::routing_id, id_str)`
  1500. template<int Opt, int NullTerm>
  1501. void set(sockopt::array_option<Opt, NullTerm>, std::string_view buf)
  1502. {
  1503. set_option(Opt, buf.data(), buf.size());
  1504. }
  1505. #endif
  1506. // Get scalar socket option, e.g.
  1507. // `auto opt = socket.get(zmq::sockopt::linger)`
  1508. template<int Opt, class T, bool BoolUnit>
  1509. ZMQ_NODISCARD T get(sockopt::integral_option<Opt, T, BoolUnit>) const
  1510. {
  1511. static_assert(std::is_integral<T>::value, "T must be integral");
  1512. T val;
  1513. size_t size = sizeof val;
  1514. get_option(Opt, &val, &size);
  1515. assert(size == sizeof val);
  1516. return val;
  1517. }
  1518. // Get array socket option, writes to buf, returns option size in bytes, e.g.
  1519. // `size_t optsize = socket.get(zmq::sockopt::routing_id, zmq::buffer(id))`
  1520. template<int Opt, int NullTerm>
  1521. ZMQ_NODISCARD size_t get(sockopt::array_option<Opt, NullTerm>,
  1522. mutable_buffer buf) const
  1523. {
  1524. size_t size = buf.size();
  1525. get_option(Opt, buf.data(), &size);
  1526. return size;
  1527. }
  1528. // Get array socket option as string (initializes the string buffer size to init_size) e.g.
  1529. // `auto s = socket.get(zmq::sockopt::routing_id)`
  1530. // Note: removes the null character from null-terminated string options,
  1531. // i.e. the string size excludes the null character.
  1532. template<int Opt, int NullTerm>
  1533. ZMQ_NODISCARD std::string get(sockopt::array_option<Opt, NullTerm>,
  1534. size_t init_size = 1024) const
  1535. {
  1536. if (NullTerm == 2 && init_size == 1024) {
  1537. init_size = 41; // get as Z85 string
  1538. }
  1539. std::string str(init_size, '\0');
  1540. size_t size = get(sockopt::array_option<Opt>{}, buffer(str));
  1541. if (NullTerm == 1) {
  1542. if (size > 0) {
  1543. assert(str[size - 1] == '\0');
  1544. --size;
  1545. }
  1546. } else if (NullTerm == 2) {
  1547. assert(size == 32 || size == 41);
  1548. if (size == 41) {
  1549. assert(str[size - 1] == '\0');
  1550. --size;
  1551. }
  1552. }
  1553. str.resize(size);
  1554. return str;
  1555. }
  1556. #endif
  1557. void bind(std::string const &addr) { bind(addr.c_str()); }
  1558. void bind(const char *addr_)
  1559. {
  1560. int rc = zmq_bind(_handle, addr_);
  1561. if (rc != 0)
  1562. throw error_t();
  1563. }
  1564. void unbind(std::string const &addr) { unbind(addr.c_str()); }
  1565. void unbind(const char *addr_)
  1566. {
  1567. int rc = zmq_unbind(_handle, addr_);
  1568. if (rc != 0)
  1569. throw error_t();
  1570. }
  1571. void connect(std::string const &addr) { connect(addr.c_str()); }
  1572. void connect(const char *addr_)
  1573. {
  1574. int rc = zmq_connect(_handle, addr_);
  1575. if (rc != 0)
  1576. throw error_t();
  1577. }
  1578. void disconnect(std::string const &addr) { disconnect(addr.c_str()); }
  1579. void disconnect(const char *addr_)
  1580. {
  1581. int rc = zmq_disconnect(_handle, addr_);
  1582. if (rc != 0)
  1583. throw error_t();
  1584. }
  1585. bool connected() const ZMQ_NOTHROW { return (_handle != ZMQ_NULLPTR); }
  1586. ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking a const_buffer and send_flags")
  1587. size_t send(const void *buf_, size_t len_, int flags_ = 0)
  1588. {
  1589. int nbytes = zmq_send(_handle, buf_, len_, flags_);
  1590. if (nbytes >= 0)
  1591. return static_cast<size_t>(nbytes);
  1592. if (zmq_errno() == EAGAIN)
  1593. return 0;
  1594. throw error_t();
  1595. }
  1596. ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags")
  1597. bool send(message_t &msg_,
  1598. int flags_ = 0) // default until removed
  1599. {
  1600. int nbytes = zmq_msg_send(msg_.handle(), _handle, flags_);
  1601. if (nbytes >= 0)
  1602. return true;
  1603. if (zmq_errno() == EAGAIN)
  1604. return false;
  1605. throw error_t();
  1606. }
  1607. template<typename T>
  1608. ZMQ_CPP11_DEPRECATED(
  1609. "from 4.4.1, use send taking message_t or buffer (for contiguous "
  1610. "ranges), and send_flags")
  1611. bool send(T first, T last, int flags_ = 0)
  1612. {
  1613. zmq::message_t msg(first, last);
  1614. int nbytes = zmq_msg_send(msg.handle(), _handle, flags_);
  1615. if (nbytes >= 0)
  1616. return true;
  1617. if (zmq_errno() == EAGAIN)
  1618. return false;
  1619. throw error_t();
  1620. }
  1621. #ifdef ZMQ_HAS_RVALUE_REFS
  1622. ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags")
  1623. bool send(message_t &&msg_,
  1624. int flags_ = 0) // default until removed
  1625. {
  1626. #ifdef ZMQ_CPP11
  1627. return send(msg_, static_cast<send_flags>(flags_)).has_value();
  1628. #else
  1629. return send(msg_, flags_);
  1630. #endif
  1631. }
  1632. #endif
  1633. #ifdef ZMQ_CPP11
  1634. send_result_t send(const_buffer buf, send_flags flags = send_flags::none)
  1635. {
  1636. const int nbytes =
  1637. zmq_send(_handle, buf.data(), buf.size(), static_cast<int>(flags));
  1638. if (nbytes >= 0)
  1639. return static_cast<size_t>(nbytes);
  1640. if (zmq_errno() == EAGAIN)
  1641. return {};
  1642. throw error_t();
  1643. }
  1644. send_result_t send(message_t &msg, send_flags flags)
  1645. {
  1646. int nbytes = zmq_msg_send(msg.handle(), _handle, static_cast<int>(flags));
  1647. if (nbytes >= 0)
  1648. return static_cast<size_t>(nbytes);
  1649. if (zmq_errno() == EAGAIN)
  1650. return {};
  1651. throw error_t();
  1652. }
  1653. send_result_t send(message_t &&msg, send_flags flags)
  1654. {
  1655. return send(msg, flags);
  1656. }
  1657. #endif
  1658. ZMQ_CPP11_DEPRECATED(
  1659. "from 4.3.1, use recv taking a mutable_buffer and recv_flags")
  1660. size_t recv(void *buf_, size_t len_, int flags_ = 0)
  1661. {
  1662. int nbytes = zmq_recv(_handle, buf_, len_, flags_);
  1663. if (nbytes >= 0)
  1664. return static_cast<size_t>(nbytes);
  1665. if (zmq_errno() == EAGAIN)
  1666. return 0;
  1667. throw error_t();
  1668. }
  1669. ZMQ_CPP11_DEPRECATED(
  1670. "from 4.3.1, use recv taking a reference to message_t and recv_flags")
  1671. bool recv(message_t *msg_, int flags_ = 0)
  1672. {
  1673. int nbytes = zmq_msg_recv(msg_->handle(), _handle, flags_);
  1674. if (nbytes >= 0)
  1675. return true;
  1676. if (zmq_errno() == EAGAIN)
  1677. return false;
  1678. throw error_t();
  1679. }
  1680. #ifdef ZMQ_CPP11
  1681. ZMQ_NODISCARD
  1682. recv_buffer_result_t recv(mutable_buffer buf,
  1683. recv_flags flags = recv_flags::none)
  1684. {
  1685. const int nbytes =
  1686. zmq_recv(_handle, buf.data(), buf.size(), static_cast<int>(flags));
  1687. if (nbytes >= 0) {
  1688. return recv_buffer_size{
  1689. (std::min)(static_cast<size_t>(nbytes), buf.size()),
  1690. static_cast<size_t>(nbytes)};
  1691. }
  1692. if (zmq_errno() == EAGAIN)
  1693. return {};
  1694. throw error_t();
  1695. }
  1696. ZMQ_NODISCARD
  1697. recv_result_t recv(message_t &msg, recv_flags flags = recv_flags::none)
  1698. {
  1699. const int nbytes =
  1700. zmq_msg_recv(msg.handle(), _handle, static_cast<int>(flags));
  1701. if (nbytes >= 0) {
  1702. assert(msg.size() == static_cast<size_t>(nbytes));
  1703. return static_cast<size_t>(nbytes);
  1704. }
  1705. if (zmq_errno() == EAGAIN)
  1706. return {};
  1707. throw error_t();
  1708. }
  1709. #endif
  1710. #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0)
  1711. void join(const char *group)
  1712. {
  1713. int rc = zmq_join(_handle, group);
  1714. if (rc != 0)
  1715. throw error_t();
  1716. }
  1717. void leave(const char *group)
  1718. {
  1719. int rc = zmq_leave(_handle, group);
  1720. if (rc != 0)
  1721. throw error_t();
  1722. }
  1723. #endif
  1724. ZMQ_NODISCARD void *handle() ZMQ_NOTHROW { return _handle; }
  1725. ZMQ_NODISCARD const void *handle() const ZMQ_NOTHROW { return _handle; }
  1726. ZMQ_EXPLICIT operator bool() const ZMQ_NOTHROW { return _handle != ZMQ_NULLPTR; }
  1727. // note: non-const operator bool can be removed once
  1728. // operator void* is removed from socket_t
  1729. ZMQ_EXPLICIT operator bool() ZMQ_NOTHROW { return _handle != ZMQ_NULLPTR; }
  1730. protected:
  1731. void *_handle;
  1732. private:
  1733. void set_option(int option_, const void *optval_, size_t optvallen_)
  1734. {
  1735. int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_);
  1736. if (rc != 0)
  1737. throw error_t();
  1738. }
  1739. void get_option(int option_, void *optval_, size_t *optvallen_) const
  1740. {
  1741. int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_);
  1742. if (rc != 0)
  1743. throw error_t();
  1744. }
  1745. };
  1746. } // namespace detail
  1747. #ifdef ZMQ_CPP11
  1748. enum class socket_type : int
  1749. {
  1750. req = ZMQ_REQ,
  1751. rep = ZMQ_REP,
  1752. dealer = ZMQ_DEALER,
  1753. router = ZMQ_ROUTER,
  1754. pub = ZMQ_PUB,
  1755. sub = ZMQ_SUB,
  1756. xpub = ZMQ_XPUB,
  1757. xsub = ZMQ_XSUB,
  1758. push = ZMQ_PUSH,
  1759. pull = ZMQ_PULL,
  1760. #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0)
  1761. server = ZMQ_SERVER,
  1762. client = ZMQ_CLIENT,
  1763. radio = ZMQ_RADIO,
  1764. dish = ZMQ_DISH,
  1765. #endif
  1766. #if ZMQ_VERSION_MAJOR >= 4
  1767. stream = ZMQ_STREAM,
  1768. #endif
  1769. pair = ZMQ_PAIR
  1770. };
  1771. #endif
  1772. struct from_handle_t
  1773. {
  1774. struct _private
  1775. {
  1776. }; // disabling use other than with from_handle
  1777. ZMQ_CONSTEXPR_FN ZMQ_EXPLICIT from_handle_t(_private /*p*/) ZMQ_NOTHROW {}
  1778. };
  1779. ZMQ_CONSTEXPR_VAR from_handle_t from_handle =
  1780. from_handle_t(from_handle_t::_private());
  1781. // A non-owning nullable reference to a socket.
  1782. // The reference is invalidated on socket close or destruction.
  1783. class socket_ref : public detail::socket_base
  1784. {
  1785. public:
  1786. socket_ref() ZMQ_NOTHROW : detail::socket_base() {}
  1787. #ifdef ZMQ_CPP11
  1788. socket_ref(std::nullptr_t) ZMQ_NOTHROW : detail::socket_base() {}
  1789. #endif
  1790. socket_ref(from_handle_t /*fh*/, void *handle) ZMQ_NOTHROW
  1791. : detail::socket_base(handle)
  1792. {
  1793. }
  1794. };
  1795. #ifdef ZMQ_CPP11
  1796. inline bool operator==(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW
  1797. {
  1798. return sr.handle() == nullptr;
  1799. }
  1800. inline bool operator==(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW
  1801. {
  1802. return sr.handle() == nullptr;
  1803. }
  1804. inline bool operator!=(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW
  1805. {
  1806. return !(sr == nullptr);
  1807. }
  1808. inline bool operator!=(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW
  1809. {
  1810. return !(sr == nullptr);
  1811. }
  1812. #endif
  1813. inline bool operator==(socket_ref a, socket_ref b) ZMQ_NOTHROW
  1814. {
  1815. return std::equal_to<void *>()(a.handle(), b.handle());
  1816. }
  1817. inline bool operator!=(socket_ref a, socket_ref b) ZMQ_NOTHROW
  1818. {
  1819. return !(a == b);
  1820. }
  1821. inline bool operator<(socket_ref a, socket_ref b) ZMQ_NOTHROW
  1822. {
  1823. return std::less<void *>()(a.handle(), b.handle());
  1824. }
  1825. inline bool operator>(socket_ref a, socket_ref b) ZMQ_NOTHROW
  1826. {
  1827. return b < a;
  1828. }
  1829. inline bool operator<=(socket_ref a, socket_ref b) ZMQ_NOTHROW
  1830. {
  1831. return !(a > b);
  1832. }
  1833. inline bool operator>=(socket_ref a, socket_ref b) ZMQ_NOTHROW
  1834. {
  1835. return !(a < b);
  1836. }
  1837. } // namespace zmq
  1838. #ifdef ZMQ_CPP11
  1839. namespace std
  1840. {
  1841. template<> struct hash<zmq::socket_ref>
  1842. {
  1843. size_t operator()(zmq::socket_ref sr) const ZMQ_NOTHROW
  1844. {
  1845. return hash<void *>()(sr.handle());
  1846. }
  1847. };
  1848. } // namespace std
  1849. #endif
  1850. namespace zmq
  1851. {
  1852. class socket_t : public detail::socket_base
  1853. {
  1854. friend class monitor_t;
  1855. public:
  1856. socket_t() ZMQ_NOTHROW : detail::socket_base(ZMQ_NULLPTR), ctxptr(ZMQ_NULLPTR) {}
  1857. socket_t(context_t &context_, int type_) :
  1858. detail::socket_base(zmq_socket(context_.handle(), type_)),
  1859. ctxptr(context_.handle())
  1860. {
  1861. if (_handle == ZMQ_NULLPTR)
  1862. throw error_t();
  1863. }
  1864. #ifdef ZMQ_CPP11
  1865. socket_t(context_t &context_, socket_type type_) :
  1866. socket_t(context_, static_cast<int>(type_))
  1867. {
  1868. }
  1869. #endif
  1870. #ifdef ZMQ_HAS_RVALUE_REFS
  1871. socket_t(socket_t &&rhs) ZMQ_NOTHROW : detail::socket_base(rhs._handle),
  1872. ctxptr(rhs.ctxptr)
  1873. {
  1874. rhs._handle = ZMQ_NULLPTR;
  1875. rhs.ctxptr = ZMQ_NULLPTR;
  1876. }
  1877. socket_t &operator=(socket_t &&rhs) ZMQ_NOTHROW
  1878. {
  1879. close();
  1880. std::swap(_handle, rhs._handle);
  1881. return *this;
  1882. }
  1883. #endif
  1884. ~socket_t() ZMQ_NOTHROW { close(); }
  1885. operator void *() ZMQ_NOTHROW { return _handle; }
  1886. operator void const *() const ZMQ_NOTHROW { return _handle; }
  1887. void close() ZMQ_NOTHROW
  1888. {
  1889. if (_handle == ZMQ_NULLPTR)
  1890. // already closed
  1891. return;
  1892. int rc = zmq_close(_handle);
  1893. ZMQ_ASSERT(rc == 0);
  1894. _handle = ZMQ_NULLPTR;
  1895. }
  1896. void swap(socket_t &other) ZMQ_NOTHROW
  1897. {
  1898. std::swap(_handle, other._handle);
  1899. std::swap(ctxptr, other.ctxptr);
  1900. }
  1901. operator socket_ref() ZMQ_NOTHROW { return socket_ref(from_handle, _handle); }
  1902. private:
  1903. void *ctxptr;
  1904. socket_t(const socket_t &) ZMQ_DELETED_FUNCTION;
  1905. void operator=(const socket_t &) ZMQ_DELETED_FUNCTION;
  1906. // used by monitor_t
  1907. socket_t(void *context_, int type_) :
  1908. detail::socket_base(zmq_socket(context_, type_)), ctxptr(context_)
  1909. {
  1910. if (_handle == ZMQ_NULLPTR)
  1911. throw error_t();
  1912. }
  1913. };
  1914. inline void swap(socket_t &a, socket_t &b) ZMQ_NOTHROW
  1915. {
  1916. a.swap(b);
  1917. }
  1918. ZMQ_DEPRECATED("from 4.3.1, use proxy taking socket_t objects")
  1919. inline void proxy(void *frontend, void *backend, void *capture)
  1920. {
  1921. int rc = zmq_proxy(frontend, backend, capture);
  1922. if (rc != 0)
  1923. throw error_t();
  1924. }
  1925. inline void
  1926. proxy(socket_ref frontend, socket_ref backend, socket_ref capture = socket_ref())
  1927. {
  1928. int rc = zmq_proxy(frontend.handle(), backend.handle(), capture.handle());
  1929. if (rc != 0)
  1930. throw error_t();
  1931. }
  1932. #ifdef ZMQ_HAS_PROXY_STEERABLE
  1933. ZMQ_DEPRECATED("from 4.3.1, use proxy_steerable taking socket_t objects")
  1934. inline void
  1935. proxy_steerable(void *frontend, void *backend, void *capture, void *control)
  1936. {
  1937. int rc = zmq_proxy_steerable(frontend, backend, capture, control);
  1938. if (rc != 0)
  1939. throw error_t();
  1940. }
  1941. inline void proxy_steerable(socket_ref frontend,
  1942. socket_ref backend,
  1943. socket_ref capture,
  1944. socket_ref control)
  1945. {
  1946. int rc = zmq_proxy_steerable(frontend.handle(), backend.handle(),
  1947. capture.handle(), control.handle());
  1948. if (rc != 0)
  1949. throw error_t();
  1950. }
  1951. #endif
  1952. class monitor_t
  1953. {
  1954. public:
  1955. monitor_t() : _socket(), _monitor_socket() {}
  1956. virtual ~monitor_t() { close(); }
  1957. #ifdef ZMQ_HAS_RVALUE_REFS
  1958. monitor_t(monitor_t &&rhs) ZMQ_NOTHROW : _socket(), _monitor_socket()
  1959. {
  1960. std::swap(_socket, rhs._socket);
  1961. std::swap(_monitor_socket, rhs._monitor_socket);
  1962. }
  1963. monitor_t &operator=(monitor_t &&rhs) ZMQ_NOTHROW
  1964. {
  1965. close();
  1966. _socket = socket_ref();
  1967. std::swap(_socket, rhs._socket);
  1968. std::swap(_monitor_socket, rhs._monitor_socket);
  1969. return *this;
  1970. }
  1971. #endif
  1972. void
  1973. monitor(socket_t &socket, std::string const &addr, int events = ZMQ_EVENT_ALL)
  1974. {
  1975. monitor(socket, addr.c_str(), events);
  1976. }
  1977. void monitor(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL)
  1978. {
  1979. init(socket, addr_, events);
  1980. while (true) {
  1981. check_event(-1);
  1982. }
  1983. }
  1984. void init(socket_t &socket, std::string const &addr, int events = ZMQ_EVENT_ALL)
  1985. {
  1986. init(socket, addr.c_str(), events);
  1987. }
  1988. void init(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL)
  1989. {
  1990. int rc = zmq_socket_monitor(socket.handle(), addr_, events);
  1991. if (rc != 0)
  1992. throw error_t();
  1993. _socket = socket;
  1994. _monitor_socket = socket_t(socket.ctxptr, ZMQ_PAIR);
  1995. _monitor_socket.connect(addr_);
  1996. on_monitor_started();
  1997. }
  1998. bool check_event(int timeout = 0)
  1999. {
  2000. assert(_monitor_socket);
  2001. zmq_msg_t eventMsg;
  2002. zmq_msg_init(&eventMsg);
  2003. zmq::pollitem_t items[] = {
  2004. {_monitor_socket.handle(), 0, ZMQ_POLLIN, 0},
  2005. };
  2006. zmq::poll(&items[0], 1, timeout);
  2007. if (items[0].revents & ZMQ_POLLIN) {
  2008. int rc = zmq_msg_recv(&eventMsg, _monitor_socket.handle(), 0);
  2009. if (rc == -1 && zmq_errno() == ETERM)
  2010. return false;
  2011. assert(rc != -1);
  2012. } else {
  2013. zmq_msg_close(&eventMsg);
  2014. return false;
  2015. }
  2016. #if ZMQ_VERSION_MAJOR >= 4
  2017. const char *data = static_cast<const char *>(zmq_msg_data(&eventMsg));
  2018. zmq_event_t msgEvent;
  2019. memcpy(&msgEvent.event, data, sizeof(uint16_t));
  2020. data += sizeof(uint16_t);
  2021. memcpy(&msgEvent.value, data, sizeof(int32_t));
  2022. zmq_event_t *event = &msgEvent;
  2023. #else
  2024. zmq_event_t *event = static_cast<zmq_event_t *>(zmq_msg_data(&eventMsg));
  2025. #endif
  2026. #ifdef ZMQ_NEW_MONITOR_EVENT_LAYOUT
  2027. zmq_msg_t addrMsg;
  2028. zmq_msg_init(&addrMsg);
  2029. int rc = zmq_msg_recv(&addrMsg, _monitor_socket.handle(), 0);
  2030. if (rc == -1 && zmq_errno() == ETERM) {
  2031. zmq_msg_close(&eventMsg);
  2032. return false;
  2033. }
  2034. assert(rc != -1);
  2035. const char *str = static_cast<const char *>(zmq_msg_data(&addrMsg));
  2036. std::string address(str, str + zmq_msg_size(&addrMsg));
  2037. zmq_msg_close(&addrMsg);
  2038. #else
  2039. // Bit of a hack, but all events in the zmq_event_t union have the same layout so this will work for all event types.
  2040. std::string address = event->data.connected.addr;
  2041. #endif
  2042. #ifdef ZMQ_EVENT_MONITOR_STOPPED
  2043. if (event->event == ZMQ_EVENT_MONITOR_STOPPED) {
  2044. zmq_msg_close(&eventMsg);
  2045. return false;
  2046. }
  2047. #endif
  2048. switch (event->event) {
  2049. case ZMQ_EVENT_CONNECTED:
  2050. on_event_connected(*event, address.c_str());
  2051. break;
  2052. case ZMQ_EVENT_CONNECT_DELAYED:
  2053. on_event_connect_delayed(*event, address.c_str());
  2054. break;
  2055. case ZMQ_EVENT_CONNECT_RETRIED:
  2056. on_event_connect_retried(*event, address.c_str());
  2057. break;
  2058. case ZMQ_EVENT_LISTENING:
  2059. on_event_listening(*event, address.c_str());
  2060. break;
  2061. case ZMQ_EVENT_BIND_FAILED:
  2062. on_event_bind_failed(*event, address.c_str());
  2063. break;
  2064. case ZMQ_EVENT_ACCEPTED:
  2065. on_event_accepted(*event, address.c_str());
  2066. break;
  2067. case ZMQ_EVENT_ACCEPT_FAILED:
  2068. on_event_accept_failed(*event, address.c_str());
  2069. break;
  2070. case ZMQ_EVENT_CLOSED:
  2071. on_event_closed(*event, address.c_str());
  2072. break;
  2073. case ZMQ_EVENT_CLOSE_FAILED:
  2074. on_event_close_failed(*event, address.c_str());
  2075. break;
  2076. case ZMQ_EVENT_DISCONNECTED:
  2077. on_event_disconnected(*event, address.c_str());
  2078. break;
  2079. #ifdef ZMQ_BUILD_DRAFT_API
  2080. #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3)
  2081. case ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL:
  2082. on_event_handshake_failed_no_detail(*event, address.c_str());
  2083. break;
  2084. case ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL:
  2085. on_event_handshake_failed_protocol(*event, address.c_str());
  2086. break;
  2087. case ZMQ_EVENT_HANDSHAKE_FAILED_AUTH:
  2088. on_event_handshake_failed_auth(*event, address.c_str());
  2089. break;
  2090. case ZMQ_EVENT_HANDSHAKE_SUCCEEDED:
  2091. on_event_handshake_succeeded(*event, address.c_str());
  2092. break;
  2093. #elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1)
  2094. case ZMQ_EVENT_HANDSHAKE_FAILED:
  2095. on_event_handshake_failed(*event, address.c_str());
  2096. break;
  2097. case ZMQ_EVENT_HANDSHAKE_SUCCEED:
  2098. on_event_handshake_succeed(*event, address.c_str());
  2099. break;
  2100. #endif
  2101. #endif
  2102. default:
  2103. on_event_unknown(*event, address.c_str());
  2104. break;
  2105. }
  2106. zmq_msg_close(&eventMsg);
  2107. return true;
  2108. }
  2109. #ifdef ZMQ_EVENT_MONITOR_STOPPED
  2110. void abort()
  2111. {
  2112. if (_socket)
  2113. zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0);
  2114. _socket = socket_ref();
  2115. }
  2116. #endif
  2117. virtual void on_monitor_started() {}
  2118. virtual void on_event_connected(const zmq_event_t &event_, const char *addr_)
  2119. {
  2120. (void) event_;
  2121. (void) addr_;
  2122. }
  2123. virtual void on_event_connect_delayed(const zmq_event_t &event_,
  2124. const char *addr_)
  2125. {
  2126. (void) event_;
  2127. (void) addr_;
  2128. }
  2129. virtual void on_event_connect_retried(const zmq_event_t &event_,
  2130. const char *addr_)
  2131. {
  2132. (void) event_;
  2133. (void) addr_;
  2134. }
  2135. virtual void on_event_listening(const zmq_event_t &event_, const char *addr_)
  2136. {
  2137. (void) event_;
  2138. (void) addr_;
  2139. }
  2140. virtual void on_event_bind_failed(const zmq_event_t &event_, const char *addr_)
  2141. {
  2142. (void) event_;
  2143. (void) addr_;
  2144. }
  2145. virtual void on_event_accepted(const zmq_event_t &event_, const char *addr_)
  2146. {
  2147. (void) event_;
  2148. (void) addr_;
  2149. }
  2150. virtual void on_event_accept_failed(const zmq_event_t &event_, const char *addr_)
  2151. {
  2152. (void) event_;
  2153. (void) addr_;
  2154. }
  2155. virtual void on_event_closed(const zmq_event_t &event_, const char *addr_)
  2156. {
  2157. (void) event_;
  2158. (void) addr_;
  2159. }
  2160. virtual void on_event_close_failed(const zmq_event_t &event_, const char *addr_)
  2161. {
  2162. (void) event_;
  2163. (void) addr_;
  2164. }
  2165. virtual void on_event_disconnected(const zmq_event_t &event_, const char *addr_)
  2166. {
  2167. (void) event_;
  2168. (void) addr_;
  2169. }
  2170. #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3)
  2171. virtual void on_event_handshake_failed_no_detail(const zmq_event_t &event_,
  2172. const char *addr_)
  2173. {
  2174. (void) event_;
  2175. (void) addr_;
  2176. }
  2177. virtual void on_event_handshake_failed_protocol(const zmq_event_t &event_,
  2178. const char *addr_)
  2179. {
  2180. (void) event_;
  2181. (void) addr_;
  2182. }
  2183. virtual void on_event_handshake_failed_auth(const zmq_event_t &event_,
  2184. const char *addr_)
  2185. {
  2186. (void) event_;
  2187. (void) addr_;
  2188. }
  2189. virtual void on_event_handshake_succeeded(const zmq_event_t &event_,
  2190. const char *addr_)
  2191. {
  2192. (void) event_;
  2193. (void) addr_;
  2194. }
  2195. #elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1)
  2196. virtual void on_event_handshake_failed(const zmq_event_t &event_,
  2197. const char *addr_)
  2198. {
  2199. (void) event_;
  2200. (void) addr_;
  2201. }
  2202. virtual void on_event_handshake_succeed(const zmq_event_t &event_,
  2203. const char *addr_)
  2204. {
  2205. (void) event_;
  2206. (void) addr_;
  2207. }
  2208. #endif
  2209. virtual void on_event_unknown(const zmq_event_t &event_, const char *addr_)
  2210. {
  2211. (void) event_;
  2212. (void) addr_;
  2213. }
  2214. private:
  2215. monitor_t(const monitor_t &) ZMQ_DELETED_FUNCTION;
  2216. void operator=(const monitor_t &) ZMQ_DELETED_FUNCTION;
  2217. socket_ref _socket;
  2218. socket_t _monitor_socket;
  2219. void close() ZMQ_NOTHROW
  2220. {
  2221. if (_socket)
  2222. zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0);
  2223. _monitor_socket.close();
  2224. }
  2225. };
  2226. #if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
  2227. // polling events
  2228. enum class event_flags : short
  2229. {
  2230. none = 0,
  2231. pollin = ZMQ_POLLIN,
  2232. pollout = ZMQ_POLLOUT,
  2233. pollerr = ZMQ_POLLERR,
  2234. pollpri = ZMQ_POLLPRI
  2235. };
  2236. constexpr event_flags operator|(event_flags a, event_flags b) noexcept
  2237. {
  2238. return detail::enum_bit_or(a, b);
  2239. }
  2240. constexpr event_flags operator&(event_flags a, event_flags b) noexcept
  2241. {
  2242. return detail::enum_bit_and(a, b);
  2243. }
  2244. constexpr event_flags operator^(event_flags a, event_flags b) noexcept
  2245. {
  2246. return detail::enum_bit_xor(a, b);
  2247. }
  2248. constexpr event_flags operator~(event_flags a) noexcept
  2249. {
  2250. return detail::enum_bit_not(a);
  2251. }
  2252. struct no_user_data;
  2253. // layout compatible with zmq_poller_event_t
  2254. template<class T = no_user_data> struct poller_event
  2255. {
  2256. socket_ref socket;
  2257. #ifdef _WIN32
  2258. SOCKET fd;
  2259. #else
  2260. int fd;
  2261. #endif
  2262. T *user_data;
  2263. event_flags events;
  2264. };
  2265. template<typename T = no_user_data> class poller_t
  2266. {
  2267. public:
  2268. using event_type = poller_event<T>;
  2269. poller_t() : poller_ptr(zmq_poller_new())
  2270. {
  2271. if (!poller_ptr)
  2272. throw error_t();
  2273. }
  2274. template<
  2275. typename Dummy = void,
  2276. typename =
  2277. typename std::enable_if<!std::is_same<T, no_user_data>::value, Dummy>::type>
  2278. void add(zmq::socket_ref socket, event_flags events, T *user_data)
  2279. {
  2280. add_impl(socket, events, user_data);
  2281. }
  2282. void add(zmq::socket_ref socket, event_flags events)
  2283. {
  2284. add_impl(socket, events, nullptr);
  2285. }
  2286. void remove(zmq::socket_ref socket)
  2287. {
  2288. if (0 != zmq_poller_remove(poller_ptr.get(), socket.handle())) {
  2289. throw error_t();
  2290. }
  2291. }
  2292. void modify(zmq::socket_ref socket, event_flags events)
  2293. {
  2294. if (0
  2295. != zmq_poller_modify(poller_ptr.get(), socket.handle(),
  2296. static_cast<short>(events))) {
  2297. throw error_t();
  2298. }
  2299. }
  2300. size_t wait_all(std::vector<event_type> &poller_events,
  2301. const std::chrono::milliseconds timeout)
  2302. {
  2303. int rc = zmq_poller_wait_all(
  2304. poller_ptr.get(),
  2305. reinterpret_cast<zmq_poller_event_t *>(poller_events.data()),
  2306. static_cast<int>(poller_events.size()),
  2307. static_cast<long>(timeout.count()));
  2308. if (rc > 0)
  2309. return static_cast<size_t>(rc);
  2310. #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3)
  2311. if (zmq_errno() == EAGAIN)
  2312. #else
  2313. if (zmq_errno() == ETIMEDOUT)
  2314. #endif
  2315. return 0;
  2316. throw error_t();
  2317. }
  2318. private:
  2319. struct destroy_poller_t
  2320. {
  2321. void operator()(void *ptr) noexcept
  2322. {
  2323. int rc = zmq_poller_destroy(&ptr);
  2324. ZMQ_ASSERT(rc == 0);
  2325. }
  2326. };
  2327. std::unique_ptr<void, destroy_poller_t> poller_ptr;
  2328. void add_impl(zmq::socket_ref socket, event_flags events, T *user_data)
  2329. {
  2330. if (0
  2331. != zmq_poller_add(poller_ptr.get(), socket.handle(), user_data,
  2332. static_cast<short>(events))) {
  2333. throw error_t();
  2334. }
  2335. }
  2336. };
  2337. #endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
  2338. inline std::ostream &operator<<(std::ostream &os, const message_t &msg)
  2339. {
  2340. return os << msg.str();
  2341. }
  2342. } // namespace zmq
  2343. #endif // __ZMQ_HPP_INCLUDED__