/* ===================================================================== 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 #if (!defined (WIN32)) # include #endif #if (defined (WIN32)) # include #endif // Version checking, and patch up missing constants to match 2.1 #if ZMQ_VERSION_MAJOR == 2 # error "Please upgrade to ZeroMQ/3.2 for these examples" #endif // On some version of Windows, POSIX subsystem is not installed by default. // So define srandom and random ourself. #if (defined (WIN32)) # define srandom srand # define random rand #endif // Provide random number from 0..(num-1) #define randof(num) (int) ((float) (num) * random () / (RAND_MAX + 1.0)) // 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) { enum { cap = 256 }; char buffer [cap]; int size = zmq_recv (socket, buffer, cap - 1, 0); if (size == -1) return NULL; buffer[size < cap ? size : cap - 1] = '\0'; #if (defined (WIN32)) return strdup (buffer); #else return strndup (buffer, sizeof(buffer) - 1); #endif // remember that the strdup family of functions use malloc/alloc for space for the new string. It must be manually // freed when you are done with it. Failure to do so will allow a heap attack. } // Convert C string to 0MQ string and send to socket static int s_send (void *socket, char *string) { int size = zmq_send (socket, string, strlen (string), 0); return size; } // Sends string as 0MQ string, as multipart non-terminal static int s_sendmore (void *socket, char *string) { int size = zmq_send (socket, string, strlen (string), ZMQ_SNDMORE); return size; } // Receives all message parts from socket, prints neatly // static void s_dump (void *socket) { int rc; zmq_msg_t message; rc = zmq_msg_init (&message); assert (rc == 0); puts ("----------------------------------------"); // Process all parts of the message do { int size = zmq_msg_recv (&message, socket, 0); assert (size >= 0); // Dump the message as text or binary char *data = (char*)zmq_msg_data (&message); assert (data != 0); 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] > 126) { 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"); } while (zmq_msg_more (&message)); rc = zmq_msg_close (&message); assert (rc == 0); } #if (!defined (WIN32)) // Set simple random printable identity on socket // Caution: // DO NOT call this version of s_set_id from multiple threads on MS Windows // since s_set_id will call rand() on MS Windows. rand(), however, is not // reentrant or thread-safe. See issue #521. 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)); } #else // Fix #521 for MS Windows. static void s_set_id(void *socket, intptr_t id) { char identity [10]; sprintf(identity, "%04X", (int)id); zmq_setsockopt(socket, ZMQ_IDENTITY, identity, strlen(identity)); } #endif // Sleep for a number of milliseconds static void s_sleep (int msecs) { #if (defined (WIN32)) 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 (WIN32)) 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 = (char*)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__