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
38namespace FIX
39{
40void 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
53std::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
60std::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
67std::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
103int 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
120int 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
148int 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
164int socket_accept( int s )
165{
166 if ( !socket_isValid( s ) ) return -1;
167 return accept( s, 0, 0 );
168}
169
170ssize_t socket_recv( int s, char* buf, size_t length )
171{
172 return recv( s, buf, length, 0 );
173}
174
175ssize_t socket_send( int s, const char* msg, size_t length )
176{
177 return send( s, msg, length, 0 );
178}
179
180void 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
190bool 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
203{
204 char byte;
205 return ::recv (s, &byte, sizeof (byte), MSG_PEEK) <= 0;
206}
207
208int 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
218int 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
233int 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
250int socket_fcntl( int s, int opt, int arg )
251{
252 return ::fcntl( s, opt, arg );
253}
254
255int socket_getfcntlflag( int s, int arg )
256{
257 return socket_fcntl( s, F_GETFL, arg );
258}
259
260int 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
268void 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}
277bool 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
287bool socket_isBad( int s )
288{
289 struct stat buf;
290 fstat( s, &buf );
291 return errno == EBADF;
292}
293#endif
294
295void socket_invalidate( int& socket )
296{
297#ifdef _MSC_VER
298 socket = INVALID_SOCKET;
299#else
300 socket = -1;
301#endif
302}
303
304short 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
314const 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
324const 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
353const 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
366std::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
384tm 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
400tm 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
416bool 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
431bool thread_spawn( THREAD_START_ROUTINE func, void* var )
432{
433 thread_id thread = 0;
434 return thread_spawn( func, var, thread );
435}
436
437void 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
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
466void 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
480std::string file_separator()
481{
482#ifdef _MSC_VER
483 return "\\";
484#else
485 return "/";
486#endif
487}
488
489void 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
509FILE* 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
520void file_fclose( FILE* file )
521{
522 fclose( file );
523}
524
525bool 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
537void file_unlink( const char* path )
538{
539#ifdef _MSC_VER
540 _unlink( path );
541#else
542 unlink( path );
543#endif
544}
545
546int file_rename( const char* oldpath, const char* newpath )
547{
548 return rename( oldpath, newpath );
549}
550
551std::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}
std::string string_strip(const std::string &value)
Definition Utility.cpp:67
void socket_setnonblock(int socket)
Definition Utility.cpp:268
int socket_accept(int s)
Definition Utility.cpp:164
int socket_setsockopt(int s, int opt)
Definition Utility.cpp:208
bool socket_fionread(int s, int &bytes)
Definition Utility.cpp:190
int socket_getfcntlflag(int s, int arg)
Definition Utility.cpp:255
void thread_detach(thread_id thread)
Definition Utility.cpp:447
bool socket_isBad(int s)
Definition Utility.cpp:287
int socket_createConnector()
Definition Utility.cpp:143
int socket_setfcntlflag(int s, int arg)
Definition Utility.cpp:260
void file_unlink(const char *path)
Definition Utility.cpp:537
int file_rename(const char *oldpath, const char *newpath)
Definition Utility.cpp:546
pthread_t thread_id
Definition Utility.h:190
bool thread_spawn(THREAD_START_ROUTINE func, void *var, thread_id &thread)
Definition Utility.cpp:416
const char * socket_hostname(int socket)
Definition Utility.cpp:314
tm time_localtime(const time_t *t)
Definition Utility.cpp:400
thread_id thread_self()
Definition Utility.cpp:457
bool socket_disconnected(int s)
Definition Utility.cpp:202
void socket_invalidate(int &socket)
Definition Utility.cpp:295
ssize_t socket_recv(int s, char *buf, size_t length)
Definition Utility.cpp:170
short socket_hostport(int socket)
Definition Utility.cpp:304
void *() THREAD_START_ROUTINE(void *)
Definition Utility.h:183
tm time_gmtime(const time_t *t)
Definition Utility.cpp:384
void socket_close(int s)
Definition Utility.cpp:180
void process_sleep(double s)
Definition Utility.cpp:466
void file_mkdir(const char *path)
Definition Utility.cpp:489
std::pair< int, int > socket_createpair()
Definition Utility.cpp:366
void string_replace(const std::string &oldValue, const std::string &newValue, std::string &value)
Definition Utility.cpp:40
std::string string_toLower(const std::string &value)
Definition Utility.cpp:60
void thread_join(thread_id thread)
Definition Utility.cpp:437
int socket_getsockopt(int s, int opt, int &optval)
Definition Utility.cpp:233
int socket_connect(int socket, const char *address, int port)
Definition Utility.cpp:148
int socket_bind(int socket, const char *hostname, int port)
Definition Utility.cpp:103
std::string file_separator()
Definition Utility.cpp:480
void socket_init()
Definition Utility.cpp:81
std::string string_toUpper(const std::string &value)
Definition Utility.cpp:53
ssize_t socket_send(int s, const char *msg, size_t length)
Definition Utility.cpp:175
bool file_exists(const char *path)
Definition Utility.cpp:525
void socket_term()
Definition Utility.cpp:96
bool socket_isValid(int socket)
Definition Utility.cpp:277
int socket_createAcceptor(int port, bool reuse)
Definition Utility.cpp:120
void file_fclose(FILE *file)
Definition Utility.cpp:520
int socket_fcntl(int s, int opt, int arg)
Definition Utility.cpp:250
FILE * file_fopen(const char *path, const char *mode)
Definition Utility.cpp:509
std::string file_appendpath(const std::string &path, const std::string &file)
Definition Utility.cpp:551
const char * socket_peername(int socket)
Definition Utility.cpp:353

Generated on Fri Sep 27 2024 13:45:21 for QuickFIX by doxygen 1.9.8 written by Dimitri van Heesch, © 1997-2001