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 
81 void socket_init()
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 
96 void socket_term()
97 {
98 #ifdef _MSC_VER
99  WSACleanup();
100 #endif
101 }
102 
103 int socket_bind( int socket, const char* hostname, int port )
104 {
105  sockaddr_in address;
106  socklen_t socklen;
107 
108  address.sin_family = PF_INET;
109  address.sin_port = htons( port );
110  if ( !hostname || !*hostname )
111  address.sin_addr.s_addr = INADDR_ANY;
112  else
113  address.sin_addr.s_addr = inet_addr( hostname );
114  socklen = sizeof( address );
115 
116  return bind( socket, reinterpret_cast < sockaddr* > ( &address ),
117  socklen );
118 }
119 
120 int socket_createAcceptor(int port, bool reuse)
121 {
122  int socket = ::socket( PF_INET, SOCK_STREAM, 0 );
123  if ( socket < 0 ) return -1;
124 
125  sockaddr_in address;
126  socklen_t socklen;
127 
128  address.sin_family = PF_INET;
129  address.sin_port = htons( port );
130  address.sin_addr.s_addr = INADDR_ANY;
131  socklen = sizeof( address );
132  if( reuse )
133  socket_setsockopt( socket, SO_REUSEADDR );
134 
135  int result = bind( socket, reinterpret_cast < sockaddr* > ( &address ),
136  socklen );
137  if ( result < 0 ) return -1;
138  result = listen( socket, SOMAXCONN );
139  if ( result < 0 ) return -1;
140  return socket;
141 }
142 
144 {
145  return ::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
146 }
147 
148 int socket_connect( int socket, const char* address, int port )
149 {
150  const char* hostname = socket_hostname( address );
151  if( hostname == 0 ) return -1;
152 
153  sockaddr_in addr;
154  addr.sin_family = PF_INET;
155  addr.sin_port = htons( port );
156  addr.sin_addr.s_addr = inet_addr( hostname );
157 
158  int result = connect( socket, reinterpret_cast < sockaddr* > ( &addr ),
159  sizeof( addr ) );
160 
161  return result;
162 }
163 
164 int socket_accept( int s )
165 {
166  if ( !socket_isValid( s ) ) return -1;
167  return accept( s, 0, 0 );
168 }
169 
170 ssize_t socket_recv( int s, char* buf, size_t length )
171 {
172  return recv( s, buf, length, 0 );
173 }
174 
175 ssize_t socket_send( int s, const char* msg, size_t length )
176 {
177  return send( s, msg, length, 0 );
178 }
179 
180 void socket_close( int s )
181 {
182  shutdown( s, 2 );
183 #ifdef _MSC_VER
184  closesocket( s );
185 #else
186  close( s );
187 #endif
188 }
189 
190 bool socket_fionread( int s, int& bytes )
191 {
192  bytes = 0;
193 #if defined(_MSC_VER)
194  return ::ioctlsocket( s, FIONREAD, &( ( unsigned long& ) bytes ) ) == 0;
195 #elif defined(USING_STREAMS)
196  return ::ioctl( s, I_NREAD, &bytes ) >= 0;
197 #else
198  return ::ioctl( s, FIONREAD, &bytes ) == 0;
199 #endif
200 }
201 
202 bool socket_disconnected( int s )
203 {
204  char byte;
205  return ::recv (s, &byte, sizeof (byte), MSG_PEEK) <= 0;
206 }
207 
208 int socket_setsockopt( int s, int opt )
209 {
210 #ifdef _MSC_VER
211  BOOL optval = TRUE;
212 #else
213  int optval = 1;
214 #endif
215  return socket_setsockopt( s, opt, optval );
216 }
217 
218 int socket_setsockopt( int s, int opt, int optval )
219 {
220  int level = SOL_SOCKET;
221  if( opt == TCP_NODELAY )
222  level = IPPROTO_TCP;
223 
224 #ifdef _MSC_VER
225  return ::setsockopt( s, level, opt,
226  ( char* ) & optval, sizeof( optval ) );
227 #else
228  return ::setsockopt( s, level, opt,
229  &optval, sizeof( optval ) );
230 #endif
231 }
232 
233 int socket_getsockopt( int s, int opt, int& optval )
234 {
235  int level = SOL_SOCKET;
236  if( opt == TCP_NODELAY )
237  level = IPPROTO_TCP;
238 
239 #ifdef _MSC_VER
240  int length = sizeof(int);
241 #else
242  socklen_t length = sizeof(socklen_t);
243 #endif
244 
245  return ::getsockopt( s, level, opt,
246  ( char* ) & optval, & length );
247 }
248 
249 #ifndef _MSC_VER
250 int socket_fcntl( int s, int opt, int arg )
251 {
252  return ::fcntl( s, opt, arg );
253 }
254 
255 int socket_getfcntlflag( int s, int arg )
256 {
257  return socket_fcntl( s, F_GETFL, arg );
258 }
259 
260 int socket_setfcntlflag( int s, int arg )
261 {
262  int oldValue = socket_getfcntlflag( s, arg );
263  oldValue |= arg;
264  return socket_fcntl( s, F_SETFL, arg );
265 }
266 #endif
267 
268 void socket_setnonblock( int socket )
269 {
270 #ifdef _MSC_VER
271  u_long opt = 1;
272  ::ioctlsocket( socket, FIONBIO, &opt );
273 #else
274  socket_setfcntlflag( socket, O_NONBLOCK );
275 #endif
276 }
277 bool socket_isValid( int socket )
278 {
279 #ifdef _MSC_VER
280  return socket != INVALID_SOCKET;
281 #else
282  return socket >= 0;
283 #endif
284 }
285 
286 #ifndef _MSC_VER
287 bool socket_isBad( int s )
288 {
289  struct stat buf;
290  fstat( s, &buf );
291  return errno == EBADF;
292 }
293 #endif
294 
295 void socket_invalidate( int& socket )
296 {
297 #ifdef _MSC_VER
298  socket = INVALID_SOCKET;
299 #else
300  socket = -1;
301 #endif
302 }
303 
304 short socket_hostport( int socket )
305 {
306  struct sockaddr_in addr;
307  socklen_t len = sizeof(addr);
308  if( getsockname(socket, (struct sockaddr*)&addr, &len) < 0 )
309  return 0;
310 
311  return ntohs( addr.sin_port );
312 }
313 
314 const char* socket_hostname( int socket )
315 {
316  struct sockaddr_in addr;
317  socklen_t len = sizeof(addr);
318  if( getsockname(socket, (struct sockaddr*)&addr, &len) < 0 )
319  return 0;
320 
321  return inet_ntoa( addr.sin_addr );
322 }
323 
324 const char* socket_hostname( const char* name )
325 {
326  struct hostent* host_ptr = 0;
327  struct in_addr** paddr;
328  struct in_addr saddr;
329 
330 #if( GETHOSTBYNAME_R_INPUTS_RESULT || GETHOSTBYNAME_R_RETURNS_RESULT )
331  hostent host;
332  char buf[1024];
333  int error;
334 #endif
335 
336  saddr.s_addr = inet_addr( name );
337  if ( saddr.s_addr != ( unsigned ) - 1 ) return name;
338 
339 #if GETHOSTBYNAME_R_INPUTS_RESULT
340  gethostbyname_r( name, &host, buf, sizeof(buf), &host_ptr, &error );
341 #elif GETHOSTBYNAME_R_RETURNS_RESULT
342  host_ptr = gethostbyname_r( name, &host, buf, sizeof(buf), &error );
343 #else
344  host_ptr = gethostbyname( name );
345 #endif
346 
347  if ( host_ptr == 0 ) return 0;
348 
349  paddr = ( struct in_addr ** ) host_ptr->h_addr_list;
350  return inet_ntoa( **paddr );
351 }
352 
353 const char* socket_peername( int socket )
354 {
355  struct sockaddr_in addr;
356  socklen_t len = sizeof(addr);
357  if( getpeername( socket, (struct sockaddr*)&addr, &len ) < 0 )
358  return "UNKNOWN";
359  char* result = inet_ntoa( addr.sin_addr );
360  if( result )
361  return result;
362  else
363  return "UNKNOWN";
364 }
365 
366 std::pair<int, int> socket_createpair()
367 {
368 #ifdef _MSC_VER
369  int acceptor = socket_createAcceptor(0, true);
370  const char* host = socket_hostname( acceptor );
371  short port = socket_hostport( acceptor );
372  int client = socket_createConnector();
373  socket_connect( client, "localhost", port );
374  int server = socket_accept( acceptor );
375  socket_close(acceptor);
376  return std::pair<int, int>( client, server );
377 #else
378  int pair[2];
379  socketpair( AF_UNIX, SOCK_STREAM, 0, pair );
380  return std::pair<int, int>( pair[0], pair[1] );
381 #endif
382 }
383 
384 tm time_gmtime( const time_t* t )
385 {
386 #ifdef _MSC_VER
387  #if( _MSC_VER >= 1400 )
388  tm result;
389  gmtime_s( &result, t );
390  return result;
391  #else
392  return *gmtime( t );
393  #endif
394 #else
395  tm result;
396  return *gmtime_r( t, &result );
397 #endif
398 }
399 
400 tm time_localtime( const time_t* t)
401 {
402 #ifdef _MSC_VER
403  #if( _MSC_VER >= 1400 )
404  tm result;
405  localtime_s( &result, t );
406  return result;
407  #else
408  return *localtime( t );
409  #endif
410 #else
411  tm result;
412  return *localtime_r( t, &result );
413 #endif
414 }
415 
416 bool thread_spawn( THREAD_START_ROUTINE func, void* var, thread_id& thread )
417 {
418 #ifdef _MSC_VER
419  thread_id result = 0;
420  unsigned int id = 0;
421  result = _beginthreadex( NULL, 0, func, var, 0, &id );
422  if ( result == 0 ) return false;
423 #else
424  thread_id result = 0;
425  if( pthread_create( &result, 0, func, var ) != 0 ) return false;
426 #endif
427  thread = result;
428  return true;
429 }
430 
431 bool thread_spawn( THREAD_START_ROUTINE func, void* var )
432 {
433  thread_id thread = 0;
434  return thread_spawn( func, var, thread );
435 }
436 
437 void thread_join( thread_id thread )
438 {
439 #ifdef _MSC_VER
440  WaitForSingleObject( ( void* ) thread, INFINITE );
441  CloseHandle((HANDLE)thread);
442 #else
443  pthread_join( ( pthread_t ) thread, 0 );
444 #endif
445 }
446 
447 void thread_detach( thread_id thread )
448 {
449 #ifdef _MSC_VER
450  CloseHandle((HANDLE)thread);
451 #else
452  pthread_t t = thread;
453  pthread_detach( t );
454 #endif
455 }
456 
458 {
459 #ifdef _MSC_VER
460  return (unsigned)GetCurrentThread();
461 #else
462  return pthread_self();
463 #endif
464 }
465 
466 void process_sleep( double s )
467 {
468 #ifdef _MSC_VER
469  Sleep( (long)(s * 1000) );
470 #else
471  timespec time, remainder;
472  double intpart;
473  time.tv_nsec = (long)(modf(s, &intpart) * 1e9);
474  time.tv_sec = (int)intpart;
475  while( nanosleep(&time, &remainder) == -1 )
476  time = remainder;
477 #endif
478 }
479 
480 std::string file_separator()
481 {
482 #ifdef _MSC_VER
483  return "\\";
484 #else
485  return "/";
486 #endif
487 }
488 
489 void file_mkdir( const char* path )
490 {
491  int length = (int)strlen( path );
492  std::string createPath = "";
493 
494  for( const char* pos = path; (pos - path) <= length; ++pos )
495  {
496  createPath += *pos;
497  if( *pos == '/' || *pos == '\\' || (pos - path) == length )
498  {
499  #ifdef _MSC_VER
500  _mkdir( createPath.c_str() );
501  #else
502  // use umask to override rwx for all
503  mkdir( createPath.c_str(), 0777 );
504  #endif
505  }
506  }
507 }
508 
509 FILE* file_fopen( const char* path, const char* mode )
510 {
511 #if( _MSC_VER >= 1400 )
512  FILE* result = 0;
513  fopen_s( &result, path, mode );
514  return result;
515 #else
516  return fopen( path, mode );
517 #endif
518 }
519 
520 void file_fclose( FILE* file )
521 {
522  fclose( file );
523 }
524 
525 bool file_exists( const char* path )
526 {
527  std::ifstream stream;
528  stream.open( path, std::ios_base::in );
529  if( stream.is_open() )
530  {
531  stream.close();
532  return true;
533  }
534  return false;
535 }
536 
537 void file_unlink( const char* path )
538 {
539 #ifdef _MSC_VER
540  _unlink( path );
541 #else
542  unlink( path );
543 #endif
544 }
545 
546 int file_rename( const char* oldpath, const char* newpath )
547 {
548  return rename( oldpath, newpath );
549 }
550 
551 std::string file_appendpath( const std::string& path, const std::string& file )
552 {
553  const char last = path[path.size()-1];
554  if( last == '/' || last == '\\' )
555  return std::string(path) + file;
556  else
557  return std::string(path) + file_separator() + file;
558 }
559 }
FIX::thread_id
pthread_t thread_id
Definition: Utility.h:190
FIX::file_appendpath
std::string file_appendpath(const std::string &path, const std::string &file)
Definition: Utility.cpp:568
FIX::time_localtime
tm time_localtime(const time_t *t)
Definition: Utility.cpp:417
FIX::string_toUpper
std::string string_toUpper(const std::string &value)
Definition: Utility.cpp:70
FIX::file_fclose
void file_fclose(FILE *file)
Definition: Utility.cpp:537
FIX::socket_setsockopt
int socket_setsockopt(int s, int opt)
Definition: Utility.cpp:225
FIX::socket_fcntl
int socket_fcntl(int s, int opt, int arg)
Definition: Utility.cpp:267
FIX::socket_init
void socket_init()
Definition: Utility.cpp:98
FIX::socket_connect
int socket_connect(int socket, const char *address, int port)
Definition: Utility.cpp:165
FIX::string_strip
std::string string_strip(const std::string &value)
Definition: Utility.cpp:84
FIX::thread_detach
void thread_detach(thread_id thread)
Definition: Utility.cpp:464
FIX::socket_getsockopt
int socket_getsockopt(int s, int opt, int &optval)
Definition: Utility.cpp:250
FIX::socket_term
void socket_term()
Definition: Utility.cpp:113
FIX::file_rename
int file_rename(const char *oldpath, const char *newpath)
Definition: Utility.cpp:563
FIX::socket_isValid
bool socket_isValid(int socket)
Definition: Utility.cpp:294
FIX::file_exists
bool file_exists(const char *path)
Definition: Utility.cpp:542
FIX::socket_recv
ssize_t socket_recv(int s, char *buf, size_t length)
Definition: Utility.cpp:187
FIX::socket_bind
int socket_bind(int socket, const char *hostname, int port)
Definition: Utility.cpp:120
FIX::socket_isBad
bool socket_isBad(int s)
Definition: Utility.cpp:304
FIX::socket_disconnected
bool socket_disconnected(int s)
Definition: Utility.cpp:219
FIX::socket_accept
int socket_accept(int s)
Definition: Utility.cpp:181
FIX::socket_hostport
short socket_hostport(int socket)
Definition: Utility.cpp:321
FIX::socket_send
ssize_t socket_send(int s, const char *msg, size_t length)
Definition: Utility.cpp:192
FIX::socket_createConnector
int socket_createConnector()
Definition: Utility.cpp:160
FIX::time_gmtime
tm time_gmtime(const time_t *t)
Definition: Utility.cpp:401
FIX::file_separator
std::string file_separator()
Definition: Utility.cpp:497
FIX::string_replace
void string_replace(const std::string &oldValue, const std::string &newValue, std::string &value)
Definition: Utility.cpp:57
FIX::socket_getfcntlflag
int socket_getfcntlflag(int s, int arg)
Definition: Utility.cpp:272
FIX::file_unlink
void file_unlink(const char *path)
Definition: Utility.cpp:554
FIX::process_sleep
void process_sleep(double s)
Definition: Utility.cpp:483
FIX::THREAD_START_ROUTINE
void *() THREAD_START_ROUTINE(void *)
Definition: Utility.h:183
FIX::socket_setnonblock
void socket_setnonblock(int socket)
Definition: Utility.cpp:285
FIX::file_mkdir
void file_mkdir(const char *path)
Definition: Utility.cpp:506
FIX
Definition: Acceptor.cpp:34
FIX::socket_createAcceptor
int socket_createAcceptor(int port, bool reuse)
Definition: Utility.cpp:137
FIX::socket_invalidate
void socket_invalidate(int &socket)
Definition: Utility.cpp:312
FIX::socket_hostname
const char * socket_hostname(int socket)
Definition: Utility.cpp:331
FIX::socket_close
void socket_close(int s)
Definition: Utility.cpp:197
FIX::file_fopen
FILE * file_fopen(const char *path, const char *mode)
Definition: Utility.cpp:526
FIX::thread_self
thread_id thread_self()
Definition: Utility.cpp:474
FIX::thread_join
void thread_join(thread_id thread)
Definition: Utility.cpp:454
Utility.h
FIX::socket_fionread
bool socket_fionread(int s, int &bytes)
Definition: Utility.cpp:207
FIX::thread_spawn
bool thread_spawn(THREAD_START_ROUTINE func, void *var, thread_id &thread)
Definition: Utility.cpp:433
FIX::string_toLower
std::string string_toLower(const std::string &value)
Definition: Utility.cpp:77
FIX::socket_createpair
std::pair< int, int > socket_createpair()
Definition: Utility.cpp:383
FIX::socket_peername
const char * socket_peername(int socket)
Definition: Utility.cpp:370
FIX::socket_setfcntlflag
int socket_setfcntlflag(int s, int arg)
Definition: Utility.cpp:277

Generated on Wed Apr 29 2020 19:41:30 for QuickFIX by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2001