quickfix_ruby 1.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/quickfix/Acceptor.cpp +248 -0
- data/ext/quickfix/Acceptor.h +127 -0
- data/ext/quickfix/Allocator.h +9 -0
- data/ext/quickfix/Application.h +127 -0
- data/ext/quickfix/AtomicCount.h +109 -0
- data/ext/quickfix/DOMDocument.h +74 -0
- data/ext/quickfix/DataDictionary.cpp +618 -0
- data/ext/quickfix/DataDictionary.h +539 -0
- data/ext/quickfix/DataDictionaryProvider.cpp +71 -0
- data/ext/quickfix/DataDictionaryProvider.h +70 -0
- data/ext/quickfix/DatabaseConnectionID.h +105 -0
- data/ext/quickfix/DatabaseConnectionPool.h +91 -0
- data/ext/quickfix/Dictionary.cpp +162 -0
- data/ext/quickfix/Dictionary.h +94 -0
- data/ext/quickfix/Event.h +95 -0
- data/ext/quickfix/Exceptions.h +299 -0
- data/ext/quickfix/Field.h +672 -0
- data/ext/quickfix/FieldConvertors.h +863 -0
- data/ext/quickfix/FieldMap.cpp +238 -0
- data/ext/quickfix/FieldMap.h +244 -0
- data/ext/quickfix/FieldNumbers.h +46 -0
- data/ext/quickfix/FieldTypes.cpp +64 -0
- data/ext/quickfix/FieldTypes.h +698 -0
- data/ext/quickfix/Fields.h +31 -0
- data/ext/quickfix/FileLog.cpp +200 -0
- data/ext/quickfix/FileLog.h +112 -0
- data/ext/quickfix/FileStore.cpp +332 -0
- data/ext/quickfix/FileStore.h +129 -0
- data/ext/quickfix/FixFieldNumbers.h +1537 -0
- data/ext/quickfix/FixFields.h +1538 -0
- data/ext/quickfix/FixValues.h +3281 -0
- data/ext/quickfix/FlexLexer.h +188 -0
- data/ext/quickfix/Group.cpp +64 -0
- data/ext/quickfix/Group.h +73 -0
- data/ext/quickfix/HtmlBuilder.h +186 -0
- data/ext/quickfix/HttpConnection.cpp +739 -0
- data/ext/quickfix/HttpConnection.h +78 -0
- data/ext/quickfix/HttpMessage.cpp +149 -0
- data/ext/quickfix/HttpMessage.h +133 -0
- data/ext/quickfix/HttpParser.cpp +49 -0
- data/ext/quickfix/HttpParser.h +54 -0
- data/ext/quickfix/HttpServer.cpp +169 -0
- data/ext/quickfix/HttpServer.h +78 -0
- data/ext/quickfix/Initiator.cpp +289 -0
- data/ext/quickfix/Initiator.h +149 -0
- data/ext/quickfix/Log.cpp +77 -0
- data/ext/quickfix/Log.h +179 -0
- data/ext/quickfix/Message.cpp +580 -0
- data/ext/quickfix/Message.h +370 -0
- data/ext/quickfix/MessageCracker.h +188 -0
- data/ext/quickfix/MessageSorters.cpp +105 -0
- data/ext/quickfix/MessageSorters.h +156 -0
- data/ext/quickfix/MessageStore.cpp +146 -0
- data/ext/quickfix/MessageStore.h +174 -0
- data/ext/quickfix/Mutex.h +131 -0
- data/ext/quickfix/MySQLConnection.h +194 -0
- data/ext/quickfix/MySQLLog.cpp +275 -0
- data/ext/quickfix/MySQLLog.h +145 -0
- data/ext/quickfix/MySQLStore.cpp +331 -0
- data/ext/quickfix/MySQLStore.h +142 -0
- data/ext/quickfix/NullStore.cpp +54 -0
- data/ext/quickfix/NullStore.h +99 -0
- data/ext/quickfix/OdbcConnection.h +266 -0
- data/ext/quickfix/OdbcLog.cpp +252 -0
- data/ext/quickfix/OdbcLog.h +117 -0
- data/ext/quickfix/OdbcStore.cpp +338 -0
- data/ext/quickfix/OdbcStore.h +113 -0
- data/ext/quickfix/PUGIXML_DOMDocument.cpp +112 -0
- data/ext/quickfix/PUGIXML_DOMDocument.h +81 -0
- data/ext/quickfix/Parser.cpp +103 -0
- data/ext/quickfix/Parser.h +57 -0
- data/ext/quickfix/PostgreSQLConnection.h +176 -0
- data/ext/quickfix/PostgreSQLLog.cpp +276 -0
- data/ext/quickfix/PostgreSQLLog.h +144 -0
- data/ext/quickfix/PostgreSQLStore.cpp +334 -0
- data/ext/quickfix/PostgreSQLStore.h +141 -0
- data/ext/quickfix/Queue.h +75 -0
- data/ext/quickfix/QuickfixRuby.cpp +252066 -0
- data/ext/quickfix/QuickfixRuby.h +34 -0
- data/ext/quickfix/Responder.h +43 -0
- data/ext/quickfix/Session.cpp +1487 -0
- data/ext/quickfix/Session.h +335 -0
- data/ext/quickfix/SessionFactory.cpp +274 -0
- data/ext/quickfix/SessionFactory.h +86 -0
- data/ext/quickfix/SessionID.h +170 -0
- data/ext/quickfix/SessionSettings.cpp +189 -0
- data/ext/quickfix/SessionSettings.h +171 -0
- data/ext/quickfix/SessionState.h +231 -0
- data/ext/quickfix/Settings.cpp +100 -0
- data/ext/quickfix/Settings.h +53 -0
- data/ext/quickfix/SharedArray.h +150 -0
- data/ext/quickfix/SocketAcceptor.cpp +222 -0
- data/ext/quickfix/SocketAcceptor.h +75 -0
- data/ext/quickfix/SocketConnection.cpp +238 -0
- data/ext/quickfix/SocketConnection.h +103 -0
- data/ext/quickfix/SocketConnector.cpp +116 -0
- data/ext/quickfix/SocketConnector.h +67 -0
- data/ext/quickfix/SocketInitiator.cpp +260 -0
- data/ext/quickfix/SocketInitiator.h +81 -0
- data/ext/quickfix/SocketMonitor.cpp +335 -0
- data/ext/quickfix/SocketMonitor.h +111 -0
- data/ext/quickfix/SocketServer.cpp +177 -0
- data/ext/quickfix/SocketServer.h +100 -0
- data/ext/quickfix/ThreadedSocketAcceptor.cpp +258 -0
- data/ext/quickfix/ThreadedSocketAcceptor.h +98 -0
- data/ext/quickfix/ThreadedSocketConnection.cpp +209 -0
- data/ext/quickfix/ThreadedSocketConnection.h +82 -0
- data/ext/quickfix/ThreadedSocketInitiator.cpp +268 -0
- data/ext/quickfix/ThreadedSocketInitiator.h +84 -0
- data/ext/quickfix/TimeRange.cpp +173 -0
- data/ext/quickfix/TimeRange.h +258 -0
- data/ext/quickfix/Utility.cpp +537 -0
- data/ext/quickfix/Utility.h +219 -0
- data/ext/quickfix/Values.h +62 -0
- data/ext/quickfix/config.h +0 -0
- data/ext/quickfix/config_windows.h +0 -0
- data/ext/quickfix/extconf.rb +12 -0
- data/ext/quickfix/index.h +37 -0
- data/ext/quickfix/pugiconfig.hpp +72 -0
- data/ext/quickfix/pugixml.cpp +10765 -0
- data/ext/quickfix/pugixml.hpp +1341 -0
- data/ext/quickfix/strptime.h +7 -0
- data/lib/quickfix40.rb +274 -0
- data/lib/quickfix41.rb +351 -0
- data/lib/quickfix42.rb +1184 -0
- data/lib/quickfix43.rb +3504 -0
- data/lib/quickfix44.rb +10721 -0
- data/lib/quickfix50.rb +13426 -0
- data/lib/quickfix50sp1.rb +15629 -0
- data/lib/quickfix50sp2.rb +17068 -0
- data/lib/quickfix_fields.rb +19853 -0
- data/lib/quickfix_ruby.rb +82 -0
- data/lib/quickfixt11.rb +70 -0
- data/spec/FIX40.xml +862 -0
- data/spec/FIX41.xml +1285 -0
- data/spec/FIX42.xml +2746 -0
- data/spec/FIX43.xml +4229 -0
- data/spec/FIX44.xml +6596 -0
- data/spec/FIX50.xml +8137 -0
- data/spec/FIX50SP1.xml +9496 -0
- data/spec/FIX50SP2.xml +10011 -0
- data/spec/FIXT11.xml +313 -0
- data/test/test_DataDictionaryTestCase.rb +268 -0
- data/test/test_DictionaryTestCase.rb +112 -0
- data/test/test_FieldBaseTestCase.rb +24 -0
- data/test/test_MessageTestCase.rb +368 -0
- data/test/test_SessionSettingsTestCase.rb +41 -0
- metadata +193 -0
|
@@ -0,0 +1,222 @@
|
|
|
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 "SocketAcceptor.h"
|
|
27
|
+
#include "Session.h"
|
|
28
|
+
#include "Settings.h"
|
|
29
|
+
#include "Utility.h"
|
|
30
|
+
#include "Exceptions.h"
|
|
31
|
+
|
|
32
|
+
namespace FIX
|
|
33
|
+
{
|
|
34
|
+
SocketAcceptor::SocketAcceptor( Application& application,
|
|
35
|
+
MessageStoreFactory& factory,
|
|
36
|
+
const SessionSettings& settings ) throw( ConfigError )
|
|
37
|
+
: Acceptor( application, factory, settings ),
|
|
38
|
+
m_pServer( 0 ) {}
|
|
39
|
+
|
|
40
|
+
SocketAcceptor::SocketAcceptor( Application& application,
|
|
41
|
+
MessageStoreFactory& factory,
|
|
42
|
+
const SessionSettings& settings,
|
|
43
|
+
LogFactory& logFactory ) throw( ConfigError )
|
|
44
|
+
: Acceptor( application, factory, settings, logFactory ),
|
|
45
|
+
m_pServer( 0 )
|
|
46
|
+
{
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
SocketAcceptor::~SocketAcceptor()
|
|
50
|
+
{
|
|
51
|
+
SocketConnections::iterator iter;
|
|
52
|
+
for ( iter = m_connections.begin(); iter != m_connections.end(); ++iter )
|
|
53
|
+
delete iter->second;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void SocketAcceptor::onConfigure( const SessionSettings& s )
|
|
57
|
+
throw ( ConfigError )
|
|
58
|
+
{
|
|
59
|
+
std::set<SessionID> sessions = s.getSessions();
|
|
60
|
+
std::set<SessionID>::iterator i;
|
|
61
|
+
for( i = sessions.begin(); i != sessions.end(); ++i )
|
|
62
|
+
{
|
|
63
|
+
const Dictionary& settings = s.get( *i );
|
|
64
|
+
settings.getInt( SOCKET_ACCEPT_PORT );
|
|
65
|
+
if( settings.has(SOCKET_REUSE_ADDRESS) )
|
|
66
|
+
settings.getBool( SOCKET_REUSE_ADDRESS );
|
|
67
|
+
if( settings.has(SOCKET_NODELAY) )
|
|
68
|
+
settings.getBool( SOCKET_NODELAY );
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
void SocketAcceptor::onInitialize( const SessionSettings& s )
|
|
73
|
+
throw ( RuntimeError )
|
|
74
|
+
{
|
|
75
|
+
short port = 0;
|
|
76
|
+
|
|
77
|
+
try
|
|
78
|
+
{
|
|
79
|
+
m_pServer = new SocketServer( 1 );
|
|
80
|
+
|
|
81
|
+
std::set<SessionID> sessions = s.getSessions();
|
|
82
|
+
std::set<SessionID>::iterator i = sessions.begin();
|
|
83
|
+
for( ; i != sessions.end(); ++i )
|
|
84
|
+
{
|
|
85
|
+
const Dictionary& settings = s.get( *i );
|
|
86
|
+
port = (short)settings.getInt( SOCKET_ACCEPT_PORT );
|
|
87
|
+
|
|
88
|
+
const bool reuseAddress = settings.has( SOCKET_REUSE_ADDRESS ) ?
|
|
89
|
+
settings.getBool( SOCKET_REUSE_ADDRESS ) : true;
|
|
90
|
+
|
|
91
|
+
const bool noDelay = settings.has( SOCKET_NODELAY ) ?
|
|
92
|
+
settings.getBool( SOCKET_NODELAY ) : false;
|
|
93
|
+
|
|
94
|
+
const int sendBufSize = settings.has( SOCKET_SEND_BUFFER_SIZE ) ?
|
|
95
|
+
settings.getInt( SOCKET_SEND_BUFFER_SIZE ) : 0;
|
|
96
|
+
|
|
97
|
+
const int rcvBufSize = settings.has( SOCKET_RECEIVE_BUFFER_SIZE ) ?
|
|
98
|
+
settings.getInt( SOCKET_RECEIVE_BUFFER_SIZE ) : 0;
|
|
99
|
+
|
|
100
|
+
m_portToSessions[port].insert( *i );
|
|
101
|
+
m_pServer->add( port, reuseAddress, noDelay, sendBufSize, rcvBufSize );
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch( SocketException& e )
|
|
105
|
+
{
|
|
106
|
+
throw RuntimeError( "Unable to create, bind, or listen to port "
|
|
107
|
+
+ IntConvertor::convert( (unsigned short)port ) + " (" + e.what() + ")" );
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
void SocketAcceptor::onStart()
|
|
112
|
+
{
|
|
113
|
+
while ( !isStopped() && m_pServer && m_pServer->block( *this ) ) {}
|
|
114
|
+
|
|
115
|
+
if( !m_pServer )
|
|
116
|
+
return;
|
|
117
|
+
|
|
118
|
+
time_t start = 0;
|
|
119
|
+
time_t now = 0;
|
|
120
|
+
|
|
121
|
+
::time( &start );
|
|
122
|
+
while ( isLoggedOn() )
|
|
123
|
+
{
|
|
124
|
+
m_pServer->block( *this );
|
|
125
|
+
if( ::time(&now) -5 >= start )
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
m_pServer->close();
|
|
130
|
+
delete m_pServer;
|
|
131
|
+
m_pServer = 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
bool SocketAcceptor::onPoll( double timeout )
|
|
135
|
+
{
|
|
136
|
+
if( !m_pServer )
|
|
137
|
+
return false;
|
|
138
|
+
|
|
139
|
+
time_t start = 0;
|
|
140
|
+
time_t now = 0;
|
|
141
|
+
|
|
142
|
+
if( isStopped() )
|
|
143
|
+
{
|
|
144
|
+
if( start == 0 )
|
|
145
|
+
::time( &start );
|
|
146
|
+
if( !isLoggedOn() )
|
|
147
|
+
{
|
|
148
|
+
start = 0;
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
if( ::time(&now) - 5 >= start )
|
|
152
|
+
{
|
|
153
|
+
start = 0;
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
m_pServer->block( *this, true, timeout );
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
void SocketAcceptor::onStop()
|
|
163
|
+
{
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
void SocketAcceptor::onConnect( SocketServer& server, int a, int s )
|
|
167
|
+
{
|
|
168
|
+
if ( !socket_isValid( s ) ) return;
|
|
169
|
+
SocketConnections::iterator i = m_connections.find( s );
|
|
170
|
+
if ( i != m_connections.end() ) return;
|
|
171
|
+
int port = server.socketToPort( a );
|
|
172
|
+
Sessions sessions = m_portToSessions[port];
|
|
173
|
+
m_connections[ s ] = new SocketConnection( s, sessions, &server.getMonitor() );
|
|
174
|
+
|
|
175
|
+
std::stringstream stream;
|
|
176
|
+
stream << "Accepted connection from " << socket_peername( s ) << " on port " << port;
|
|
177
|
+
|
|
178
|
+
if( getLog() )
|
|
179
|
+
getLog()->onEvent( stream.str() );
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
void SocketAcceptor::onWrite( SocketServer& server, int s )
|
|
183
|
+
{
|
|
184
|
+
SocketConnections::iterator i = m_connections.find( s );
|
|
185
|
+
if ( i == m_connections.end() ) return ;
|
|
186
|
+
SocketConnection* pSocketConnection = i->second;
|
|
187
|
+
if( pSocketConnection->processQueue() )
|
|
188
|
+
pSocketConnection->unsignal();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
bool SocketAcceptor::onData( SocketServer& server, int s )
|
|
192
|
+
{
|
|
193
|
+
SocketConnections::iterator i = m_connections.find( s );
|
|
194
|
+
if ( i == m_connections.end() ) return false;
|
|
195
|
+
SocketConnection* pSocketConnection = i->second;
|
|
196
|
+
return pSocketConnection->read( *this, server );
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
void SocketAcceptor::onDisconnect( SocketServer&, int s )
|
|
200
|
+
{
|
|
201
|
+
SocketConnections::iterator i = m_connections.find( s );
|
|
202
|
+
if ( i == m_connections.end() ) return ;
|
|
203
|
+
SocketConnection* pSocketConnection = i->second;
|
|
204
|
+
|
|
205
|
+
Session* pSession = pSocketConnection->getSession();
|
|
206
|
+
if ( pSession ) pSession->disconnect();
|
|
207
|
+
|
|
208
|
+
delete pSocketConnection;
|
|
209
|
+
m_connections.erase( s );
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
void SocketAcceptor::onError( SocketServer& )
|
|
213
|
+
{
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
void SocketAcceptor::onTimeout( SocketServer& )
|
|
217
|
+
{
|
|
218
|
+
SocketConnections::iterator i;
|
|
219
|
+
for ( i = m_connections.begin(); i != m_connections.end(); ++i )
|
|
220
|
+
i->second->onTimeout();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/* -*- C++ -*- */
|
|
2
|
+
|
|
3
|
+
/****************************************************************************
|
|
4
|
+
** Copyright (c) 2001-2014
|
|
5
|
+
**
|
|
6
|
+
** This file is part of the QuickFIX FIX Engine
|
|
7
|
+
**
|
|
8
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
9
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
10
|
+
** LICENSE included in the packaging of this file.
|
|
11
|
+
**
|
|
12
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
13
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
14
|
+
**
|
|
15
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
16
|
+
**
|
|
17
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
18
|
+
** not clear to you.
|
|
19
|
+
**
|
|
20
|
+
****************************************************************************/
|
|
21
|
+
|
|
22
|
+
#ifndef FIX_SOCKETACCEPTOR_H
|
|
23
|
+
#define FIX_SOCKETACCEPTOR_H
|
|
24
|
+
|
|
25
|
+
#ifdef _MSC_VER
|
|
26
|
+
#pragma warning( disable : 4503 4355 4786 4290 )
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#include "Acceptor.h"
|
|
30
|
+
#include "SocketServer.h"
|
|
31
|
+
#include "SocketConnection.h"
|
|
32
|
+
|
|
33
|
+
namespace FIX
|
|
34
|
+
{
|
|
35
|
+
/// Socket implementation of Acceptor.
|
|
36
|
+
class SocketAcceptor : public Acceptor, SocketServer::Strategy
|
|
37
|
+
{
|
|
38
|
+
friend class SocketConnection;
|
|
39
|
+
public:
|
|
40
|
+
SocketAcceptor( Application&, MessageStoreFactory&,
|
|
41
|
+
const SessionSettings& ) throw( ConfigError );
|
|
42
|
+
SocketAcceptor( Application&, MessageStoreFactory&,
|
|
43
|
+
const SessionSettings&, LogFactory& ) throw( ConfigError );
|
|
44
|
+
|
|
45
|
+
virtual ~SocketAcceptor();
|
|
46
|
+
|
|
47
|
+
private:
|
|
48
|
+
bool readSettings( const SessionSettings& );
|
|
49
|
+
|
|
50
|
+
typedef std::set < SessionID > Sessions;
|
|
51
|
+
typedef std::map < int, Sessions > PortToSessions;
|
|
52
|
+
typedef std::map < int, SocketConnection* > SocketConnections;
|
|
53
|
+
|
|
54
|
+
void onConfigure( const SessionSettings& ) throw ( ConfigError );
|
|
55
|
+
void onInitialize( const SessionSettings& ) throw ( RuntimeError );
|
|
56
|
+
|
|
57
|
+
void onStart();
|
|
58
|
+
bool onPoll( double timeout );
|
|
59
|
+
void onStop();
|
|
60
|
+
|
|
61
|
+
void onConnect( SocketServer&, int, int );
|
|
62
|
+
void onWrite( SocketServer&, int );
|
|
63
|
+
bool onData( SocketServer&, int );
|
|
64
|
+
void onDisconnect( SocketServer&, int );
|
|
65
|
+
void onError( SocketServer& );
|
|
66
|
+
void onTimeout( SocketServer& );
|
|
67
|
+
|
|
68
|
+
SocketServer* m_pServer;
|
|
69
|
+
PortToSessions m_portToSessions;
|
|
70
|
+
SocketConnections m_connections;
|
|
71
|
+
};
|
|
72
|
+
/*! @} */
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
#endif //FIX_SOCKETACCEPTOR_H
|
|
@@ -0,0 +1,238 @@
|
|
|
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 "SocketConnection.h"
|
|
27
|
+
#include "SocketAcceptor.h"
|
|
28
|
+
#include "SocketConnector.h"
|
|
29
|
+
#include "SocketInitiator.h"
|
|
30
|
+
#include "Session.h"
|
|
31
|
+
#include "Utility.h"
|
|
32
|
+
|
|
33
|
+
namespace FIX
|
|
34
|
+
{
|
|
35
|
+
SocketConnection::SocketConnection( int s, Sessions sessions,
|
|
36
|
+
SocketMonitor* pMonitor )
|
|
37
|
+
: m_socket( s ), m_sendLength( 0 ),
|
|
38
|
+
m_sessions(sessions), m_pSession( 0 ), m_pMonitor( pMonitor )
|
|
39
|
+
{
|
|
40
|
+
FD_ZERO( &m_fds );
|
|
41
|
+
FD_SET( m_socket, &m_fds );
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
SocketConnection::SocketConnection( SocketInitiator& i,
|
|
45
|
+
const SessionID& sessionID, int s,
|
|
46
|
+
SocketMonitor* pMonitor )
|
|
47
|
+
: m_socket( s ), m_sendLength( 0 ),
|
|
48
|
+
m_pSession( i.getSession( sessionID, *this ) ),
|
|
49
|
+
m_pMonitor( pMonitor )
|
|
50
|
+
{
|
|
51
|
+
FD_ZERO( &m_fds );
|
|
52
|
+
FD_SET( m_socket, &m_fds );
|
|
53
|
+
m_sessions.insert( sessionID );
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
SocketConnection::~SocketConnection()
|
|
57
|
+
{
|
|
58
|
+
if ( m_pSession )
|
|
59
|
+
Session::unregisterSession( m_pSession->getSessionID() );
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
bool SocketConnection::send( const std::string& msg )
|
|
63
|
+
{
|
|
64
|
+
Locker l( m_mutex );
|
|
65
|
+
|
|
66
|
+
m_sendQueue.push_back( msg );
|
|
67
|
+
processQueue();
|
|
68
|
+
signal();
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
bool SocketConnection::processQueue()
|
|
73
|
+
{
|
|
74
|
+
Locker l( m_mutex );
|
|
75
|
+
|
|
76
|
+
if( !m_sendQueue.size() ) return true;
|
|
77
|
+
|
|
78
|
+
struct timeval timeout = { 0, 0 };
|
|
79
|
+
fd_set writeset = m_fds;
|
|
80
|
+
if( select( 1 + m_socket, 0, &writeset, 0, &timeout ) <= 0 )
|
|
81
|
+
return false;
|
|
82
|
+
|
|
83
|
+
const std::string& msg = m_sendQueue.front();
|
|
84
|
+
|
|
85
|
+
size_t result = socket_send
|
|
86
|
+
( m_socket, msg.c_str() + m_sendLength, msg.length() - m_sendLength );
|
|
87
|
+
|
|
88
|
+
if( result > 0 )
|
|
89
|
+
m_sendLength += result;
|
|
90
|
+
|
|
91
|
+
if( m_sendLength == msg.length() )
|
|
92
|
+
{
|
|
93
|
+
m_sendLength = 0;
|
|
94
|
+
m_sendQueue.pop_front();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return !m_sendQueue.size();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
void SocketConnection::disconnect()
|
|
101
|
+
{
|
|
102
|
+
if ( m_pMonitor )
|
|
103
|
+
m_pMonitor->drop( m_socket );
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
bool SocketConnection::read( SocketConnector& s )
|
|
107
|
+
{
|
|
108
|
+
if ( !m_pSession ) return false;
|
|
109
|
+
|
|
110
|
+
try
|
|
111
|
+
{
|
|
112
|
+
readFromSocket();
|
|
113
|
+
readMessages( s.getMonitor() );
|
|
114
|
+
}
|
|
115
|
+
catch( SocketRecvFailed& e )
|
|
116
|
+
{
|
|
117
|
+
m_pSession->getLog()->onEvent( e.what() );
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
bool SocketConnection::read( SocketAcceptor& a, SocketServer& s )
|
|
124
|
+
{
|
|
125
|
+
std::string msg;
|
|
126
|
+
try
|
|
127
|
+
{
|
|
128
|
+
if ( !m_pSession )
|
|
129
|
+
{
|
|
130
|
+
struct timeval timeout = { 1, 0 };
|
|
131
|
+
fd_set readset = m_fds;
|
|
132
|
+
|
|
133
|
+
while( !readMessage( msg ) )
|
|
134
|
+
{
|
|
135
|
+
int result = select( 1 + m_socket, &readset, 0, 0, &timeout );
|
|
136
|
+
if( result > 0 )
|
|
137
|
+
readFromSocket();
|
|
138
|
+
else if( result == 0 )
|
|
139
|
+
return false;
|
|
140
|
+
else if( result < 0 )
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
m_pSession = Session::lookupSession( msg, true );
|
|
145
|
+
if( !isValidSession() )
|
|
146
|
+
{
|
|
147
|
+
m_pSession = 0;
|
|
148
|
+
if( a.getLog() )
|
|
149
|
+
{
|
|
150
|
+
a.getLog()->onEvent( "Session not found for incoming message: " + msg );
|
|
151
|
+
a.getLog()->onIncoming( msg );
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if( m_pSession )
|
|
155
|
+
m_pSession = a.getSession( msg, *this );
|
|
156
|
+
if( m_pSession )
|
|
157
|
+
m_pSession->next( msg, UtcTimeStamp() );
|
|
158
|
+
if( !m_pSession )
|
|
159
|
+
{
|
|
160
|
+
s.getMonitor().drop( m_socket );
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
Session::registerSession( m_pSession->getSessionID() );
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
else
|
|
168
|
+
{
|
|
169
|
+
readFromSocket();
|
|
170
|
+
readMessages( s.getMonitor() );
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch ( SocketRecvFailed& e )
|
|
175
|
+
{
|
|
176
|
+
if( m_pSession )
|
|
177
|
+
m_pSession->getLog()->onEvent( e.what() );
|
|
178
|
+
s.getMonitor().drop( m_socket );
|
|
179
|
+
}
|
|
180
|
+
catch ( InvalidMessage& )
|
|
181
|
+
{
|
|
182
|
+
s.getMonitor().drop( m_socket );
|
|
183
|
+
}
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
bool SocketConnection::isValidSession()
|
|
188
|
+
{
|
|
189
|
+
if( m_pSession == 0 )
|
|
190
|
+
return false;
|
|
191
|
+
SessionID sessionID = m_pSession->getSessionID();
|
|
192
|
+
if( Session::isSessionRegistered(sessionID) )
|
|
193
|
+
return false;
|
|
194
|
+
return !( m_sessions.find(sessionID) == m_sessions.end() );
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
void SocketConnection::readFromSocket()
|
|
198
|
+
throw( SocketRecvFailed )
|
|
199
|
+
{
|
|
200
|
+
ssize_t size = recv( m_socket, m_buffer, sizeof(m_buffer), 0 );
|
|
201
|
+
if( size <= 0 ) throw SocketRecvFailed( size );
|
|
202
|
+
m_parser.addToStream( m_buffer, size );
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
bool SocketConnection::readMessage( std::string& msg )
|
|
206
|
+
{
|
|
207
|
+
try
|
|
208
|
+
{
|
|
209
|
+
return m_parser.readFixMessage( msg );
|
|
210
|
+
}
|
|
211
|
+
catch ( MessageParseError& ) {}
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
void SocketConnection::readMessages( SocketMonitor& s )
|
|
216
|
+
{
|
|
217
|
+
if( !m_pSession ) return;
|
|
218
|
+
|
|
219
|
+
std::string msg;
|
|
220
|
+
while( readMessage( msg ) )
|
|
221
|
+
{
|
|
222
|
+
try
|
|
223
|
+
{
|
|
224
|
+
m_pSession->next( msg, UtcTimeStamp() );
|
|
225
|
+
}
|
|
226
|
+
catch ( InvalidMessage& )
|
|
227
|
+
{
|
|
228
|
+
if( !m_pSession->isLoggedOn() )
|
|
229
|
+
s.drop( m_socket );
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
void SocketConnection::onTimeout()
|
|
235
|
+
{
|
|
236
|
+
if ( m_pSession ) m_pSession->next();
|
|
237
|
+
}
|
|
238
|
+
} // namespace FIX
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/* -*- C++ -*- */
|
|
2
|
+
|
|
3
|
+
/****************************************************************************
|
|
4
|
+
** Copyright (c) 2001-2014
|
|
5
|
+
**
|
|
6
|
+
** This file is part of the QuickFIX FIX Engine
|
|
7
|
+
**
|
|
8
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
9
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
10
|
+
** LICENSE included in the packaging of this file.
|
|
11
|
+
**
|
|
12
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
13
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
14
|
+
**
|
|
15
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
16
|
+
**
|
|
17
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
18
|
+
** not clear to you.
|
|
19
|
+
**
|
|
20
|
+
****************************************************************************/
|
|
21
|
+
|
|
22
|
+
#ifndef FIX_SOCKETCONNECTION_H
|
|
23
|
+
#define FIX_SOCKETCONNECTION_H
|
|
24
|
+
|
|
25
|
+
#ifdef _MSC_VER
|
|
26
|
+
#pragma warning( disable : 4503 4355 4786 4290 )
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#include "Parser.h"
|
|
30
|
+
#include "Responder.h"
|
|
31
|
+
#include "SessionID.h"
|
|
32
|
+
#include "SocketMonitor.h"
|
|
33
|
+
#include "Utility.h"
|
|
34
|
+
#include "Mutex.h"
|
|
35
|
+
#include <set>
|
|
36
|
+
|
|
37
|
+
namespace FIX
|
|
38
|
+
{
|
|
39
|
+
class SocketAcceptor;
|
|
40
|
+
class SocketServer;
|
|
41
|
+
class SocketConnector;
|
|
42
|
+
class SocketInitiator;
|
|
43
|
+
class Session;
|
|
44
|
+
|
|
45
|
+
/// Encapsulates a socket file descriptor (single-threaded).
|
|
46
|
+
class SocketConnection : Responder
|
|
47
|
+
{
|
|
48
|
+
public:
|
|
49
|
+
typedef std::set<SessionID> Sessions;
|
|
50
|
+
|
|
51
|
+
SocketConnection( int s, Sessions sessions, SocketMonitor* pMonitor );
|
|
52
|
+
SocketConnection( SocketInitiator&, const SessionID&, int, SocketMonitor* );
|
|
53
|
+
virtual ~SocketConnection();
|
|
54
|
+
|
|
55
|
+
int getSocket() const { return m_socket; }
|
|
56
|
+
Session* getSession() const { return m_pSession; }
|
|
57
|
+
|
|
58
|
+
bool read( SocketConnector& s );
|
|
59
|
+
bool read( SocketAcceptor&, SocketServer& );
|
|
60
|
+
bool processQueue();
|
|
61
|
+
|
|
62
|
+
void signal()
|
|
63
|
+
{
|
|
64
|
+
Locker l( m_mutex );
|
|
65
|
+
if( m_sendQueue.size() == 1 )
|
|
66
|
+
m_pMonitor->signal( m_socket );
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
void unsignal()
|
|
70
|
+
{
|
|
71
|
+
Locker l( m_mutex );
|
|
72
|
+
if( m_sendQueue.size() == 0 )
|
|
73
|
+
m_pMonitor->unsignal( m_socket );
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void onTimeout();
|
|
77
|
+
|
|
78
|
+
private:
|
|
79
|
+
typedef std::deque<std::string, ALLOCATOR<std::string> >
|
|
80
|
+
Queue;
|
|
81
|
+
|
|
82
|
+
bool isValidSession();
|
|
83
|
+
void readFromSocket() throw( SocketRecvFailed );
|
|
84
|
+
bool readMessage( std::string& msg );
|
|
85
|
+
void readMessages( SocketMonitor& s );
|
|
86
|
+
bool send( const std::string& );
|
|
87
|
+
void disconnect();
|
|
88
|
+
|
|
89
|
+
int m_socket;
|
|
90
|
+
char m_buffer[BUFSIZ];
|
|
91
|
+
|
|
92
|
+
Parser m_parser;
|
|
93
|
+
Queue m_sendQueue;
|
|
94
|
+
unsigned m_sendLength;
|
|
95
|
+
Sessions m_sessions;
|
|
96
|
+
Session* m_pSession;
|
|
97
|
+
SocketMonitor* m_pMonitor;
|
|
98
|
+
Mutex m_mutex;
|
|
99
|
+
fd_set m_fds;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
#endif //FIX_SOCKETCONNECTION_H
|