LCOV - code coverage report
Current view: top level - home/h/core/forks/m4-libzmq/src - zmq_utils.cpp (source / functions) Hit Total Coverage
Test: zeromq-4.2.0 Code Coverage Lines: 62 66 93.9 %
Date: 2016-05-09 Functions: 14 14 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :     Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
       3             : 
       4             :     This file is part of libzmq, the ZeroMQ core engine in C++.
       5             : 
       6             :     libzmq is free software; you can redistribute it and/or modify it under
       7             :     the terms of the GNU Lesser General Public License (LGPL) as published
       8             :     by the Free Software Foundation; either version 3 of the License, or
       9             :     (at your option) any later version.
      10             : 
      11             :     As a special exception, the Contributors give you permission to link
      12             :     this library with independent modules to produce an executable,
      13             :     regardless of the license terms of these independent modules, and to
      14             :     copy and distribute the resulting executable under terms of your choice,
      15             :     provided that you also meet, for each linked independent module, the
      16             :     terms and conditions of the license of that module. An independent
      17             :     module is a module which is not derived from or based on this library.
      18             :     If you modify this library, you must extend this exception to your
      19             :     version of the library.
      20             : 
      21             :     libzmq is distributed in the hope that it will be useful, but WITHOUT
      22             :     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      23             :     FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
      24             :     License for more details.
      25             : 
      26             :     You should have received a copy of the GNU Lesser General Public License
      27             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      28             : */
      29             : 
      30             : #include "precompiled.hpp"
      31             : #include "macros.hpp"
      32             : #include "platform.hpp"
      33             : 
      34             : #include "clock.hpp"
      35             : #include "err.hpp"
      36             : #include "thread.hpp"
      37             : #include "atomic_counter.hpp"
      38             : #include "atomic_ptr.hpp"
      39             : #include <assert.h>
      40             : 
      41             : #if !defined ZMQ_HAVE_WINDOWS
      42             : #   include <unistd.h>
      43             : #else
      44             : #   include "windows.hpp"
      45             : #endif
      46             : 
      47             : #if defined (ZMQ_USE_TWEETNACL)
      48             : #   include "tweetnacl.h"
      49             : #elif defined (ZMQ_USE_LIBSODIUM)
      50             : #   include "sodium.h"
      51             : #endif
      52             : 
      53           6 : void zmq_sleep (int seconds_)
      54             : {
      55             : #if defined ZMQ_HAVE_WINDOWS
      56             :     Sleep (seconds_ * 1000);
      57             : #else
      58           6 :     sleep (seconds_);
      59             : #endif
      60           6 : }
      61             : 
      62           3 : void *zmq_stopwatch_start ()
      63             : {
      64           3 :     uint64_t *watch = (uint64_t*) malloc (sizeof (uint64_t));
      65           3 :     alloc_assert (watch);
      66           3 :     *watch = zmq::clock_t::now_us ();
      67           3 :     return (void*) watch;
      68             : }
      69             : 
      70           3 : unsigned long zmq_stopwatch_stop (void *watch_)
      71             : {
      72           3 :     uint64_t end = zmq::clock_t::now_us ();
      73           3 :     uint64_t start = *(uint64_t*) watch_;
      74           3 :     free (watch_);
      75           3 :     return (unsigned long) (end - start);
      76             : }
      77             : 
      78        3444 : void *zmq_threadstart(zmq_thread_fn* func, void* arg)
      79             : {
      80        6888 :     zmq::thread_t* thread = new zmq::thread_t;
      81        3444 :     thread->start(func, arg);
      82        3444 :     return thread;
      83             : }
      84             : 
      85        3444 : void zmq_threadclose(void* thread)
      86             : {
      87        3444 :     zmq::thread_t* pThread = static_cast<zmq::thread_t*>(thread);
      88        3444 :     pThread->stop();
      89        3444 :     LIBZMQ_DELETE(pThread);
      90        3444 : }
      91             : 
      92             : //  Z85 codec, taken from 0MQ RFC project, implements RFC32 Z85 encoding
      93             : 
      94             : //  Maps base 256 to base 85
      95             : static char encoder [85 + 1] = {
      96             :     "0123456789" "abcdefghij" "klmnopqrst" "uvwxyzABCD"
      97             :     "EFGHIJKLMN" "OPQRSTUVWX" "YZ.-:+=^!/" "*?&<>()[]{"
      98             :     "}@%$#"
      99             : };
     100             : 
     101             : //  Maps base 85 to base 256
     102             : //  We chop off lower 32 and higher 128 ranges
     103             : static uint8_t decoder [96] = {
     104             :     0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00,
     105             :     0x4B, 0x4C, 0x46, 0x41, 0x00, 0x3F, 0x3E, 0x45,
     106             :     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     107             :     0x08, 0x09, 0x40, 0x00, 0x49, 0x42, 0x4A, 0x47,
     108             :     0x51, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
     109             :     0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
     110             :     0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
     111             :     0x3B, 0x3C, 0x3D, 0x4D, 0x00, 0x4E, 0x43, 0x00,
     112             :     0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
     113             :     0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
     114             :     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
     115             :     0x21, 0x22, 0x23, 0x4F, 0x00, 0x50, 0x00, 0x00
     116             : };
     117             : 
     118             : //  --------------------------------------------------------------------------
     119             : //  Encode a binary frame as a string; destination string MUST be at least
     120             : //  size * 5 / 4 bytes long plus 1 byte for the null terminator. Returns
     121             : //  dest. Size must be a multiple of 4.
     122             : //  Returns NULL and sets errno = EINVAL for invalid input.
     123             : 
     124          24 : char *zmq_z85_encode (char *dest, const uint8_t *data, size_t size)
     125             : {
     126          24 :     if (size % 4 != 0) {
     127           0 :         errno = EINVAL;
     128           0 :         return NULL;
     129             :     }
     130             :     unsigned int char_nbr = 0;
     131             :     unsigned int byte_nbr = 0;
     132             :     uint32_t value = 0;
     133         792 :     while (byte_nbr < size) {
     134             :         //  Accumulate value in base 256 (binary)
     135         768 :         value = value * 256 + data [byte_nbr++];
     136         768 :         if (byte_nbr % 4 == 0) {
     137             :             //  Output value in base 85
     138             :             unsigned int divisor = 85 * 85 * 85 * 85;
     139        1152 :             while (divisor) {
     140         960 :                 dest [char_nbr++] = encoder [value / divisor % 85];
     141         960 :                 divisor /= 85;
     142             :             }
     143             :             value = 0;
     144             :         }
     145             :     }
     146             :     assert (char_nbr == size * 5 / 4);
     147          24 :     dest [char_nbr] = 0;
     148          24 :     return dest;
     149             : }
     150             : 
     151             : 
     152             : //  --------------------------------------------------------------------------
     153             : //  Decode an encoded string into a binary frame; dest must be at least
     154             : //  strlen (string) * 4 / 5 bytes long. Returns dest. strlen (string)
     155             : //  must be a multiple of 5.
     156             : //  Returns NULL and sets errno = EINVAL for invalid input.
     157             : 
     158          63 : uint8_t *zmq_z85_decode (uint8_t *dest, const char *string)
     159             : {
     160          63 :     if (strlen (string) % 5 != 0) {
     161           0 :         errno = EINVAL;
     162           0 :         return NULL;
     163             :     }
     164             :     unsigned int byte_nbr = 0;
     165             :     unsigned int char_nbr = 0;
     166             :     size_t string_len = strlen (string);
     167             :     uint32_t value = 0;
     168        2583 :     while (char_nbr < string_len) {
     169             :         //  Accumulate value in base 85
     170        2520 :         value = value * 85 + decoder [(uint8_t) string [char_nbr++] - 32];
     171        2520 :         if (char_nbr % 5 == 0) {
     172             :             //  Output value in base 256
     173             :             unsigned int divisor = 256 * 256 * 256;
     174        2520 :             while (divisor) {
     175        2016 :                 dest [byte_nbr++] = value / divisor % 256;
     176        2016 :                 divisor /= 256;
     177             :             }
     178             :             value = 0;
     179             :         }
     180             :     }
     181             :     assert (byte_nbr == strlen (string) * 4 / 5);
     182             :     return dest;
     183             : }
     184             : 
     185             : //  --------------------------------------------------------------------------
     186             : //  Generate a public/private keypair with tweetnacl or libsodium.
     187             : //  Generated keys will be 40 byte z85-encoded strings.
     188             : //  Returns 0 on success, -1 on failure, setting errno.
     189             : //  Sets errno = ENOTSUP in the absence of a CURVE library.
     190             : 
     191           9 : int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key)
     192             : {
     193             : #if defined (ZMQ_HAVE_CURVE)
     194             : #   if crypto_box_PUBLICKEYBYTES != 32 \
     195             :     || crypto_box_SECRETKEYBYTES != 32
     196             : #       error "CURVE encryption library not built correctly"
     197             : #   endif
     198             : 
     199             :     uint8_t public_key [32];
     200             :     uint8_t secret_key [32];
     201             : 
     202           9 :     int rc = crypto_box_keypair (public_key, secret_key);
     203             :     //  Is there a sensible errno to set here?
     204           9 :     if (rc)
     205             :         return rc;
     206             : 
     207           9 :     zmq_z85_encode (z85_public_key, public_key, 32);
     208           9 :     zmq_z85_encode (z85_secret_key, secret_key, 32);
     209             : 
     210             :     return 0;
     211             : #else
     212             :     (void) z85_public_key, (void) z85_secret_key;
     213             :     errno = ENOTSUP;
     214             :     return -1;
     215             : #endif
     216             : }
     217             : 
     218             : 
     219             : //  --------------------------------------------------------------------------
     220             : //  Initialize a new atomic counter, which is set to zero
     221             : 
     222           3 : void *zmq_atomic_counter_new (void)
     223             : {
     224           6 :     zmq::atomic_counter_t *counter = new zmq::atomic_counter_t;
     225           3 :     alloc_assert (counter);
     226           3 :     return counter;
     227             : }
     228             : 
     229             : //  Se the value of the atomic counter
     230             : 
     231           3 : void zmq_atomic_counter_set (void *counter_, int value_)
     232             : {
     233           3 :     ((zmq::atomic_counter_t *) counter_)->set (value_);
     234           3 : }
     235             : 
     236             : //  Increment the atomic counter, and return the old value
     237             : 
     238           9 : int zmq_atomic_counter_inc (void *counter_)
     239             : {
     240           9 :     return ((zmq::atomic_counter_t *) counter_)->add (1);
     241             : }
     242             : 
     243             : //  Decrement the atomic counter and return 1 (if counter >= 1), or
     244             : //  0 if counter hit zero.
     245             : 
     246          15 : int zmq_atomic_counter_dec (void *counter_)
     247             : {
     248          15 :     return ((zmq::atomic_counter_t *) counter_)->sub (1)? 1: 0;
     249             : }
     250             : 
     251             : //  Return actual value of atomic counter
     252             : 
     253           6 : int zmq_atomic_counter_value (void *counter_)
     254             : {
     255           6 :     return ((zmq::atomic_counter_t *) counter_)->get ();
     256             : }
     257             : 
     258             : //  Destroy atomic counter, and set reference to NULL
     259             : 
     260           3 : void zmq_atomic_counter_destroy (void **counter_p_)
     261             : {
     262           3 :     delete ((zmq::atomic_counter_t *) *counter_p_);
     263           3 :     *counter_p_ = NULL;
     264           3 : }

Generated by: LCOV version 1.10