Index Source Files Annotated Class List Alphabetical Class List Class Hierarchy Graphical Class Hierarchy

# Utility.cpp

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 ** Copyright (c) quickfixengine.org  All rights reserved.
    00003 **
    00004 ** This file is part of the QuickFIX FIX Engine
    00005 **
    00006 ** This file may be distributed under the terms of the quickfixengine.org
    00007 ** license as defined by quickfixengine.org and appearing in the file
    00008 ** LICENSE included in the packaging of this file.
    00009 **
    00010 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    00011 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    00012 **
    00013 ** See http://www.quickfixengine.org/LICENSE for licensing information.
    00014 **
    00015 ** Contact ask@quickfixengine.org if any conditions of this licensing are
    00016 ** not clear to you.
    00017 **
    00018 ****************************************************************************/
    00019
    00020 #ifdef _MSC_VER
    00021 #include "stdafx.h"
    00022 #else
    00023 #include "config.h"
    00024 #endif
    00025 #include "CallStack.h"
    00026
    00027 #include "Utility.h"
    00028
    00029 #ifdef USING_STREAMS
    00030 #include <stropts.h>
    00031 #include <sys/conf.h>
    00032 #endif
    00033 #include <math.h>
    00034 #include <stdio.h>
    00035 #include <algorithm>
    00036 #include <fstream>
    00037
    00038 namespace FIX
    00039 {
    00040 void string_replace( const std::string& oldValue,
    00041                              const std::string& newValue,
    00042                              std::string& value )
    00043 { QF_STACK_PUSH(string_replace)
    00044
    00045   for( std::string::size_type pos = value.find(oldValue);
    00046        pos != std::string::npos;
    00047        pos = value.find(oldValue, pos) )
    00048   {
    00049     value.replace( pos, oldValue.size(), newValue );
    00050     pos += newValue.size();
    00051   }
    00052
    00053   QF_STACK_POP
    00054 }
    00055
    00056 std::string string_toUpper( const std::string& value )
    00057 { QF_STACK_PUSH(string_toUpper)
    00058
    00059   std::string copy = value;
    00060   std::transform( copy.begin(), copy.end(), copy.begin(), toupper );
    00061   return copy;
    00062
    00063   QF_STACK_POP
    00064 }
    00065
    00066 std::string string_toLower( const std::string& value )
    00067 { QF_STACK_PUSH(string_toLower)
    00068
    00069   std::string copy = value;
    00070   std::transform( copy.begin(), copy.end(), copy.begin(), tolower );
    00071   return copy;
    00072
    00073   QF_STACK_POP
    00074 }
    00075
    00076 std::string string_strip( const std::string& value )
    00077 { QF_STACK_PUSH(string_strip)
    00078
    00079   if( !value.size() )
    00080     return value;
    00081
    00082   int startPos = value.find_first_not_of(" \t\r\n");
    00083   int endPos = value.find_last_not_of(" \t\r\n");
    00084
    00085   if( startPos == -1 )
    00086    return value;
    00087
    00088    return std::string( value, startPos, endPos - startPos + 1 );
    00089
    00090   QF_STACK_POP
    00091 }
    00092
    00093 void socket_init()
    00094 { QF_STACK_PUSH(socket_init)
    00095
    00096 #ifdef _MSC_VER
    00097   WORD version = MAKEWORD( 2, 2 );
    00098   WSADATA data;
    00099   WSAStartup( version, &data );
    00100 #else
    00101   struct sigaction sa;
    00102   sa.sa_handler = SIG_IGN;
    00103   sigemptyset( &sa.sa_mask );
    00104   sa.sa_flags = 0;
    00105   sigaction( SIGPIPE, &sa, 0 );
    00106 #endif
    00107
    00108   QF_STACK_POP
    00109 }
    00110
    00111 void socket_term()
    00112 { QF_STACK_PUSH(socket_term)
    00113
    00114 #ifdef _MSC_VER
    00115   WSACleanup();
    00116 #endif
    00117
    00118   QF_STACK_POP
    00119 }
    00120
    00121 int socket_createAcceptor(int port, bool reuse)
    00122 { QF_STACK_PUSH(socket_createAcceptor)
    00123
    00124   int socket = ::socket( PF_INET, SOCK_STREAM, 0 );
    00125   if ( socket < 0 ) return -1;
    00126
    00127   sockaddr_in address;
    00128   socklen_t socklen;
    00129
    00130   address.sin_family = PF_INET;
    00131   address.sin_port = htons( port );
    00132   address.sin_addr.s_addr = INADDR_ANY;
    00133   socklen = sizeof( address );
    00134   if( reuse )
    00135     socket_setsockopt( socket, SO_REUSEADDR );
    00136
    00137   int result = bind( socket, reinterpret_cast < sockaddr* > ( &address ),
    00138                      socklen );
    00139   if ( result < 0 ) return -1;
    00140   result = listen( socket, SOMAXCONN );
    00141   if ( result < 0 ) return -1;
    00142   return socket;
    00143
    00144   QF_STACK_POP
    00145 }
    00146
    00147 int socket_createConnector()
    00148 { QF_STACK_PUSH(socket_createConnector)
    00149   return ::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
    00150   QF_STACK_POP
    00151 }
    00152
    00153 int socket_connect( int socket, const char* address, int port )
    00154 { QF_STACK_PUSH(socket_connect)
    00155
    00156   const char* hostname = socket_hostname( address );
    00157   if( hostname == 0 ) return -1;
    00158
    00159   sockaddr_in addr;
    00160   addr.sin_family = PF_INET;
    00161   addr.sin_port = htons( port );
    00162   addr.sin_addr.s_addr = inet_addr( hostname );
    00163
    00164   int result = connect( socket, reinterpret_cast < sockaddr* > ( &addr ),
    00165                         sizeof( addr ) );
    00166
    00167   return result;
    00168
    00169   QF_STACK_POP
    00170 }
    00171
    00172 int socket_accept( int s )
    00173 { QF_STACK_PUSH(socket_accept)
    00174
    00175   if ( !socket_isValid( s ) ) return -1;
    00176   return accept( s, 0, 0 );
    00177
    00178   QF_STACK_POP
    00179 }
    00180
    00181 int socket_send( int s, const char* msg, int length )
    00182 { QF_STACK_PUSH(socket_send)
    00183   return send( s, msg, length, 0 );
    00184   QF_STACK_POP
    00185 }
    00186
    00187 void socket_close( int s )
    00188 { QF_STACK_PUSH(socket_close)
    00189
    00190   shutdown( s, 2 );
    00191 #ifdef _MSC_VER
    00192   closesocket( s );
    00193 #else
    00194   close( s );
    00195 #endif
    00196
    00197   QF_STACK_POP
    00198 }
    00199
    00200 bool socket_fionread( int s, int& bytes )
    00201 { QF_STACK_PUSH(socket_fionread)
    00202
    00203   bytes = 0;
    00204 #if defined(_MSC_VER)
    00205   return ::ioctlsocket( s, FIONREAD, &( ( unsigned long& ) bytes ) ) == 0;
    00206 #elif defined(USING_STREAMS)
    00207   return ::ioctl( s, I_NREAD, &bytes ) >= 0;
    00208 #else
    00209   return ::ioctl( s, FIONREAD, &bytes ) == 0;
    00210 #endif
    00211
    00212   QF_STACK_POP
    00213 }
    00214
    00215 bool socket_disconnected( int s )
    00216 { QF_STACK_PUSH(socket_disconnected)
    00217
    00218   char byte;
    00219   return ::recv (s, &byte, sizeof (byte), MSG_PEEK) <= 0;
    00220
    00221   QF_STACK_POP
    00222 }
    00223
    00224 int socket_setsockopt( int s, int opt )
    00225 { QF_STACK_PUSH(socket_setsockopt)
    00226
    00227 #ifdef _MSC_VER
    00228   BOOL optval = TRUE;
    00229 #else
    00230   int optval = 1;
    00231 #endif
    00232   return socket_setsockopt( s, opt, optval );
    00233
    00234   QF_STACK_POP
    00235 }
    00236
    00237 int socket_setsockopt( int s, int opt, int optval )
    00238 { QF_STACK_PUSH(socket_setsockopt)
    00239
    00240   int level = SOL_SOCKET;
    00241   if( opt == TCP_NODELAY )
    00242     level = IPPROTO_TCP;
    00243
    00244 #ifdef _MSC_VER
    00245   return ::setsockopt( s, level, opt,
    00246                        ( char* ) & optval, sizeof( optval ) );
    00247 #else
    00248   return ::setsockopt( s, level, opt,
    00249                        &optval, sizeof( optval ) );
    00250 #endif
    00251
    00252   QF_STACK_POP
    00253 }
    00254
    00255 int socket_getsockopt( int s, int opt, int& optval )
    00256 { QF_STACK_PUSH(socket_getsockopt)
    00257
    00258   int level = SOL_SOCKET;
    00259   if( opt == TCP_NODELAY )
    00260     level = IPPROTO_TCP;
    00261
    00262 #ifdef _MSC_VER
    00263   int length = sizeof(int);
    00264 #else
    00265   socklen_t length = sizeof(socklen_t);
    00266 #endif
    00267
    00268   return ::getsockopt( s, level, opt,
    00269                        ( char* ) & optval, & length );
    00270
    00271   QF_STACK_POP
    00272 }
    00273
    00274 #ifndef _MSC_VER
    00275 int socket_fcntl( int s, int opt, int arg )
    00276 { QF_STACK_PUSH(socket_fcntl)
    00277   return ::fcntl( s, opt, arg );
    00278   QF_STACK_POP
    00279 }
    00280
    00281 int socket_getfcntlflag( int s, int arg )
    00282 { QF_STACK_PUSH(socket_getfcntlflag)
    00283   return socket_fcntl( s, F_GETFL, arg );
    00284   QF_STACK_POP
    00285 }
    00286
    00287 int socket_setfcntlflag( int s, int arg )
    00288 { QF_STACK_PUSH(socket_setfcntlflag)
    00289
    00290   int oldValue = socket_getfcntlflag( s, arg );
    00291   oldValue |= arg;
    00292   return socket_fcntl( s, F_SETFL, arg );
    00293
    00294   QF_STACK_POP
    00295 }
    00296 #endif
    00297
    00298 void socket_setnonblock( int socket )
    00299 { QF_STACK_PUSH(socket_setnonblock)
    00300
    00301 #ifdef _MSC_VER
    00302   u_long opt = 1;
    00303   ::ioctlsocket( socket, FIONBIO, &opt );
    00304 #else
    00305   socket_setfcntlflag( socket, O_NONBLOCK );
    00306 #endif
    00307
    00308   QF_STACK_POP
    00309 }
    00310 bool socket_isValid( int socket )
    00311 { QF_STACK_PUSH(socket_isValid)
    00312
    00313 #ifdef _MSC_VER
    00314   return socket != INVALID_SOCKET;
    00315 #else
    00316   return socket >= 0;
    00317 #endif
    00318
    00319   QF_STACK_POP
    00320 }
    00321
    00322 #ifndef _MSC_VER
    00323 bool socket_isBad( int s )
    00324 { QF_STACK_PUSH(socket_isBad)
    00325
    00326   struct stat buf;
    00327   fstat( s, &buf );
    00328   return errno == EBADF;
    00329
    00330   QF_STACK_POP
    00331 }
    00332 #endif
    00333
    00334 void socket_invalidate( int& socket )
    00335 { QF_STACK_PUSH(socket_invalidate)
    00336
    00337 #ifdef _MSC_VER
    00338   socket = INVALID_SOCKET;
    00339 #else
    00340   socket = -1;
    00341 #endif
    00342
    00343   QF_STACK_POP
    00344 }
    00345
    00346 short socket_hostport( int socket )
    00347 { QF_STACK_PUSH(socket_hostport)
    00348
    00349   struct sockaddr_in addr;
    00350   socklen_t len = sizeof(addr);
    00351   if( getsockname(socket, (struct sockaddr*)&addr, &len) < 0 )
    00352     return 0;
    00353
    00354   return ntohs( addr.sin_port );
    00355
    00356   QF_STACK_POP
    00357 }
    00358
    00359 const char* socket_hostname( int socket )
    00360 { QF_STACK_PUSH(socket_hostname)
    00361
    00362   struct sockaddr_in addr;
    00363   socklen_t len = sizeof(addr);
    00364   if( getsockname(socket, (struct sockaddr*)&addr, &len) < 0 )
    00365     return 0;
    00366
    00367   return inet_ntoa( addr.sin_addr );
    00368
    00369   QF_STACK_POP
    00370 }
    00371
    00372 const char* socket_hostname( const char* name )
    00373 { QF_STACK_PUSH(socket_hostname)
    00374
    00375   struct hostent* host_ptr = 0;
    00376   struct in_addr** paddr;
    00377   struct in_addr saddr;
    00378
    00379 #if( GETHOSTBYNAME_R_INPUTS_RESULT || GETHOSTBYNAME_R_RETURNS_RESULT )
    00380   hostent host;
    00381   char buf[1024];
    00382   int error;
    00383 #endif
    00384
    00385   saddr.s_addr = inet_addr( name );
    00386   if ( saddr.s_addr != ( unsigned ) - 1 ) return name;
    00387
    00388 #if GETHOSTBYNAME_R_INPUTS_RESULT
    00389   gethostbyname_r( name, &host, buf, sizeof(buf), &host_ptr, &error );
    00390 #elif GETHOSTBYNAME_R_RETURNS_RESULT
    00391   host_ptr = gethostbyname_r( name, &host, buf, sizeof(buf), &error );
    00392 #else
    00393   host_ptr = gethostbyname( name );
    00394 #endif
    00395
    00396   if ( host_ptr == 0 ) return 0;
    00397
    00398   paddr = ( struct in_addr ** ) host_ptr->h_addr_list;
    00399   return inet_ntoa( **paddr );
    00400
    00401   QF_STACK_POP
    00402 }
    00403
    00404 const char* socket_peername( int socket )
    00405 { QF_STACK_PUSH(socket_peername)
    00406
    00407   struct sockaddr_in addr;
    00408   socklen_t len = sizeof(addr);
    00409   if( getpeername( socket, (struct sockaddr*)&addr, &len ) < 0 )
    00410     return "UNKNOWN";
    00411   char* result = inet_ntoa( addr.sin_addr );
    00412   if( result )
    00413     return result;
    00414   else
    00415     return "UNKNOWN";
    00416
    00417
    00418   QF_STACK_POP
    00419 }
    00420
    00421 std::pair<int, int> socket_createpair()
    00422 { QF_STACK_PUSH(socket_createpair)
    00423
    00424 #ifdef _MSC_VER
    00425   int acceptor = socket_createAcceptor(0, true);
    00426   const char* host = socket_hostname( acceptor );
    00427   short port = socket_hostport( acceptor );
    00428   int client = socket_createConnector();
    00429   socket_connect( client, "localhost", port );
    00430   int server = socket_accept( acceptor );
    00431   return std::pair<int, int>( client, server );
    00432 #else
    00433   int pair[2];
    00434   socketpair( AF_UNIX, SOCK_STREAM, 0, pair );
    00435   return std::pair<int, int>( pair[0], pair[1] );
    00436 #endif
    00437
    00438   QF_STACK_POP
    00439 }
    00440
    00441 tm time_gmtime( const time_t* t )
    00442 { QF_STACK_PUSH(time_gmtime)
    00443
    00444 #ifdef _MSC_VER
    00445   #if( _MSC_VER >= 1400 )
    00446     tm result;
    00447     gmtime_s( &result, t );
    00448     return result;
    00449   #else
    00450     return *gmtime( t );
    00451   #endif
    00452 #else
    00453   tm result;
    00454   return *gmtime_r( t, &result );
    00455 #endif
    00456
    00457   QF_STACK_POP
    00458 }
    00459
    00460 tm time_localtime( const time_t* t)
    00461 { QF_STACK_PUSH(time_localtime)
    00462
    00463 #ifdef _MSC_VER
    00464   #if( _MSC_VER >= 1400 )
    00465     tm result;
    00466     localtime_s( &result, t );
    00467     return result;
    00468   #else
    00469     return *localtime( t );
    00470   #endif
    00471 #else
    00472   tm result;
    00473   return *localtime_r( t, &result );
    00474 #endif
    00475
    00476   QF_STACK_POP
    00477 }
    00478
    00479 bool thread_spawn( THREAD_START_ROUTINE func, void* var, thread_id& thread )
    00480 {
    00481 #ifdef _MSC_VER
    00482   thread_id result = 0;
    00483   unsigned int id = 0;
    00484   result = _beginthreadex( NULL, 0, &func, var, 0, &id );
    00485   if ( result == 0 ) return false;
    00486 #else
    00487   thread_id result = 0;
    00488   if( pthread_create( &result, 0, func, var ) != 0 ) return false;
    00489 #endif
    00490   thread = result;
    00491   return true;
    00492 }
    00493
    00494 bool thread_spawn( THREAD_START_ROUTINE func, void* var )
    00495 {
    00496   thread_id thread = 0;
    00497   return thread_spawn( func, var, thread );
    00498 }
    00499
    00500 void thread_join( thread_id thread )
    00501 { QF_STACK_PUSH(thread_join)
    00502
    00503 #ifdef _MSC_VER
    00504   WaitForSingleObject( ( void* ) thread, INFINITE );
    00505   CloseHandle((HANDLE)thread);
    00506 #else
    00507   pthread_join( ( pthread_t ) thread, 0 );
    00508 #endif
    00509
    00510   QF_STACK_POP
    00511 }
    00512
    00513 void thread_detach( thread_id thread )
    00514 { QF_STACK_PUSH(thread_detach)
    00515
    00516 #ifdef _MSC_VER
    00517   CloseHandle((HANDLE)thread);
    00518 #else
    00519   pthread_t t = thread;
    00520   pthread_detach( t );
    00521 #endif
    00522
    00523   QF_STACK_POP
    00524 }
    00525
    00526 thread_id thread_self()
    00527 {
    00528 #ifdef _MSC_VER
    00529   return (unsigned)GetCurrentThread();
    00530 #else
    00531   return pthread_self();
    00532 #endif
    00533 }
    00534
    00535 void process_sleep( double s )
    00536 { QF_STACK_PUSH(process_sleep)
    00537
    00538 #ifdef _MSC_VER
    00539   Sleep( (long)(s * 1000) );
    00540 #else
    00541   timespec time, remainder;
    00542   double intpart;
    00543   time.tv_nsec = (long)(modf(s, &intpart) * 1e9);
    00544   time.tv_sec = (int)intpart;
    00545   while( nanosleep(&time, &remainder) == -1 )
    00546   time = remainder;
    00547 #endif
    00548
    00549   QF_STACK_POP
    00550 }
    00551
    00552 std::string file_separator()
    00553 { QF_STACK_PUSH(file_separator)
    00554
    00555 #ifdef _MSC_VER
    00556   return "\\";
    00557 #else
    00558   return "/";
    00559 #endif
    00560
    00561   QF_STACK_POP
    00562 }
    00563
    00564 void file_mkdir( const char* path )
    00565 { QF_STACK_PUSH(file_mkdir)
    00566
    00567   int length = strlen( path );
    00568   std::string createPath = "";
    00569
    00570   for( const char* pos = path; pos - path <= length; ++pos )
    00571   {
    00572     createPath += *pos;
    00573     if( *pos == '/' || *pos == '\\' || pos - path == length )
    00574     {
    00575     #ifdef _MSC_VER
    00576       _mkdir( createPath.c_str() );
    00577     #else
    00578       // use umask to override rwx for all
    00579       mkdir( createPath.c_str(), 0777 );
    00580     #endif
    00581     }
    00582   }
    00583
    00584   QF_STACK_POP
    00585 }
    00586
    00587 FILE* file_fopen( const char* path, const char* mode )
    00588 { QF_STACK_PUSH(file_fopen)
    00589
    00590 #if( _MSC_VER >= 1400 )
    00591   FILE* result = 0;
    00592   fopen_s( &result, path, mode );
    00593   return result;
    00594 #else
    00595   return fopen( path, mode );
    00596 #endif
    00597
    00598   QF_STACK_POP
    00599 }
    00600
    00601 void file_fclose( FILE* file )
    00602 { QF_STACK_PUSH(file_fclose)
    00603   fclose( file );
    00604   QF_STACK_POP
    00605 }
    00606
    00607 bool file_exists( const char* path )
    00608 { QF_STACK_PUSH(file_exists)
    00609
    00610   std::ifstream stream;
    00611   stream.open( path, std::ios_base::in );
    00612   if( stream.is_open() )
    00613   {
    00614     stream.close();
    00615     return true;
    00616   }
    00617   return false;
    00618
    00619   QF_STACK_POP
    00620 }
    00621
    00622 void file_unlink( const char* path )
    00623 { QF_STACK_PUSH(file_unlink)
    00624
    00625 #ifdef _MSC_VER
    00626   _unlink( path );
    00627 #else
    00628   unlink( path );
    00629 #endif
    00630
    00631   QF_STACK_POP
    00632 }
    00633
    00634 int file_rename( const char* oldpath, const char* newpath )
    00635 { QF_STACK_PUSH(file_rename)
    00636   return rename( oldpath, newpath );
    00637   QF_STACK_POP
    00638 }
    00639
    00640 std::string file_appendpath( const std::string& path, const std::string& file )
    00641 { QF_STACK_PUSH(file_appendpath)
    00642
    00643   const char last = path[path.size()-1];
    00644   if( last == '/' || last == '\\' )
    00645     return std::string(path) + file;
    00646   else
    00647     return std::string(path) + file_separator() + file;
    00648
    00649   QF_STACK_POP
    00650 }
    00651 }