1"""0MQ utils."""
2
3#
4#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
5#
6#    This file is part of pyzmq.
7#
8#    pyzmq is free software; you can redistribute it and/or modify it under
9#    the terms of the Lesser GNU General Public License as published by
10#    the Free Software Foundation; either version 3 of the License, or
11#    (at your option) any later version.
12#
13#    pyzmq is distributed in the hope that it will be useful,
14#    but WITHOUT ANY WARRANTY; without even the implied warranty of
15#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16#    Lesser GNU General Public License for more details.
17#
18#    You should have received a copy of the Lesser GNU General Public License
19#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20#
21
22from libzmq cimport (
23    zmq_stopwatch_start, zmq_stopwatch_stop, zmq_sleep, zmq_curve_keypair,
24    zmq_has, const_char_ptr
25)
26from zmq.error import ZMQError, _check_rc, _check_version
27from zmq.utils.strtypes import unicode
28
29def has(capability):
30    """Check for zmq capability by name (e.g. 'ipc', 'curve')
31    
32    .. versionadded:: libzmq-4.1
33    .. versionadded:: 14.1
34    """
35    _check_version((4,1), 'zmq.has')
36    cdef bytes ccap
37    if isinstance(capability, unicode):
38        capability = capability.encode('utf8')
39    ccap = capability
40    return bool(zmq_has(ccap))
41
42def curve_keypair():
43    """generate a Z85 keypair for use with zmq.CURVE security
44    
45    Requires libzmq (≥ 4.0) to have been linked with libsodium.
46    
47    .. versionadded:: libzmq-4.0
48    .. versionadded:: 14.0
49    
50    Returns
51    -------
52    (public, secret) : two bytestrings
53        The public and private keypair as 40 byte z85-encoded bytestrings.
54    """
55    cdef int rc
56    cdef char[64] public_key
57    cdef char[64] secret_key
58    _check_version((4,0), "curve_keypair")
59    rc = zmq_curve_keypair (public_key, secret_key)
60    _check_rc(rc)
61    return public_key, secret_key
62
63
64cdef class Stopwatch:
65    """Stopwatch()
66
67    A simple stopwatch based on zmq_stopwatch_start/stop.
68
69    This class should be used for benchmarking and timing 0MQ code.
70    """
71
72    def __cinit__(self):
73        self.watch = NULL
74
75    def __dealloc__(self):
76        # copy of self.stop() we can't call object methods in dealloc as it
77        # might already be partially deleted
78        if self.watch:
79            zmq_stopwatch_stop(self.watch)
80            self.watch = NULL
81
82    def start(self):
83        """s.start()
84
85        Start the stopwatch.
86        """
87        if self.watch == NULL:
88            self.watch = zmq_stopwatch_start()
89        else:
90            raise ZMQError('Stopwatch is already running.')
91
92    def stop(self):
93        """s.stop()
94
95        Stop the stopwatch.
96        
97        Returns
98        -------
99        t : unsigned long int
100            the number of microseconds since ``start()`` was called.
101        """
102        cdef unsigned long time
103        if self.watch == NULL:
104            raise ZMQError('Must start the Stopwatch before calling stop.')
105        else:
106            time = zmq_stopwatch_stop(self.watch)
107            self.watch = NULL
108            return time
109
110    def sleep(self, int seconds):
111        """s.sleep(seconds)
112
113        Sleep for an integer number of seconds.
114        """
115        with nogil:
116            zmq_sleep(seconds)
117
118
119__all__ = ['has', 'curve_keypair', 'Stopwatch']
120