zmq.hpp 6.51 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

    This file is part of 0MQ.

    0MQ is free software; you can redistribute it and/or modify it under
7
    the terms of the GNU Lesser General Public License as published by
Martin Sustrik's avatar
Martin Sustrik committed
8 9 10 11 12 13
    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
14
    GNU Lesser General Public License for more details.
Martin Sustrik's avatar
Martin Sustrik committed
15

16
    You should have received a copy of the GNU Lesser General Public License
Martin Sustrik's avatar
Martin Sustrik committed
17 18 19
    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 26
#include <cassert>
#include <cstring>
27
#include <exception>
Martin Sustrik's avatar
Martin Sustrik committed
28

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

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

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

39
        error_t () : errnum (zmq_errno ()) {}
40

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

46 47 48 49 50
        int num () const
        {
            return errnum;
        }

Martin Sustrik's avatar
Martin Sustrik committed
51 52 53
    private:

        int errnum;
54 55
    };

unknown's avatar
unknown committed
56 57 58 59 60 61 62 63
    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;
    }

64 65 66 67 68 69 70
    inline void device (int device_, void * insocket_, void* outsocket_)
    {
        int rc = zmq_device (device_, insocket_, outsocket_);
        if (rc != 0)
            throw error_t ();
    }

71
    class message_t : private zmq_msg_t
Martin Sustrik's avatar
Martin Sustrik committed
72 73 74 75 76
    {
        friend class socket_t;

    public:

77 78 79 80 81 82 83 84
        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
85
        {
Martin Sustrik's avatar
Martin Sustrik committed
86
            int rc = zmq_msg_init_size (this, size_);
Martin Sustrik's avatar
Martin Sustrik committed
87 88
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
89 90
        }

91 92
        inline message_t (void *data_, size_t size_, free_fn *ffn_,
            void *hint_ = NULL)
Martin Sustrik's avatar
Martin Sustrik committed
93
        {
94
            int rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
Martin Sustrik's avatar
Martin Sustrik committed
95 96
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
97 98 99 100
        }

        inline ~message_t ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
101
            int rc = zmq_msg_close (this);
102
            assert (rc == 0);
Martin Sustrik's avatar
Martin Sustrik committed
103 104
        }

105 106 107 108 109 110 111 112 113 114
        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
115 116
        inline void rebuild (size_t size_)
        {
Martin Sustrik's avatar
Martin Sustrik committed
117
            int rc = zmq_msg_close (this);
Martin Sustrik's avatar
Martin Sustrik committed
118 119
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
120
            rc = zmq_msg_init_size (this, size_);
Martin Sustrik's avatar
Martin Sustrik committed
121 122
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
123 124
        }

125 126
        inline void rebuild (void *data_, size_t size_, free_fn *ffn_,
            void *hint_ = NULL)
Martin Sustrik's avatar
Martin Sustrik committed
127
        {
Martin Sustrik's avatar
Martin Sustrik committed
128
            int rc = zmq_msg_close (this);
Martin Sustrik's avatar
Martin Sustrik committed
129 130
            if (rc != 0)
                throw error_t ();
131
            rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
Martin Sustrik's avatar
Martin Sustrik committed
132 133
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
134 135
        }

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

143
        inline void copy (message_t *msg_)
Martin Sustrik's avatar
Martin Sustrik committed
144
        {
145
            int rc = zmq_msg_copy (this, (zmq_msg_t*) msg_);
Martin Sustrik's avatar
Martin Sustrik committed
146 147
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
148 149 150 151
        }

        inline void *data ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
152
            return zmq_msg_data (this);
Martin Sustrik's avatar
Martin Sustrik committed
153 154 155 156
        }

        inline size_t size ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
157
            return zmq_msg_size (this);
Martin Sustrik's avatar
Martin Sustrik committed
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
        }

    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:

174
        inline context_t (int io_threads_)
Martin Sustrik's avatar
Martin Sustrik committed
175
        {
176
            ptr = zmq_init (io_threads_);
Martin Sustrik's avatar
Martin Sustrik committed
177 178
            if (ptr == NULL)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
179 180 181 182
        }

        inline ~context_t ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
183
            int rc = zmq_term (ptr);
Martin Sustrik's avatar
Martin Sustrik committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
            assert (rc == 0);
        }

    private:

        void *ptr;

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

    class socket_t
    {
    public:

199
        inline socket_t (context_t &context_, int type_)
Martin Sustrik's avatar
Martin Sustrik committed
200
        {
Martin Sustrik's avatar
Martin Sustrik committed
201
            ptr = zmq_socket (context_.ptr, type_);
Martin Sustrik's avatar
Martin Sustrik committed
202 203
            if (ptr == NULL)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
204 205 206 207
        }

        inline ~socket_t ()
        {
Martin Sustrik's avatar
Martin Sustrik committed
208
            int rc = zmq_close (ptr);
209
            assert (rc == 0);
Martin Sustrik's avatar
Martin Sustrik committed
210 211
        }

212 213 214 215 216
        inline operator void* ()
        {
            return ptr;
        }

217 218
        inline void setsockopt (int option_, const void *optval_,
            size_t optvallen_)
Martin Sustrik's avatar
Martin Sustrik committed
219
        {
220
            int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_);
Martin Sustrik's avatar
Martin Sustrik committed
221 222
            if (rc != 0)
                throw error_t ();
223 224
        }

225 226 227 228 229 230 231 232
        inline void getsockopt (int option_, void *optval_,
            size_t *optvallen_)
        {
            int rc = zmq_getsockopt (ptr, option_, optval_, optvallen_);
            if (rc != 0)
                throw error_t ();
        }

233 234 235
        inline void bind (const char *addr_)
        {
            int rc = zmq_bind (ptr, addr_);
Martin Sustrik's avatar
Martin Sustrik committed
236 237
            if (rc != 0)
                throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
238 239
        }

240
        inline void connect (const char *addr_)
Martin Sustrik's avatar
Martin Sustrik committed
241
        {
242
            int rc = zmq_connect (ptr, addr_);
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 send (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_send (ptr, &msg_, flags_);
Martin Sustrik's avatar
Martin Sustrik committed
250 251
            if (rc == 0)
                return true;
252
            if (rc == -1 && zmq_errno () == EAGAIN)
Martin Sustrik's avatar
Martin Sustrik committed
253 254
                return false;
            throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
255 256
        }

Martin Sustrik's avatar
Martin Sustrik committed
257
        inline bool recv (message_t *msg_, int flags_ = 0)
Martin Sustrik's avatar
Martin Sustrik committed
258
        {
Martin Sustrik's avatar
Martin Sustrik committed
259
            int rc = zmq_recv (ptr, msg_, flags_);
Martin Sustrik's avatar
Martin Sustrik committed
260 261
            if (rc == 0)
                return true;
262
            if (rc == -1 && zmq_errno () == EAGAIN)
Martin Sustrik's avatar
Martin Sustrik committed
263 264
                return false;
            throw error_t ();
Martin Sustrik's avatar
Martin Sustrik committed
265 266 267 268 269 270 271 272 273 274 275 276 277
        }

    private:

        void *ptr;

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

}

#endif