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 }

Generated on Mon Apr 5 20:59:51 2010 for QuickFIX by doxygen 1.6.1 written by Dimitri van Heesch, © 1997-2001