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