zmq.hpp 6.26 KB
Newer Older
Martin Sustrik's avatar
Martin Sustrik committed
1
/*
2
    Copyright (c) 2007-2010 iMatix Corporation
Martin Sustrik's avatar
Martin Sustrik committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

    This file is part of 0MQ.

    0MQ is free software; you can redistribute it and/or modify it under
    the terms of the Lesser GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    0MQ is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    Lesser GNU General Public License for more details.

    You should have received a copy of the Lesser GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

Martin Sustrik's avatar
Martin Sustrik committed
20 21
#ifndef __ZMQ_HPP_INCLUDED__
#define __ZMQ_HPP_INCLUDED__
Martin Sustrik's avatar
Martin Sustrik committed
22

Martin Sustrik's avatar
Martin Sustrik committed
23
#include "zmq.h"
Martin Sustrik's avatar
Martin Sustrik committed
24 25

#include <assert.h>
26
#include <errno.h>
Martin Sustrik's avatar
Martin Sustrik committed
27
#include <string.h>
28
#include <exception>
Martin Sustrik's avatar
Martin Sustrik committed
29

Martin Sustrik's avatar
Martin Sustrik committed
30
namespace zmq
Martin Sustrik's avatar
Martin Sustrik committed
31 32
{

Martin Sustrik's avatar
Martin Sustrik committed
33
    typedef zmq_free_fn free_fn;
34 35
    typedef zmq_pollitem_t pollitem_t;

Martin Sustrik's avatar
Martin Sustrik committed
36
    class error_t : public std::exception
37
    {
Martin Sustrik's avatar
Martin Sustrik committed
38
    public:
39

Martin Sustrik's avatar
Martin Sustrik committed
40
        error_t () : errnum (errno) {}
41

Martin Sustrik's avatar
Martin Sustrik committed
42
        virtual const char *what () const throw ()
43
        {
44
            return zmq_strerror (errnum);
45 46
        }

Martin Sustrik's avatar
Martin Sustrik committed
47 48 49
    private:

        int errnum;
50 51
    };

unknown's avatar
unknown committed
52 53 54 55 56 57 58 59
    inline int poll (zmq_pollitem_t *items_, int nitems_, long timeout_ = -1)
    {
        int rc = zmq_poll (items_, nitems_, timeout_);
        if (rc < 0)
            throw error_t ();
        return rc;
    }

60
    class message_t : private zmq_msg_t
Martin Sustrik's avatar
Martin Sustrik committed
61 62 63 64 65
    {
        friend class socket_t;

    public:

66 67 68 69 70 71 72 73
        inline message_t ()
        {
            int rc = zmq_msg_init (this);
            if (rc != 0)
                throw error_t ();
        }

        inline message_t (size_t size_)
Martin Sustrik's avatar
Martin Sustrik committed
74
        {
Martin Sustrik's avatar
Martin Sustrik committed
75
            int rc = zmq_msg_init_size (this, size_);
Martin Sustrik's avatar
Martin Sustrik committed
76 77
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
78 79
        }

80 81
        inline message_t (void *data_, size_t size_, free_fn *ffn_,
            void *hint_ = NULL)
Martin Sustrik's avatar
Martin Sustrik committed
82
        {
83
            int rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
Martin Sustrik's avatar
Martin Sustrik committed
84 85
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
86 87 88 89
        }

        inline ~message_t ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
90
            int rc = zmq_msg_close (this);
Martin Sustrik's avatar
Martin Sustrik committed
91 92
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
93 94
        }

95 96 97 98 99 100 101 102 103 104
        inline void rebuild ()
        {
            int rc = zmq_msg_close (this);
            if (rc != 0)
                throw error_t ();
            rc = zmq_msg_init (this);
            if (rc != 0)
                throw error_t ();
        }

Martin Sustrik's avatar
Martin Sustrik committed
105 106
        inline void rebuild (size_t size_)
        {
Martin Sustrik's avatar
Martin Sustrik committed
107
            int rc = zmq_msg_close (this);
Martin Sustrik's avatar
Martin Sustrik committed
108 109
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
110
            rc = zmq_msg_init_size (this, size_);
Martin Sustrik's avatar
Martin Sustrik committed
111 112
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
113 114
        }

115 116
        inline void rebuild (void *data_, size_t size_, free_fn *ffn_,
            void *hint_ = NULL)
Martin Sustrik's avatar
Martin Sustrik committed
117
        {
Martin Sustrik's avatar
Martin Sustrik committed
118
            int rc = zmq_msg_close (this);
Martin Sustrik's avatar
Martin Sustrik committed
119 120
            if (rc != 0)
                throw error_t ();
121
            rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
Martin Sustrik's avatar
Martin Sustrik committed
122 123
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
124 125
        }

126
        inline void move (message_t *msg_)
Martin Sustrik's avatar
Martin Sustrik committed
127
        {
128
            int rc = zmq_msg_move (this, (zmq_msg_t*) msg_);
Martin Sustrik's avatar
Martin Sustrik committed
129 130
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
131 132
        }

133
        inline void copy (message_t *msg_)
Martin Sustrik's avatar
Martin Sustrik committed
134
        {
135
            int rc = zmq_msg_copy (this, (zmq_msg_t*) msg_);
Martin Sustrik's avatar
Martin Sustrik committed
136 137
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
138 139 140 141
        }

        inline void *data ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
142
            return zmq_msg_data (this);
Martin Sustrik's avatar
Martin Sustrik committed
143 144 145 146
        }

        inline size_t size ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
147
            return zmq_msg_size (this);
Martin Sustrik's avatar
Martin Sustrik committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
        }

    private:

        //  Disable implicit message copying, so that users won't use shared
        //  messages (less efficient) without being aware of the fact.
        message_t (const message_t&);
        void operator = (const message_t&);
    };

    class context_t
    {
        friend class socket_t;

    public:

164
        inline context_t (int app_threads_, int io_threads_, int flags_ = 0)
Martin Sustrik's avatar
Martin Sustrik committed
165
        {
166
            ptr = zmq_init (app_threads_, io_threads_, flags_);
Martin Sustrik's avatar
Martin Sustrik committed
167 168
            if (ptr == NULL)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
169 170 171 172
        }

        inline ~context_t ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
173
            int rc = zmq_term (ptr);
Martin Sustrik's avatar
Martin Sustrik committed
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
            assert (rc == 0);
        }

    private:

        void *ptr;

        context_t (const context_t&);
        void operator = (const context_t&);
    };

    class socket_t
    {
    public:

189
        inline socket_t (context_t &context_, int type_)
Martin Sustrik's avatar
Martin Sustrik committed
190
        {
Martin Sustrik's avatar
Martin Sustrik committed
191
            ptr = zmq_socket (context_.ptr, type_);
Martin Sustrik's avatar
Martin Sustrik committed
192 193
            if (ptr == NULL)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
194 195 196 197
        }

        inline ~socket_t ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
198
            int rc = zmq_close (ptr);
Martin Sustrik's avatar
Martin Sustrik committed
199 200
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
201 202
        }

203 204 205 206 207
        inline operator void* ()
        {
            return ptr;
        }

208 209
        inline void setsockopt (int option_, const void *optval_,
            size_t optvallen_)
Martin Sustrik's avatar
Martin Sustrik committed
210
        {
211
            int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_);
Martin Sustrik's avatar
Martin Sustrik committed
212 213
            if (rc != 0)
                throw error_t ();
214 215 216 217 218
        }

        inline void bind (const char *addr_)
        {
            int rc = zmq_bind (ptr, addr_);
Martin Sustrik's avatar
Martin Sustrik committed
219 220
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
221 222
        }

223
        inline void connect (const char *addr_)
Martin Sustrik's avatar
Martin Sustrik committed
224
        {
225
            int rc = zmq_connect (ptr, addr_);
Martin Sustrik's avatar
Martin Sustrik committed
226 227
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
228 229
        }

Martin Sustrik's avatar
Martin Sustrik committed
230
        inline bool send (message_t &msg_, int flags_ = 0)
Martin Sustrik's avatar
Martin Sustrik committed
231
        {
Martin Sustrik's avatar
Martin Sustrik committed
232
            int rc = zmq_send (ptr, &msg_, flags_);
Martin Sustrik's avatar
Martin Sustrik committed
233 234 235 236 237
            if (rc == 0)
                return true;
            if (rc == -1 && errno == EAGAIN)
                return false;
            throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
238 239 240 241
        }

        inline void flush ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
242
            int rc = zmq_flush (ptr);
Martin Sustrik's avatar
Martin Sustrik committed
243 244
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
245 246
        }

Martin Sustrik's avatar
Martin Sustrik committed
247
        inline bool recv (message_t *msg_, int flags_ = 0)
Martin Sustrik's avatar
Martin Sustrik committed
248
        {
Martin Sustrik's avatar
Martin Sustrik committed
249
            int rc = zmq_recv (ptr, msg_, flags_);
Martin Sustrik's avatar
Martin Sustrik committed
250 251 252 253 254
            if (rc == 0)
                return true;
            if (rc == -1 && errno == EAGAIN)
                return false;
            throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
255 256 257 258 259 260 261 262 263 264 265 266 267
        }

    private:

        void *ptr;

        socket_t (const socket_t&);
        void operator = (const socket_t&);
    };

}

#endif