diff --git a/zeromq/zhelpers.h b/zeromq/zhelpers.h new file mode 100644 index 0000000..e28d1f6 --- /dev/null +++ b/zeromq/zhelpers.h @@ -0,0 +1,191 @@ +/* ===================================================================== + zhelpers.h + + Helper header file for example applications. + ===================================================================== +*/ + +#ifndef __ZHELPERS_H_INCLUDED__ +#define __ZHELPERS_H_INCLUDED__ + +// Include a bunch of headers that we will need in the examples + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Version checking, and patch up missing constants to match 2.1 +#if ZMQ_VERSION_MAJOR == 2 +# if ZMQ_VERSION_MINOR == 0 +# error "Please upgrade to ZeroMQ/2.1 stable for these examples" +# endif +#elif ZMQ_VERSION_MAJOR == 3 +# error "Please stick with ZeroMQ/2.1 stable for these examples" +#endif +#ifndef ZMQ_ROUTER +# define ZMQ_ROUTER ZMQ_ROUTER +#endif +#ifndef ZMQ_DEALER +# define ZMQ_DEALER ZMQ_DEALER +#endif + + +// Provide random number from 0..(num-1) +#if (defined (__WINDOWS__)) +# define randof(num) (int) ((float) (num) * rand () / (RAND_MAX + 1.0)) +#else +# define randof(num) (int) ((float) (num) * random () / (RAND_MAX + 1.0)) +#endif + + +// Receive 0MQ string from socket and convert into C string +// Caller must free returned string. Returns NULL if the context +// is being terminated. +static char * +s_recv (void *socket) { + zmq_msg_t message; + zmq_msg_init (&message); + if (zmq_recv (socket, &message, 0)) + return (NULL); + int size = zmq_msg_size (&message); + char *string = malloc (size + 1); + memcpy (string, zmq_msg_data (&message), size); + zmq_msg_close (&message); + string [size] = 0; + return (string); +} + +// Convert C string to 0MQ string and send to socket +static int +s_send (void *socket, char *string) { + int rc; + zmq_msg_t message; + zmq_msg_init_size (&message, strlen (string)); + memcpy (zmq_msg_data (&message), string, strlen (string)); + rc = zmq_send (socket, &message, 0); + zmq_msg_close (&message); + return (rc); +} + +// Sends string as 0MQ string, as multipart non-terminal +static int +s_sendmore (void *socket, char *string) { + int rc; + zmq_msg_t message; + zmq_msg_init_size (&message, strlen (string)); + memcpy (zmq_msg_data (&message), string, strlen (string)); + rc = zmq_send (socket, &message, ZMQ_SNDMORE); + zmq_msg_close (&message); + return (rc); +} + +// Receives all message parts from socket, prints neatly +// +static void +s_dump (void *socket) +{ + puts ("----------------------------------------"); + while (1) { + // Process all parts of the message + zmq_msg_t message; + zmq_msg_init (&message); + zmq_recv (socket, &message, 0); + + // Dump the message as text or binary + char *data = zmq_msg_data (&message); + int size = zmq_msg_size (&message); + int is_text = 1; + int char_nbr; + for (char_nbr = 0; char_nbr < size; char_nbr++) + if ((unsigned char) data [char_nbr] < 32 + || (unsigned char) data [char_nbr] > 127) + is_text = 0; + + printf ("[%03d] ", size); + for (char_nbr = 0; char_nbr < size; char_nbr++) { + if (is_text) + printf ("%c", data [char_nbr]); + else + printf ("%02X", (unsigned char) data [char_nbr]); + } + printf ("\n"); + + int64_t more; // Multipart detection + size_t more_size = sizeof (more); + zmq_getsockopt (socket, ZMQ_RCVMORE, &more, &more_size); + zmq_msg_close (&message); + if (!more) + break; // Last message part + } +} + +// Set simple random printable identity on socket +// +static void +s_set_id (void *socket) +{ + char identity [10]; + sprintf (identity, "%04X-%04X", randof (0x10000), randof (0x10000)); + zmq_setsockopt (socket, ZMQ_IDENTITY, identity, strlen (identity)); +} + + +// Sleep for a number of milliseconds +static void +s_sleep (int msecs) +{ +#if (defined (__WINDOWS__)) + Sleep (msecs); +#else + struct timespec t; + t.tv_sec = msecs / 1000; + t.tv_nsec = (msecs % 1000) * 1000000; + nanosleep (&t, NULL); +#endif +} + +// Return current system clock as milliseconds +static int64_t +s_clock (void) +{ +#if (defined (__WINDOWS__)) + SYSTEMTIME st; + GetSystemTime (&st); + return (int64_t) st.wSecond * 1000 + st.wMilliseconds; +#else + struct timeval tv; + gettimeofday (&tv, NULL); + return (int64_t) (tv.tv_sec * 1000 + tv.tv_usec / 1000); +#endif +} + +// Print formatted string to stdout, prefixed by date/time and +// terminated with a newline. + +static void +s_console (const char *format, ...) +{ + time_t curtime = time (NULL); + struct tm *loctime = localtime (&curtime); + char *formatted = malloc (20); + strftime (formatted, 20, "%y-%m-%d %H:%M:%S ", loctime); + printf ("%s", formatted); + free (formatted); + + va_list argptr; + va_start (argptr, format); + vprintf (format, argptr); + va_end (argptr); + printf ("\n"); +} + +#endif // __ZHELPERS_H_INCLUDED__