Utility.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (c) 2001-2014
3 **
4 ** This file is part of the QuickFIX FIX Engine
5 **
6 ** This file may be distributed under the terms of the quickfixengine.org
7 ** license as defined by quickfixengine.org and appearing in the file
8 ** LICENSE included in the packaging of this file.
9 **
10 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12 **
13 ** See http://www.quickfixengine.org/LICENSE for licensing information.
14 **
15 ** Contact ask@quickfixengine.org if any conditions of this licensing are
16 ** not clear to you.
17 **
18 ****************************************************************************/
19 
20 #ifdef _MSC_VER
21 #include "stdafx.h"
22 #else
23 #include "config.h"
24 #endif
25 
26 #include "Utility.h"
27 
28 #ifdef USING_STREAMS
29 #include <stropts.h>
30 #include <sys/conf.h>
31 #endif
32 #include <string.h>
33 #include <math.h>
34 #include <stdio.h>
35 #include <algorithm>
36 #include <fstream>
37 
38 namespace FIX
39 {
40 void string_replace( const std::string& oldValue,
41  const std::string& newValue,
42  std::string& value )
43 {
44  for( std::string::size_type pos = value.find(oldValue);
45  pos != std::string::npos;
46  pos = value.find(oldValue, pos) )
47  {
48  value.replace( pos, oldValue.size(), newValue );
49  pos += newValue.size();
50  }
51 }
52 
53 std::string string_toUpper( const std::string& value )
54 {
55  std::string copy = value;
56  std::transform( copy.begin(), copy.end(), copy.begin(), toupper );
57  return copy;
58 }
59 
60 std::string string_toLower( const std::string& value )
61 {
62  std::string copy = value;
63  std::transform( copy.begin(), copy.end(), copy.begin(), tolower );
64  return copy;
65 }
66 
67 std::string string_strip( const std::string& value )
68 {
69  if( !value.size() )
70  return value;
71 
72  size_t startPos = value.find_first_not_of(" \t\r\n");
73  size_t endPos = value.find_last_not_of(" \t\r\n");
74 
75  if( startPos == std::string::npos )
76  return value;
77 
78  return std::string( value, startPos, endPos - startPos + 1 );
79 }
80 
82 {
83 #ifdef _MSC_VER
84  WORD version = MAKEWORD( 2, 2 );
85  WSADATA data;
86  WSAStartup( version, &data );
87 #else
88  struct sigaction sa;
89  sa.sa_handler = SIG_IGN;
90  sigemptyset( &sa.sa_mask );
91  sa.sa_flags = 0;
92  sigaction( SIGPIPE, &sa, 0 );
93 #endif
94 }
95 
97 {
98 #ifdef _MSC_VER
99  WSACleanup();
100 #endif
101 }
102 
103 int socket_createAcceptor(int port, bool reuse)
104 {
105  int socket = ::socket( PF_INET, SOCK_STREAM, 0 );
106  if ( socket < 0 ) return -1;
107 
108  sockaddr_in address;
109  socklen_t socklen;
110 
111  address.sin_family = PF_INET;
112  address.sin_port = htons( port );
113  address.sin_addr.s_addr = INADDR_ANY;
114  socklen = sizeof( address );
115  if( reuse )
116  socket_setsockopt( socket, SO_REUSEADDR );
117 
118  int result = bind( socket, reinterpret_cast < sockaddr* > ( &address ),
119  socklen );
120  if ( result < 0 ) return -1;
121  result = listen( socket, SOMAXCONN );
122  if ( result < 0 ) return -1;
123  return socket;
124 }
125 
127 {
128  return ::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
129 }
130 
131 int socket_connect( int socket, const char* address, int port )
132 {
133  const char* hostname = socket_hostname( address );
134  if( hostname == 0 ) return -1;
135 
136  sockaddr_in addr;
137  addr.sin_family = PF_INET;
138  addr.sin_port = htons( port );
139  addr.sin_addr.s_addr = inet_addr( hostname );
140 
141  int result = connect( socket, reinterpret_cast < sockaddr* > ( &addr ),
142  sizeof( addr ) );
143 
144  return result;
145 }
146 
147 int socket_accept( int s )
148 {
149  if ( !socket_isValid( s ) ) return -1;
150  return accept( s, 0, 0 );
151 }
152 
153 ssize_t socket_send( int s, const char* msg, size_t length )
154 {
155  return send( s, msg, length, 0 );
156 }
157 
158 void socket_close( int s )
159 {
160  shutdown( s, 2 );
161 #ifdef _MSC_VER
162  closesocket( s );
163 #else
164  close( s );
165 #endif
166 }
167 
168 bool socket_fionread( int s, int& bytes )
169 {
170  bytes = 0;
171 #if defined(_MSC_VER)
172  return ::ioctlsocket( s, FIONREAD, &( ( unsigned long& ) bytes ) ) == 0;
173 #elif defined(USING_STREAMS)
174  return ::ioctl( s, I_NREAD, &bytes ) >= 0;
175 #else
176  return ::ioctl( s, FIONREAD, &bytes ) == 0;
177 #endif
178 }
179 
180 bool socket_disconnected( int s )
181 {
182  char byte;
183  return ::recv (s, &byte, sizeof (byte), MSG_PEEK) <= 0;
184 }
185 
186 int socket_setsockopt( int s, int opt )
187 {
188 #ifdef _MSC_VER
189  BOOL optval = TRUE;
190 #else
191  int optval = 1;
192 #endif
193  return socket_setsockopt( s, opt, optval );
194 }
195 
196 int socket_setsockopt( int s, int opt, int optval )
197 {
198  int level = SOL_SOCKET;
199  if( opt == TCP_NODELAY )
200  level = IPPROTO_TCP;
201 
202 #ifdef _MSC_VER
203  return ::setsockopt( s, level, opt,
204  ( char* ) & optval, sizeof( optval ) );
205 #else
206  return ::setsockopt( s, level, opt,
207  &optval, sizeof( optval ) );
208 #endif
209 }
210 
211 int socket_getsockopt( int s, int opt, int& optval )
212 {
213  int level = SOL_SOCKET;
214  if( opt == TCP_NODELAY )
215  level = IPPROTO_TCP;
216 
217 #ifdef _MSC_VER
218  int length = sizeof(int);
219 #else
220  socklen_t length = sizeof(socklen_t);
221 #endif
222 
223  return ::getsockopt( s, level, opt,
224  ( char* ) & optval, & length );
225 }
226 
227 #ifndef _MSC_VER
228 int socket_fcntl( int s, int opt, int arg )
229 {
230  return ::fcntl( s, opt, arg );
231 }
232 
233 int socket_getfcntlflag( int s, int arg )
234 {
235  return socket_fcntl( s, F_GETFL, arg );
236 }
237 
238 int socket_setfcntlflag( int s, int arg )
239 {
240  int oldValue = socket_getfcntlflag( s, arg );
241  oldValue |= arg;
242  return socket_fcntl( s, F_SETFL, arg );
243 }
244 #endif
245 
246 void socket_setnonblock( int socket )
247 {
248 #ifdef _MSC_VER
249  u_long opt = 1;
250  ::ioctlsocket( socket, FIONBIO, &opt );
251 #else
252  socket_setfcntlflag( socket, O_NONBLOCK );
253 #endif
254 }
255 bool socket_isValid( int socket )
256 {
257 #ifdef _MSC_VER
258  return socket != INVALID_SOCKET;
259 #else
260  return socket >= 0;
261 #endif
262 }
263 
264 #ifndef _MSC_VER
265 bool socket_isBad( int s )
266 {
267  struct stat buf;
268  fstat( s, &buf );
269  return errno == EBADF;
270 }
271 #endif
272 
273 void socket_invalidate( int& socket )
274 {
275 #ifdef _MSC_VER
276  socket = INVALID_SOCKET;
277 #else
278  socket = -1;
279 #endif
280 }
281 
282 short socket_hostport( int socket )
283 {
284  struct sockaddr_in addr;
285  socklen_t len = sizeof(addr);
286  if( getsockname(socket, (struct sockaddr*)&addr, &len) < 0 )
287  return 0;
288 
289  return ntohs( addr.sin_port );
290 }
291 
292 const char* socket_hostname( int socket )
293 {
294  struct sockaddr_in addr;
295  socklen_t len = sizeof(addr);
296  if( getsockname(socket, (struct sockaddr*)&addr, &len) < 0 )
297  return 0;
298 
299  return inet_ntoa( addr.sin_addr );
300 }
301 
302 const char* socket_hostname( const char* name )
303 {
304  struct hostent* host_ptr = 0;
305  struct in_addr** paddr;
306  struct in_addr saddr;
307 
308 #if( GETHOSTBYNAME_R_INPUTS_RESULT || GETHOSTBYNAME_R_RETURNS_RESULT )
309  hostent host;
310  char buf[1024];
311  int error;
312 #endif
313 
314  saddr.s_addr = inet_addr( name );
315  if ( saddr.s_addr != ( unsigned ) - 1 ) return name;
316 
317 #if GETHOSTBYNAME_R_INPUTS_RESULT
318  gethostbyname_r( name, &host, buf, sizeof(buf), &host_ptr, &error );
319 #elif GETHOSTBYNAME_R_RETURNS_RESULT
320  host_ptr = gethostbyname_r( name, &host, buf, sizeof(buf), &error );
321 #else
322  host_ptr = gethostbyname( name );
323 #endif
324 
325  if ( host_ptr == 0 ) return 0;
326 
327  paddr = ( struct in_addr ** ) host_ptr->h_addr_list;
328  return inet_ntoa( **paddr );
329 }
330 
331 const char* socket_peername( int socket )
332 {
333  struct sockaddr_in addr;
334  socklen_t len = sizeof(addr);
335  if( getpeername( socket, (struct sockaddr*)&addr, &len ) < 0 )
336  return "UNKNOWN";
337  char* result = inet_ntoa( addr.sin_addr );
338  if( result )
339  return result;
340  else
341  return "UNKNOWN";
342 }
343 
344 std::pair<int, int> socket_createpair()
345 {
346 #ifdef _MSC_VER
347  int acceptor = socket_createAcceptor(0, true);
348  const char* host = socket_hostname( acceptor );
349  short port = socket_hostport( acceptor );
350  int client = socket_createConnector();
351  socket_connect( client, "localhost", port );
352  int server = socket_accept( acceptor );
353  socket_close(acceptor);
354  return std::pair<int, int>( client, server );
355 #else
356  int pair[2];
357  socketpair( AF_UNIX, SOCK_STREAM, 0, pair );
358  return std::pair<int, int>( pair[0], pair[1] );
359 #endif
360 }
361 
362 tm time_gmtime( const time_t* t )
363 {
364 #ifdef _MSC_VER
365  #if( _MSC_VER >= 1400 )
366  tm result;
367  gmtime_s( &result, t );
368  return result;
369  #else
370  return *gmtime( t );
371  #endif
372 #else
373  tm result;
374  return *gmtime_r( t, &result );
375 #endif
376 }
377 
378 tm time_localtime( const time_t* t)
379 {
380 #ifdef _MSC_VER
381  #if( _MSC_VER >= 1400 )
382  tm result;
383  localtime_s( &result, t );
384  return result;
385  #else
386  return *localtime( t );
387  #endif
388 #else
389  tm result;
390  return *localtime_r( t, &result );
391 #endif
392 }
393 
394 bool thread_spawn( THREAD_START_ROUTINE func, void* var, thread_id& thread )
395 {
396 #ifdef _MSC_VER
397  thread_id result = 0;
398  unsigned int id = 0;
399  result = _beginthreadex( NULL, 0, &func, var, 0, &id );
400  if ( result == 0 ) return false;
401 #else
402  thread_id result = 0;
403  if( pthread_create( &result, 0, func, var ) != 0 ) return false;
404 #endif
405  thread = result;
406  return true;
407 }
408 
409 bool thread_spawn( THREAD_START_ROUTINE func, void* var )
410 {
411  thread_id thread = 0;
412  return thread_spawn( func, var, thread );
413 }
414 
415 void thread_join( thread_id thread )
416 {
417 #ifdef _MSC_VER
418  WaitForSingleObject( ( void* ) thread, INFINITE );
419  CloseHandle((HANDLE)thread);
420 #else
421  pthread_join( ( pthread_t ) thread, 0 );
422 #endif
423 }
424 
425 void thread_detach( thread_id thread )
426 {
427 #ifdef _MSC_VER
428  CloseHandle((HANDLE)thread);
429 #else
430  pthread_t t = thread;
431  pthread_detach( t );
432 #endif
433 }
434 
436 {
437 #ifdef _MSC_VER
438  return (unsigned)GetCurrentThread();
439 #else
440  return pthread_self();
441 #endif
442 }
443 
444 void process_sleep( double s )
445 {
446 #ifdef _MSC_VER
447  Sleep( (long)(s * 1000) );
448 #else
449  timespec time, remainder;
450  double intpart;
451  time.tv_nsec = (long)(modf(s, &intpart) * 1e9);
452  time.tv_sec = (int)intpart;
453  while( nanosleep(&time, &remainder) == -1 )
454  time = remainder;
455 #endif
456 }
457 
458 std::string file_separator()
459 {
460 #ifdef _MSC_VER
461  return "\\";
462 #else
463  return "/";
464 #endif
465 }
466 
467 void file_mkdir( const char* path )
468 {
469  int length = (int)strlen( path );
470  std::string createPath = "";
471 
472  for( const char* pos = path; (pos - path) <= length; ++pos )
473  {
474  createPath += *pos;
475  if( *pos == '/' || *pos == '\\' || (pos - path) == length )
476  {
477  #ifdef _MSC_VER
478  _mkdir( createPath.c_str() );
479  #else
480  // use umask to override rwx for all
481  mkdir( createPath.c_str(), 0777 );
482  #endif
483  }
484  }
485 }
486 
487 FILE* file_fopen( const char* path, const char* mode )
488 {
489 #if( _MSC_VER >= 1400 )
490  FILE* result = 0;
491  fopen_s( &result, path, mode );
492  return result;
493 #else
494  return fopen( path, mode );
495 #endif
496 }
497 
498 void file_fclose( FILE* file )
499 {
500  fclose( file );
501 }
502 
503 bool file_exists( const char* path )
504 {
505  std::ifstream stream;
506  stream.open( path, std::ios_base::in );
507  if( stream.is_open() )
508  {
509  stream.close();
510  return true;
511  }
512  return false;
513 }
514 
515 void file_unlink( const char* path )
516 {
517 #ifdef _MSC_VER
518  _unlink( path );
519 #else
520  unlink( path );
521 #endif
522 }
523 
524 int file_rename( const char* oldpath, const char* newpath )
525 {
526  return rename( oldpath, newpath );
527 }
528 
529 std::string file_appendpath( const std::string& path, const std::string& file )
530 {
531  const char last = path[path.size()-1];
532  if( last == '/' || last == '\\' )
533  return std::string(path) + file;
534  else
535  return std::string(path) + file_separator() + file;
536 }
537 }
void thread_join(thread_id thread)
Definition: Utility.cpp:415
int socket_getsockopt(int s, int opt, int &optval)
Definition: Utility.cpp:211
int socket_connect(int socket, const char *address, int port)
Definition: Utility.cpp:131
int socket_accept(int s)
Definition: Utility.cpp:147
bool socket_isValid(int socket)
Definition: Utility.cpp:255
bool socket_disconnected(int s)
Definition: Utility.cpp:180
std::string string_toLower(const std::string &value)
Definition: Utility.cpp:60
void socket_init()
Definition: Utility.cpp:81
tm time_localtime(const time_t *t)
Definition: Utility.cpp:378
void socket_term()
Definition: Utility.cpp:96
short socket_hostport(int socket)
Definition: Utility.cpp:282
void thread_detach(thread_id thread)
Definition: Utility.cpp:425
int socket_createConnector()
Definition: Utility.cpp:126
void process_sleep(double s)
Definition: Utility.cpp:444
int socket_getfcntlflag(int s, int arg)
Definition: Utility.cpp:233
bool socket_fionread(int s, int &bytes)
Definition: Utility.cpp:168
bool thread_spawn(THREAD_START_ROUTINE func, void *var, thread_id &thread)
Definition: Utility.cpp:394
std::string file_appendpath(const std::string &path, const std::string &file)
Definition: Utility.cpp:529
int socket_setfcntlflag(int s, int arg)
Definition: Utility.cpp:238
tm time_gmtime(const time_t *t)
Definition: Utility.cpp:362
int socket_setsockopt(int s, int opt)
Definition: Utility.cpp:186
void socket_invalidate(int &socket)
Definition: Utility.cpp:273
int socket_fcntl(int s, int opt, int arg)
Definition: Utility.cpp:228
void file_fclose(FILE *file)
Definition: Utility.cpp:498
Definition: Acceptor.cpp:34
std::string file_separator()
Definition: Utility.cpp:458
std::string string_toUpper(const std::string &value)
Definition: Utility.cpp:53
void file_mkdir(const char *path)
Definition: Utility.cpp:467
const char * socket_hostname(int socket)
Definition: Utility.cpp:292
int file_rename(const char *oldpath, const char *newpath)
Definition: Utility.cpp:524
std::string string_strip(const std::string &value)
Definition: Utility.cpp:67
void socket_setnonblock(int socket)
Definition: Utility.cpp:246
void file_unlink(const char *path)
Definition: Utility.cpp:515
std::pair< int, int > socket_createpair()
Definition: Utility.cpp:344
bool socket_isBad(int s)
Definition: Utility.cpp:265
int socket_createAcceptor(int port, bool reuse)
Definition: Utility.cpp:103
FILE * file_fopen(const char *path, const char *mode)
Definition: Utility.cpp:487
pthread_t thread_id
Definition: Utility.h:164
ssize_t socket_send(int s, const char *msg, size_t length)
Definition: Utility.cpp:153
thread_id thread_self()
Definition: Utility.cpp:435
void string_replace(const std::string &oldValue, const std::string &newValue, std::string &value)
Definition: Utility.cpp:40
void socket_close(int s)
Definition: Utility.cpp:158
void *() THREAD_START_ROUTINE(void *)
Definition: Utility.h:157
const char * socket_peername(int socket)
Definition: Utility.cpp:331
bool file_exists(const char *path)
Definition: Utility.cpp:503

Generated on Thu Sep 5 2019 11:07:58 for QuickFIX by doxygen 1.8.13 written by Dimitri van Heesch, © 1997-2001