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.
Files changed (149) hide show
  1. checksums.yaml +7 -0
  2. data/ext/quickfix/Acceptor.cpp +248 -0
  3. data/ext/quickfix/Acceptor.h +127 -0
  4. data/ext/quickfix/Allocator.h +9 -0
  5. data/ext/quickfix/Application.h +127 -0
  6. data/ext/quickfix/AtomicCount.h +109 -0
  7. data/ext/quickfix/DOMDocument.h +74 -0
  8. data/ext/quickfix/DataDictionary.cpp +618 -0
  9. data/ext/quickfix/DataDictionary.h +539 -0
  10. data/ext/quickfix/DataDictionaryProvider.cpp +71 -0
  11. data/ext/quickfix/DataDictionaryProvider.h +70 -0
  12. data/ext/quickfix/DatabaseConnectionID.h +105 -0
  13. data/ext/quickfix/DatabaseConnectionPool.h +91 -0
  14. data/ext/quickfix/Dictionary.cpp +162 -0
  15. data/ext/quickfix/Dictionary.h +94 -0
  16. data/ext/quickfix/Event.h +95 -0
  17. data/ext/quickfix/Exceptions.h +299 -0
  18. data/ext/quickfix/Field.h +672 -0
  19. data/ext/quickfix/FieldConvertors.h +863 -0
  20. data/ext/quickfix/FieldMap.cpp +238 -0
  21. data/ext/quickfix/FieldMap.h +244 -0
  22. data/ext/quickfix/FieldNumbers.h +46 -0
  23. data/ext/quickfix/FieldTypes.cpp +64 -0
  24. data/ext/quickfix/FieldTypes.h +698 -0
  25. data/ext/quickfix/Fields.h +31 -0
  26. data/ext/quickfix/FileLog.cpp +200 -0
  27. data/ext/quickfix/FileLog.h +112 -0
  28. data/ext/quickfix/FileStore.cpp +332 -0
  29. data/ext/quickfix/FileStore.h +129 -0
  30. data/ext/quickfix/FixFieldNumbers.h +1537 -0
  31. data/ext/quickfix/FixFields.h +1538 -0
  32. data/ext/quickfix/FixValues.h +3281 -0
  33. data/ext/quickfix/FlexLexer.h +188 -0
  34. data/ext/quickfix/Group.cpp +64 -0
  35. data/ext/quickfix/Group.h +73 -0
  36. data/ext/quickfix/HtmlBuilder.h +186 -0
  37. data/ext/quickfix/HttpConnection.cpp +739 -0
  38. data/ext/quickfix/HttpConnection.h +78 -0
  39. data/ext/quickfix/HttpMessage.cpp +149 -0
  40. data/ext/quickfix/HttpMessage.h +133 -0
  41. data/ext/quickfix/HttpParser.cpp +49 -0
  42. data/ext/quickfix/HttpParser.h +54 -0
  43. data/ext/quickfix/HttpServer.cpp +169 -0
  44. data/ext/quickfix/HttpServer.h +78 -0
  45. data/ext/quickfix/Initiator.cpp +289 -0
  46. data/ext/quickfix/Initiator.h +149 -0
  47. data/ext/quickfix/Log.cpp +77 -0
  48. data/ext/quickfix/Log.h +179 -0
  49. data/ext/quickfix/Message.cpp +580 -0
  50. data/ext/quickfix/Message.h +370 -0
  51. data/ext/quickfix/MessageCracker.h +188 -0
  52. data/ext/quickfix/MessageSorters.cpp +105 -0
  53. data/ext/quickfix/MessageSorters.h +156 -0
  54. data/ext/quickfix/MessageStore.cpp +146 -0
  55. data/ext/quickfix/MessageStore.h +174 -0
  56. data/ext/quickfix/Mutex.h +131 -0
  57. data/ext/quickfix/MySQLConnection.h +194 -0
  58. data/ext/quickfix/MySQLLog.cpp +275 -0
  59. data/ext/quickfix/MySQLLog.h +145 -0
  60. data/ext/quickfix/MySQLStore.cpp +331 -0
  61. data/ext/quickfix/MySQLStore.h +142 -0
  62. data/ext/quickfix/NullStore.cpp +54 -0
  63. data/ext/quickfix/NullStore.h +99 -0
  64. data/ext/quickfix/OdbcConnection.h +266 -0
  65. data/ext/quickfix/OdbcLog.cpp +252 -0
  66. data/ext/quickfix/OdbcLog.h +117 -0
  67. data/ext/quickfix/OdbcStore.cpp +338 -0
  68. data/ext/quickfix/OdbcStore.h +113 -0
  69. data/ext/quickfix/PUGIXML_DOMDocument.cpp +112 -0
  70. data/ext/quickfix/PUGIXML_DOMDocument.h +81 -0
  71. data/ext/quickfix/Parser.cpp +103 -0
  72. data/ext/quickfix/Parser.h +57 -0
  73. data/ext/quickfix/PostgreSQLConnection.h +176 -0
  74. data/ext/quickfix/PostgreSQLLog.cpp +276 -0
  75. data/ext/quickfix/PostgreSQLLog.h +144 -0
  76. data/ext/quickfix/PostgreSQLStore.cpp +334 -0
  77. data/ext/quickfix/PostgreSQLStore.h +141 -0
  78. data/ext/quickfix/Queue.h +75 -0
  79. data/ext/quickfix/QuickfixRuby.cpp +252066 -0
  80. data/ext/quickfix/QuickfixRuby.h +34 -0
  81. data/ext/quickfix/Responder.h +43 -0
  82. data/ext/quickfix/Session.cpp +1487 -0
  83. data/ext/quickfix/Session.h +335 -0
  84. data/ext/quickfix/SessionFactory.cpp +274 -0
  85. data/ext/quickfix/SessionFactory.h +86 -0
  86. data/ext/quickfix/SessionID.h +170 -0
  87. data/ext/quickfix/SessionSettings.cpp +189 -0
  88. data/ext/quickfix/SessionSettings.h +171 -0
  89. data/ext/quickfix/SessionState.h +231 -0
  90. data/ext/quickfix/Settings.cpp +100 -0
  91. data/ext/quickfix/Settings.h +53 -0
  92. data/ext/quickfix/SharedArray.h +150 -0
  93. data/ext/quickfix/SocketAcceptor.cpp +222 -0
  94. data/ext/quickfix/SocketAcceptor.h +75 -0
  95. data/ext/quickfix/SocketConnection.cpp +238 -0
  96. data/ext/quickfix/SocketConnection.h +103 -0
  97. data/ext/quickfix/SocketConnector.cpp +116 -0
  98. data/ext/quickfix/SocketConnector.h +67 -0
  99. data/ext/quickfix/SocketInitiator.cpp +260 -0
  100. data/ext/quickfix/SocketInitiator.h +81 -0
  101. data/ext/quickfix/SocketMonitor.cpp +335 -0
  102. data/ext/quickfix/SocketMonitor.h +111 -0
  103. data/ext/quickfix/SocketServer.cpp +177 -0
  104. data/ext/quickfix/SocketServer.h +100 -0
  105. data/ext/quickfix/ThreadedSocketAcceptor.cpp +258 -0
  106. data/ext/quickfix/ThreadedSocketAcceptor.h +98 -0
  107. data/ext/quickfix/ThreadedSocketConnection.cpp +209 -0
  108. data/ext/quickfix/ThreadedSocketConnection.h +82 -0
  109. data/ext/quickfix/ThreadedSocketInitiator.cpp +268 -0
  110. data/ext/quickfix/ThreadedSocketInitiator.h +84 -0
  111. data/ext/quickfix/TimeRange.cpp +173 -0
  112. data/ext/quickfix/TimeRange.h +258 -0
  113. data/ext/quickfix/Utility.cpp +537 -0
  114. data/ext/quickfix/Utility.h +219 -0
  115. data/ext/quickfix/Values.h +62 -0
  116. data/ext/quickfix/config.h +0 -0
  117. data/ext/quickfix/config_windows.h +0 -0
  118. data/ext/quickfix/extconf.rb +12 -0
  119. data/ext/quickfix/index.h +37 -0
  120. data/ext/quickfix/pugiconfig.hpp +72 -0
  121. data/ext/quickfix/pugixml.cpp +10765 -0
  122. data/ext/quickfix/pugixml.hpp +1341 -0
  123. data/ext/quickfix/strptime.h +7 -0
  124. data/lib/quickfix40.rb +274 -0
  125. data/lib/quickfix41.rb +351 -0
  126. data/lib/quickfix42.rb +1184 -0
  127. data/lib/quickfix43.rb +3504 -0
  128. data/lib/quickfix44.rb +10721 -0
  129. data/lib/quickfix50.rb +13426 -0
  130. data/lib/quickfix50sp1.rb +15629 -0
  131. data/lib/quickfix50sp2.rb +17068 -0
  132. data/lib/quickfix_fields.rb +19853 -0
  133. data/lib/quickfix_ruby.rb +82 -0
  134. data/lib/quickfixt11.rb +70 -0
  135. data/spec/FIX40.xml +862 -0
  136. data/spec/FIX41.xml +1285 -0
  137. data/spec/FIX42.xml +2746 -0
  138. data/spec/FIX43.xml +4229 -0
  139. data/spec/FIX44.xml +6596 -0
  140. data/spec/FIX50.xml +8137 -0
  141. data/spec/FIX50SP1.xml +9496 -0
  142. data/spec/FIX50SP2.xml +10011 -0
  143. data/spec/FIXT11.xml +313 -0
  144. data/test/test_DataDictionaryTestCase.rb +268 -0
  145. data/test/test_DictionaryTestCase.rb +112 -0
  146. data/test/test_FieldBaseTestCase.rb +24 -0
  147. data/test/test_MessageTestCase.rb +368 -0
  148. data/test/test_SessionSettingsTestCase.rb +41 -0
  149. 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