Utility.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (c) 2001-2014
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 
00026 #include "Utility.h"
00027 
00028 #ifdef USING_STREAMS
00029 #include <stropts.h>
00030 #include <sys/conf.h>
00031 #endif
00032 #include <string.h>
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 {
00044   for( std::string::size_type pos = value.find(oldValue);
00045        pos != std::string::npos;
00046        pos = value.find(oldValue, pos) )
00047   {
00048     value.replace( pos, oldValue.size(), newValue );
00049     pos += newValue.size();
00050   }
00051 }
00052 
00053 std::string string_toUpper( const std::string& value )
00054 {
00055   std::string copy = value;
00056   std::transform( copy.begin(), copy.end(), copy.begin(), toupper );
00057   return copy;
00058 }
00059 
00060 std::string string_toLower( const std::string& value )
00061 {
00062   std::string copy = value;
00063   std::transform( copy.begin(), copy.end(), copy.begin(), tolower );
00064   return copy;
00065 }
00066 
00067 std::string string_strip( const std::string& value )
00068 {
00069   if( !value.size() )
00070     return value;
00071 
00072   size_t startPos = value.find_first_not_of(" \t\r\n");
00073   size_t endPos = value.find_last_not_of(" \t\r\n");
00074 
00075   if( startPos == std::string::npos )
00076    return value;
00077 
00078   return std::string( value, startPos, endPos - startPos + 1 );
00079 }
00080 
00081 void socket_init()
00082 {
00083 #ifdef _MSC_VER
00084   WORD version = MAKEWORD( 2, 2 );
00085   WSADATA data;
00086   WSAStartup( version, &data );
00087 #else
00088   struct sigaction sa;
00089   sa.sa_handler = SIG_IGN;
00090   sigemptyset( &sa.sa_mask );
00091   sa.sa_flags = 0;
00092   sigaction( SIGPIPE, &sa, 0 );
00093 #endif
00094 }
00095 
00096 void socket_term()
00097 {
00098 #ifdef _MSC_VER
00099   WSACleanup();
00100 #endif
00101 }
00102 
00103 int socket_createAcceptor(int port, bool reuse)
00104 {
00105   int socket = ::socket( PF_INET, SOCK_STREAM, 0 );
00106   if ( socket < 0 ) return -1;
00107 
00108   sockaddr_in address;
00109   socklen_t socklen;
00110 
00111   address.sin_family = PF_INET;
00112   address.sin_port = htons( port );
00113   address.sin_addr.s_addr = INADDR_ANY;
00114   socklen = sizeof( address );
00115   if( reuse )
00116     socket_setsockopt( socket, SO_REUSEADDR );
00117 
00118   int result = bind( socket, reinterpret_cast < sockaddr* > ( &address ),
00119                      socklen );
00120   if ( result < 0 ) return -1;
00121   result = listen( socket, SOMAXCONN );
00122   if ( result < 0 ) return -1;
00123   return socket;
00124 }
00125 
00126 int socket_createConnector()
00127 {
00128   return ::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
00129 }
00130 
00131 int socket_connect( int socket, const char* address, int port )
00132 {
00133   const char* hostname = socket_hostname( address );
00134   if( hostname == 0 ) return -1;
00135 
00136   sockaddr_in addr;
00137   addr.sin_family = PF_INET;
00138   addr.sin_port = htons( port );
00139   addr.sin_addr.s_addr = inet_addr( hostname );
00140 
00141   int result = connect( socket, reinterpret_cast < sockaddr* > ( &addr ),
00142                         sizeof( addr ) );
00143 
00144   return result;
00145 }
00146 
00147 int socket_accept( int s )
00148 {
00149   if ( !socket_isValid( s ) ) return -1;
00150   return accept( s, 0, 0 );
00151 }
00152 
00153 ssize_t socket_send( int s, const char* msg, size_t length )
00154 {
00155   return send( s, msg, length, 0 );
00156 }
00157 
00158 void socket_close( int s )
00159 {
00160   shutdown( s, 2 );
00161 #ifdef _MSC_VER
00162   closesocket( s );
00163 #else
00164   close( s );
00165 #endif
00166 }
00167 
00168 bool socket_fionread( int s, int& bytes )
00169 {
00170   bytes = 0;
00171 #if defined(_MSC_VER)
00172   return ::ioctlsocket( s, FIONREAD, &( ( unsigned long& ) bytes ) ) == 0;
00173 #elif defined(USING_STREAMS)
00174   return ::ioctl( s, I_NREAD, &bytes ) >= 0;
00175 #else
00176   return ::ioctl( s, FIONREAD, &bytes ) == 0;
00177 #endif
00178 }
00179 
00180 bool socket_disconnected( int s )
00181 {
00182   char byte;
00183   return ::recv (s, &byte, sizeof (byte), MSG_PEEK) <= 0;
00184 }
00185 
00186 int socket_setsockopt( int s, int opt )
00187 {
00188 #ifdef _MSC_VER
00189   BOOL optval = TRUE;
00190 #else
00191   int optval = 1;
00192 #endif
00193   return socket_setsockopt( s, opt, optval );
00194 }
00195 
00196 int socket_setsockopt( int s, int opt, int optval )
00197 {
00198   int level = SOL_SOCKET;
00199   if( opt == TCP_NODELAY )
00200     level = IPPROTO_TCP;
00201 
00202 #ifdef _MSC_VER
00203   return ::setsockopt( s, level, opt,
00204                        ( char* ) & optval, sizeof( optval ) );
00205 #else
00206   return ::setsockopt( s, level, opt,
00207                        &optval, sizeof( optval ) );
00208 #endif
00209 }
00210 
00211 int socket_getsockopt( int s, int opt, int& optval )
00212 {
00213   int level = SOL_SOCKET;
00214   if( opt == TCP_NODELAY )
00215     level = IPPROTO_TCP;
00216 
00217 #ifdef _MSC_VER
00218   int length = sizeof(int);
00219 #else
00220   socklen_t length = sizeof(socklen_t);
00221 #endif
00222 
00223   return ::getsockopt( s, level, opt, 
00224                        ( char* ) & optval, & length );
00225 }
00226 
00227 #ifndef _MSC_VER
00228 int socket_fcntl( int s, int opt, int arg )
00229 {
00230   return ::fcntl( s, opt, arg );
00231 }
00232 
00233 int socket_getfcntlflag( int s, int arg )
00234 {
00235   return socket_fcntl( s, F_GETFL, arg );
00236 }
00237 
00238 int socket_setfcntlflag( int s, int arg )
00239 {
00240   int oldValue = socket_getfcntlflag( s, arg );
00241   oldValue |= arg;
00242   return socket_fcntl( s, F_SETFL, arg );
00243 }
00244 #endif
00245 
00246 void socket_setnonblock( int socket )
00247 {
00248 #ifdef _MSC_VER
00249   u_long opt = 1;
00250   ::ioctlsocket( socket, FIONBIO, &opt );
00251 #else
00252   socket_setfcntlflag( socket, O_NONBLOCK );
00253 #endif
00254 }
00255 bool socket_isValid( int socket )
00256 {
00257 #ifdef _MSC_VER
00258   return socket != INVALID_SOCKET;
00259 #else
00260   return socket >= 0;
00261 #endif
00262 }
00263 
00264 #ifndef _MSC_VER
00265 bool socket_isBad( int s )
00266 {
00267   struct stat buf;
00268   fstat( s, &buf );
00269   return errno == EBADF;
00270 }
00271 #endif
00272 
00273 void socket_invalidate( int& socket )
00274 {
00275 #ifdef _MSC_VER
00276   socket = INVALID_SOCKET;
00277 #else
00278   socket = -1;
00279 #endif
00280 }
00281 
00282 short socket_hostport( int socket )
00283 {
00284   struct sockaddr_in addr;
00285   socklen_t len = sizeof(addr);
00286   if( getsockname(socket, (struct sockaddr*)&addr, &len) < 0 )
00287     return 0;
00288 
00289   return ntohs( addr.sin_port );
00290 }
00291 
00292 const char* socket_hostname( int socket )
00293 {
00294   struct sockaddr_in addr;
00295   socklen_t len = sizeof(addr);
00296   if( getsockname(socket, (struct sockaddr*)&addr, &len) < 0 )
00297     return 0;
00298 
00299   return inet_ntoa( addr.sin_addr );
00300 }
00301 
00302 const char* socket_hostname( const char* name )
00303 {
00304   struct hostent* host_ptr = 0;
00305   struct in_addr** paddr;
00306   struct in_addr saddr;
00307 
00308 #if( GETHOSTBYNAME_R_INPUTS_RESULT || GETHOSTBYNAME_R_RETURNS_RESULT )
00309   hostent host;
00310   char buf[1024];
00311   int error;
00312 #endif
00313 
00314   saddr.s_addr = inet_addr( name );
00315   if ( saddr.s_addr != ( unsigned ) - 1 ) return name;
00316 
00317 #if GETHOSTBYNAME_R_INPUTS_RESULT
00318   gethostbyname_r( name, &host, buf, sizeof(buf), &host_ptr, &error );
00319 #elif GETHOSTBYNAME_R_RETURNS_RESULT
00320   host_ptr = gethostbyname_r( name, &host, buf, sizeof(buf), &error );
00321 #else
00322   host_ptr = gethostbyname( name );
00323 #endif
00324 
00325   if ( host_ptr == 0 ) return 0;
00326 
00327   paddr = ( struct in_addr ** ) host_ptr->h_addr_list;
00328   return inet_ntoa( **paddr );
00329 }
00330 
00331 const char* socket_peername( int socket )
00332 {
00333   struct sockaddr_in addr;
00334   socklen_t len = sizeof(addr);
00335   if( getpeername( socket, (struct sockaddr*)&addr, &len ) < 0 )
00336     return "UNKNOWN";
00337   char* result = inet_ntoa( addr.sin_addr );
00338   if( result )
00339     return result;
00340   else
00341     return "UNKNOWN";
00342 }
00343 
00344 std::pair<int, int> socket_createpair()
00345 {
00346 #ifdef _MSC_VER
00347   int acceptor = socket_createAcceptor(0, true);
00348   const char* host = socket_hostname( acceptor );
00349   short port = socket_hostport( acceptor );
00350   int client = socket_createConnector();
00351   socket_connect( client, "localhost", port );
00352   int server = socket_accept( acceptor );
00353   socket_close(acceptor);
00354   return std::pair<int, int>( client, server );
00355 #else
00356   int pair[2];
00357   socketpair( AF_UNIX, SOCK_STREAM, 0, pair );
00358   return std::pair<int, int>( pair[0], pair[1] );
00359 #endif
00360 }
00361 
00362 tm time_gmtime( const time_t* t )
00363 {
00364 #ifdef _MSC_VER
00365   #if( _MSC_VER >= 1400 )
00366     tm result;
00367     gmtime_s( &result, t );
00368     return result;
00369   #else
00370     return *gmtime( t );
00371   #endif
00372 #else
00373   tm result;
00374   return *gmtime_r( t, &result );
00375 #endif
00376 }
00377 
00378 tm time_localtime( const time_t* t)
00379 {
00380 #ifdef _MSC_VER
00381   #if( _MSC_VER >= 1400 )
00382     tm result;
00383     localtime_s( &result, t );
00384     return result;
00385   #else
00386     return *localtime( t );
00387   #endif
00388 #else
00389   tm result;
00390   return *localtime_r( t, &result );
00391 #endif
00392 }
00393 
00394 bool thread_spawn( THREAD_START_ROUTINE func, void* var, thread_id& thread )
00395 {
00396 #ifdef _MSC_VER
00397   thread_id result = 0;
00398   unsigned int id = 0;
00399   result = _beginthreadex( NULL, 0, &func, var, 0, &id );
00400   if ( result == 0 ) return false;
00401 #else
00402   thread_id result = 0;
00403   if( pthread_create( &result, 0, func, var ) != 0 ) return false;
00404 #endif
00405   thread = result;
00406   return true;
00407 }
00408 
00409 bool thread_spawn( THREAD_START_ROUTINE func, void* var )
00410 { 
00411   thread_id thread = 0;
00412   return thread_spawn( func, var, thread );
00413 }
00414 
00415 void thread_join( thread_id thread )
00416 {
00417 #ifdef _MSC_VER
00418   WaitForSingleObject( ( void* ) thread, INFINITE );
00419   CloseHandle((HANDLE)thread);
00420 #else
00421   pthread_join( ( pthread_t ) thread, 0 );
00422 #endif
00423 }
00424 
00425 void thread_detach( thread_id thread )
00426 {
00427 #ifdef _MSC_VER
00428   CloseHandle((HANDLE)thread);
00429 #else
00430   pthread_t t = thread;
00431   pthread_detach( t );
00432 #endif
00433 }
00434 
00435 thread_id thread_self()
00436 {
00437 #ifdef _MSC_VER
00438   return (unsigned)GetCurrentThread();
00439 #else
00440   return pthread_self();
00441 #endif
00442 }
00443 
00444 void process_sleep( double s )
00445 {
00446 #ifdef _MSC_VER
00447   Sleep( (long)(s * 1000) );
00448 #else
00449   timespec time, remainder;
00450   double intpart;
00451   time.tv_nsec = (long)(modf(s, &intpart) * 1e9);
00452   time.tv_sec = (int)intpart;
00453   while( nanosleep(&time, &remainder) == -1 )
00454   time = remainder;
00455 #endif
00456 }
00457 
00458 std::string file_separator()
00459 {
00460 #ifdef _MSC_VER
00461   return "\\";
00462 #else
00463   return "/";
00464 #endif
00465 }
00466 
00467 void file_mkdir( const char* path )
00468 {
00469   int length = (int)strlen( path );
00470   std::string createPath = "";
00471 
00472   for( const char* pos = path; (pos - path) <= length; ++pos )
00473   {
00474     createPath += *pos;
00475     if( *pos == '/' || *pos == '\\' || (pos - path) == length )
00476     {
00477     #ifdef _MSC_VER
00478       _mkdir( createPath.c_str() );
00479     #else
00480       // use umask to override rwx for all
00481       mkdir( createPath.c_str(), 0777 );
00482     #endif
00483     }
00484   }
00485 }
00486 
00487 FILE* file_fopen( const char* path, const char* mode )
00488 {
00489 #if( _MSC_VER >= 1400 )
00490   FILE* result = 0;
00491   fopen_s( &result, path, mode );
00492   return result;
00493 #else
00494   return fopen( path, mode );
00495 #endif
00496 }
00497 
00498 void file_fclose( FILE* file )
00499 {
00500   fclose( file );
00501 }
00502 
00503 bool file_exists( const char* path )
00504 {
00505   std::ifstream stream;
00506   stream.open( path, std::ios_base::in );
00507   if( stream.is_open() )
00508   {
00509     stream.close();
00510     return true;
00511   }
00512   return false;
00513 }
00514 
00515 void file_unlink( const char* path )
00516 {
00517 #ifdef _MSC_VER
00518   _unlink( path );
00519 #else
00520   unlink( path );
00521 #endif
00522 }
00523 
00524 int file_rename( const char* oldpath, const char* newpath )
00525 {
00526   return rename( oldpath, newpath );
00527 }
00528 
00529 std::string file_appendpath( const std::string& path, const std::string& file )
00530 {
00531   const char last = path[path.size()-1];
00532   if( last == '/' || last == '\\' )
00533     return std::string(path) + file;
00534   else
00535     return std::string(path) + file_separator() + file;
00536 }
00537 }

Generated on Mon Sep 15 2014 01:23:55 for QuickFIX by doxygen 1.7.6.1 written by Dimitri van Heesch, © 1997-2001