quickfix_ruby 1.14.3.1 → 1.15.1
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 +4 -4
- data/ext/quickfix/Acceptor.h +2 -0
- data/ext/quickfix/AtomicCount.h +82 -12
- data/ext/quickfix/DOMDocument.h +9 -7
- data/ext/quickfix/DataDictionary.cpp +77 -14
- data/ext/quickfix/DataDictionary.h +90 -16
- data/ext/quickfix/Dictionary.cpp +1 -2
- data/ext/quickfix/Exceptions.h +3 -5
- data/ext/quickfix/Field.h +83 -32
- data/ext/quickfix/FieldConvertors.cpp +93 -0
- data/ext/quickfix/FieldConvertors.h +129 -275
- data/ext/quickfix/FieldMap.cpp +53 -13
- data/ext/quickfix/FieldMap.h +200 -62
- data/ext/quickfix/FieldTypes.cpp +10 -10
- data/ext/quickfix/FieldTypes.h +293 -44
- data/ext/quickfix/FileLog.cpp +6 -10
- data/ext/quickfix/FileLog.h +4 -10
- data/ext/quickfix/FileStore.cpp +19 -6
- data/ext/quickfix/FileStore.h +4 -0
- data/ext/quickfix/FixFieldNumbers.h +1462 -1461
- data/ext/quickfix/FixFields.h +1462 -1461
- data/ext/quickfix/FixValues.h +3230 -3227
- data/ext/quickfix/HttpConnection.cpp +1 -1
- data/ext/quickfix/Initiator.cpp +7 -1
- data/ext/quickfix/Initiator.h +2 -0
- data/ext/quickfix/Log.h +6 -12
- data/ext/quickfix/Message.cpp +186 -57
- data/ext/quickfix/Message.h +109 -47
- data/ext/quickfix/MySQLConnection.h +1 -1
- data/ext/quickfix/PostgreSQLConnection.h +1 -1
- data/ext/quickfix/QuickfixRuby.cpp +79141 -77959
- data/ext/quickfix/QuickfixRuby.h +1 -1
- data/ext/quickfix/SSLSocketAcceptor.cpp +410 -0
- data/ext/quickfix/SSLSocketAcceptor.h +185 -0
- data/ext/quickfix/SSLSocketConnection.cpp +427 -0
- data/ext/quickfix/SSLSocketConnection.h +206 -0
- data/ext/quickfix/SSLSocketInitiator.cpp +485 -0
- data/ext/quickfix/SSLSocketInitiator.h +196 -0
- data/ext/quickfix/Session.cpp +113 -20
- data/ext/quickfix/Session.h +18 -4
- data/ext/quickfix/SessionFactory.cpp +10 -3
- data/ext/quickfix/SessionSettings.cpp +5 -3
- data/ext/quickfix/SessionSettings.h +97 -5
- data/ext/quickfix/Settings.cpp +72 -2
- data/ext/quickfix/Settings.h +3 -0
- data/ext/quickfix/SharedArray.h +140 -6
- data/ext/quickfix/SocketConnection.cpp +2 -2
- data/ext/quickfix/SocketConnector.cpp +5 -2
- data/ext/quickfix/SocketConnector.h +3 -2
- data/ext/quickfix/SocketInitiator.cpp +28 -4
- data/ext/quickfix/SocketInitiator.h +1 -1
- data/ext/quickfix/SocketMonitor.cpp +5 -5
- data/ext/quickfix/ThreadedSSLSocketAcceptor.cpp +455 -0
- data/ext/quickfix/ThreadedSSLSocketAcceptor.h +217 -0
- data/ext/quickfix/ThreadedSSLSocketConnection.cpp +404 -0
- data/ext/quickfix/ThreadedSSLSocketConnection.h +189 -0
- data/ext/quickfix/ThreadedSSLSocketInitiator.cpp +469 -0
- data/ext/quickfix/ThreadedSSLSocketInitiator.h +201 -0
- data/ext/quickfix/ThreadedSocketAcceptor.cpp +5 -1
- data/ext/quickfix/ThreadedSocketConnection.cpp +8 -2
- data/ext/quickfix/ThreadedSocketConnection.h +4 -1
- data/ext/quickfix/ThreadedSocketInitiator.cpp +24 -4
- data/ext/quickfix/ThreadedSocketInitiator.h +1 -1
- data/ext/quickfix/Utility.cpp +23 -1
- data/ext/quickfix/Utility.h +28 -2
- data/ext/quickfix/UtilitySSL.cpp +1733 -0
- data/ext/quickfix/UtilitySSL.h +277 -0
- data/ext/quickfix/config-all.h +10 -0
- data/ext/quickfix/dirent_windows.h +838 -0
- data/ext/quickfix/double-conversion/bignum-dtoa.cc +641 -0
- data/ext/quickfix/double-conversion/bignum-dtoa.h +84 -0
- data/ext/quickfix/double-conversion/bignum.cc +766 -0
- data/ext/quickfix/double-conversion/bignum.h +144 -0
- data/ext/quickfix/double-conversion/cached-powers.cc +176 -0
- data/ext/quickfix/double-conversion/cached-powers.h +64 -0
- data/ext/quickfix/double-conversion/diy-fp.cc +57 -0
- data/ext/quickfix/double-conversion/diy-fp.h +118 -0
- data/ext/quickfix/double-conversion/double-conversion.cc +994 -0
- data/ext/quickfix/double-conversion/double-conversion.h +543 -0
- data/ext/quickfix/double-conversion/fast-dtoa.cc +665 -0
- data/ext/quickfix/double-conversion/fast-dtoa.h +88 -0
- data/ext/quickfix/double-conversion/fixed-dtoa.cc +404 -0
- data/ext/quickfix/double-conversion/fixed-dtoa.h +56 -0
- data/ext/quickfix/double-conversion/ieee.h +402 -0
- data/ext/quickfix/double-conversion/strtod.cc +557 -0
- data/ext/quickfix/double-conversion/strtod.h +45 -0
- data/ext/quickfix/double-conversion/utils.h +372 -0
- data/ext/quickfix/stdint_msvc.h +254 -0
- data/lib/quickfix44.rb +3329 -10
- data/lib/quickfix50.rb +6649 -81
- data/lib/quickfix50sp1.rb +8054 -142
- data/lib/quickfix50sp2.rb +10900 -234
- data/lib/quickfix_fields.rb +7662 -7649
- data/spec/FIX40.xml +28 -28
- data/spec/FIX41.xml +29 -29
- data/spec/FIX42.xml +47 -47
- data/spec/FIX43.xml +148 -148
- data/spec/FIX44.xml +1078 -1081
- data/spec/FIX50.xml +1292 -1289
- data/spec/FIX50SP1.xml +1811 -1802
- data/spec/FIX50SP2.xml +1948 -1939
- data/spec/FIXT11.xml +5 -8
- data/test/test_FieldBaseTestCase.rb +1 -1
- data/test/test_MessageTestCase.rb +2 -2
- metadata +42 -6
data/ext/quickfix/Session.h
CHANGED
|
@@ -180,9 +180,22 @@ public:
|
|
|
180
180
|
{ m_refreshOnLogon = value; }
|
|
181
181
|
|
|
182
182
|
bool getMillisecondsInTimeStamp()
|
|
183
|
-
{ return
|
|
183
|
+
{ return (m_timestampPrecision == 3); }
|
|
184
184
|
void setMillisecondsInTimeStamp ( bool value )
|
|
185
|
-
{
|
|
185
|
+
{ if (value)
|
|
186
|
+
m_timestampPrecision = 3;
|
|
187
|
+
else
|
|
188
|
+
m_timestampPrecision = 0;
|
|
189
|
+
}
|
|
190
|
+
int getTimestampPrecision()
|
|
191
|
+
{ return m_timestampPrecision; }
|
|
192
|
+
void setTimestampPrecision(int precision)
|
|
193
|
+
{
|
|
194
|
+
if (precision < 0 || precision > 9)
|
|
195
|
+
return;
|
|
196
|
+
|
|
197
|
+
m_timestampPrecision = precision;
|
|
198
|
+
}
|
|
186
199
|
|
|
187
200
|
bool getPersistMessages()
|
|
188
201
|
{ return m_persistMessages; }
|
|
@@ -298,6 +311,8 @@ private:
|
|
|
298
311
|
bool set( int s, const Message& m );
|
|
299
312
|
bool get( int s, Message& m ) const;
|
|
300
313
|
|
|
314
|
+
Message * newMessage(const std::string & msgType) const;
|
|
315
|
+
|
|
301
316
|
Application& m_application;
|
|
302
317
|
SessionID m_sessionID;
|
|
303
318
|
TimeRange m_sessionTime;
|
|
@@ -313,7 +328,7 @@ private:
|
|
|
313
328
|
bool m_resetOnLogout;
|
|
314
329
|
bool m_resetOnDisconnect;
|
|
315
330
|
bool m_refreshOnLogon;
|
|
316
|
-
|
|
331
|
+
int m_timestampPrecision;
|
|
317
332
|
bool m_persistMessages;
|
|
318
333
|
bool m_validateLengthAndChecksum;
|
|
319
334
|
|
|
@@ -328,7 +343,6 @@ private:
|
|
|
328
343
|
static SessionIDs s_sessionIDs;
|
|
329
344
|
static Sessions s_registered;
|
|
330
345
|
static Mutex s_mutex;
|
|
331
|
-
|
|
332
346
|
};
|
|
333
347
|
}
|
|
334
348
|
|
|
@@ -120,7 +120,7 @@ Session* SessionFactory::create( const SessionID& sessionID,
|
|
|
120
120
|
if ( heartBtInt <= 0 ) throw ConfigError( "Heartbeat must be greater than zero" );
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
SmartPtr<Session> pSession;
|
|
124
124
|
pSession.reset( new Session( m_application, m_messageStoreFactory,
|
|
125
125
|
sessionID, dataDictionaryProvider, sessionTimeRange,
|
|
126
126
|
heartBtInt, m_pLogFactory ) );
|
|
@@ -189,7 +189,9 @@ Session* SessionFactory::create( const SessionID& sessionID,
|
|
|
189
189
|
if ( settings.has( REFRESH_ON_LOGON ) )
|
|
190
190
|
pSession->setRefreshOnLogon( settings.getBool( REFRESH_ON_LOGON ) );
|
|
191
191
|
if ( settings.has( MILLISECONDS_IN_TIMESTAMP ) )
|
|
192
|
-
pSession->
|
|
192
|
+
pSession->setTimestampPrecision(3);
|
|
193
|
+
if ( settings.has( TIMESTAMP_PRECISION ) )
|
|
194
|
+
pSession->setTimestampPrecision(settings.getInt( TIMESTAMP_PRECISION ) );
|
|
193
195
|
if ( settings.has( PERSIST_MESSAGES ) )
|
|
194
196
|
pSession->setPersistMessages( settings.getBool( PERSIST_MESSAGES ) );
|
|
195
197
|
if ( settings.has( VALIDATE_LENGTH_AND_CHECKSUM ) )
|
|
@@ -216,7 +218,10 @@ ptr::shared_ptr<DataDictionary> SessionFactory::createDataDictionary(const Sessi
|
|
|
216
218
|
}
|
|
217
219
|
else
|
|
218
220
|
{
|
|
219
|
-
|
|
221
|
+
bool preserveMsgFldsOrder = false;
|
|
222
|
+
if( settings.has( PRESERVE_MESSAGE_FIELDS_ORDER ) )
|
|
223
|
+
preserveMsgFldsOrder = settings.getBool( PRESERVE_MESSAGE_FIELDS_ORDER );
|
|
224
|
+
pDD = ptr::shared_ptr<DataDictionary>(new DataDictionary( path, preserveMsgFldsOrder ));
|
|
220
225
|
m_dictionaries[ path ] = pDD;
|
|
221
226
|
}
|
|
222
227
|
|
|
@@ -228,6 +233,8 @@ ptr::shared_ptr<DataDictionary> SessionFactory::createDataDictionary(const Sessi
|
|
|
228
233
|
pCopyOfDD->checkFieldsHaveValues( settings.getBool( VALIDATE_FIELDS_HAVE_VALUES ) );
|
|
229
234
|
if( settings.has( VALIDATE_USER_DEFINED_FIELDS ) )
|
|
230
235
|
pCopyOfDD->checkUserDefinedFields( settings.getBool( VALIDATE_USER_DEFINED_FIELDS ) );
|
|
236
|
+
if( settings.has( ALLOW_UNKNOWN_MSG_FIELDS ) )
|
|
237
|
+
pCopyOfDD->allowUnknownMsgFields( settings.getBool( ALLOW_UNKNOWN_MSG_FIELDS ) );
|
|
231
238
|
|
|
232
239
|
return pCopyOfDD;
|
|
233
240
|
}
|
|
@@ -30,14 +30,16 @@
|
|
|
30
30
|
|
|
31
31
|
namespace FIX
|
|
32
32
|
{
|
|
33
|
-
SessionSettings::SessionSettings( std::istream& stream )
|
|
33
|
+
SessionSettings::SessionSettings( std::istream& stream, bool resolveEnvVars )
|
|
34
34
|
throw( ConfigError )
|
|
35
|
+
: m_resolveEnvVars( resolveEnvVars )
|
|
35
36
|
{
|
|
36
37
|
stream >> *this;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
SessionSettings::SessionSettings( const std::string& file )
|
|
40
|
+
SessionSettings::SessionSettings( const std::string& file, bool resolveEnvVars )
|
|
40
41
|
throw( ConfigError )
|
|
42
|
+
: m_resolveEnvVars( resolveEnvVars )
|
|
41
43
|
{
|
|
42
44
|
std::ifstream fstream( file.c_str() );
|
|
43
45
|
if ( !fstream.is_open() )
|
|
@@ -48,7 +50,7 @@ throw( ConfigError )
|
|
|
48
50
|
std::istream& operator>>( std::istream& stream, SessionSettings& s )
|
|
49
51
|
throw( ConfigError )
|
|
50
52
|
{
|
|
51
|
-
Settings settings;
|
|
53
|
+
Settings settings(s.m_resolveEnvVars);
|
|
52
54
|
stream >> settings;
|
|
53
55
|
|
|
54
56
|
Settings::Sections section;
|
|
@@ -63,14 +63,18 @@ const char SOCKET_ACCEPT_PORT[] = "SocketAcceptPort";
|
|
|
63
63
|
const char SOCKET_REUSE_ADDRESS[] = "SocketReuseAddress";
|
|
64
64
|
const char SOCKET_CONNECT_HOST[] = "SocketConnectHost";
|
|
65
65
|
const char SOCKET_CONNECT_PORT[] = "SocketConnectPort";
|
|
66
|
+
const char SOCKET_CONNECT_SOURCE_HOST[] = "SocketConnectSourceHost";
|
|
67
|
+
const char SOCKET_CONNECT_SOURCE_PORT[] = "SocketConnectSourcePort";
|
|
66
68
|
const char SOCKET_NODELAY[] = "SocketNodelay";
|
|
67
|
-
const char SOCKET_SEND_BUFFER_SIZE[] = "
|
|
68
|
-
const char SOCKET_RECEIVE_BUFFER_SIZE[] = "
|
|
69
|
+
const char SOCKET_SEND_BUFFER_SIZE[] = "SocketSendBufferSize";
|
|
70
|
+
const char SOCKET_RECEIVE_BUFFER_SIZE[] = "SocketReceiveBufferSize";
|
|
69
71
|
const char RECONNECT_INTERVAL[] = "ReconnectInterval";
|
|
70
72
|
const char VALIDATE_LENGTH_AND_CHECKSUM[] = "ValidateLengthAndChecksum";
|
|
71
73
|
const char VALIDATE_FIELDS_OUT_OF_ORDER[] = "ValidateFieldsOutOfOrder";
|
|
72
74
|
const char VALIDATE_FIELDS_HAVE_VALUES[] = "ValidateFieldsHaveValues";
|
|
73
75
|
const char VALIDATE_USER_DEFINED_FIELDS[] = "ValidateUserDefinedFields";
|
|
76
|
+
const char ALLOW_UNKNOWN_MSG_FIELDS[] = "AllowUnknownMsgFields";
|
|
77
|
+
const char PRESERVE_MESSAGE_FIELDS_ORDER[] = "PreserveMessageFieldsOrder";
|
|
74
78
|
const char LOGON_TIMEOUT[] = "LogonTimeout";
|
|
75
79
|
const char LOGOUT_TIMEOUT[] = "LogoutTimeout";
|
|
76
80
|
const char FILE_STORE_PATH[] = "FileStorePath";
|
|
@@ -123,16 +127,102 @@ const char RESET_ON_LOGOUT[] = "ResetOnLogout";
|
|
|
123
127
|
const char RESET_ON_DISCONNECT[] = "ResetOnDisconnect";
|
|
124
128
|
const char REFRESH_ON_LOGON[] = "RefreshOnLogon";
|
|
125
129
|
const char MILLISECONDS_IN_TIMESTAMP[] = "MillisecondsInTimeStamp";
|
|
130
|
+
const char TIMESTAMP_PRECISION[] = "TimestampPrecision";
|
|
126
131
|
const char HTTP_ACCEPT_PORT[] = "HttpAcceptPort";
|
|
127
132
|
const char PERSIST_MESSAGES[] = "PersistMessages";
|
|
133
|
+
const char SERVER_CERT_FILE[] = "ServerCertificateFile";
|
|
134
|
+
const char SERVER_CERT_KEY_FILE[] = "ServerCertificateKeyFile";
|
|
135
|
+
const char CLIENT_CERT_FILE[] = "ClientCertificateFile";
|
|
136
|
+
const char CLIENT_CERT_KEY_FILE[] = "ClientCertificateKeyFile";
|
|
137
|
+
const char CERT_AUTH_FILE[] = "CertificationAuthoritiesFile";
|
|
138
|
+
const char CERT_AUTH_DIR[] = "CertificationAuthoritiesDirectory";
|
|
139
|
+
const char CRL_FILE[] = "CertificateRevocationListFile";
|
|
140
|
+
const char CRL_DIR[] = "CertificateRevocationListDirectory";
|
|
141
|
+
const char VERIFY_LEVEL[] = "CertificateVerifyLevel";
|
|
142
|
+
/*
|
|
143
|
+
# This directive can be used to control the SSL protocol flavors the application
|
|
144
|
+
# should use when establishing its environment.
|
|
145
|
+
#
|
|
146
|
+
# The available (case-insensitive) protocols are:
|
|
147
|
+
#
|
|
148
|
+
# SSLv2
|
|
149
|
+
#
|
|
150
|
+
# This is the Secure Sockets Layer (SSL) protocol, version 2.0. It is the
|
|
151
|
+
# original SSL protocol as designed by Netscape Corporation.
|
|
152
|
+
#
|
|
153
|
+
# SSLv3
|
|
154
|
+
#
|
|
155
|
+
# This is the Secure Sockets Layer (SSL) protocol, version 3.0. It is the
|
|
156
|
+
# successor to SSLv2 and the currently (as of February 1999) de-facto
|
|
157
|
+
# standardized SSL protocol from Netscape Corporation. It's supported by
|
|
158
|
+
# almost all popular browsers.
|
|
159
|
+
#
|
|
160
|
+
# TLSv1
|
|
161
|
+
#
|
|
162
|
+
# This is the Transport Layer Security (TLS) protocol, version 1.0.
|
|
163
|
+
#
|
|
164
|
+
# TLSv1_1
|
|
165
|
+
#
|
|
166
|
+
# This is the Transport Layer Security (TLS) protocol, version 1.1.
|
|
167
|
+
#
|
|
168
|
+
# TLSv1_2
|
|
169
|
+
#
|
|
170
|
+
# This is the Transport Layer Security (TLS) protocol, version 1.2.
|
|
171
|
+
#
|
|
172
|
+
# all
|
|
173
|
+
#
|
|
174
|
+
# This is a shortcut for `+SSLv2 +SSLv3 +TLSv1 +TLSv1_1 +TLSv1_2' and a convenient way for
|
|
175
|
+
# enabling all protocols except one when used in combination with the minus
|
|
176
|
+
# sign on a protocol as the example above shows.
|
|
177
|
+
#
|
|
178
|
+
# Example:
|
|
179
|
+
#
|
|
180
|
+
# enable all but not SSLv2
|
|
181
|
+
# SSL_PROTOCOL = all -SSLv2
|
|
182
|
+
#
|
|
183
|
+
# `all -SSLv2` is the default value when the parameter is not specified.
|
|
184
|
+
|
|
185
|
+
*/
|
|
186
|
+
const char SSL_PROTOCOL[] = "SSLProtocol";
|
|
187
|
+
/*
|
|
188
|
+
# This complex directive uses a colon-separated cipher-spec string consisting
|
|
189
|
+
# of OpenSSL cipher specifications to configure the Cipher Suite the client is
|
|
190
|
+
# permitted to negotiate in the SSL handshake phase. Notice that this directive
|
|
191
|
+
# can be used both in per-server and per-directory context. In per-server
|
|
192
|
+
# context it applies to the standard SSL handshake when a connection is
|
|
193
|
+
# established. In per-directory context it forces a SSL renegotation with the
|
|
194
|
+
# reconfigured Cipher Suite after the HTTP request was read but before the HTTP
|
|
195
|
+
# response is sent.
|
|
196
|
+
#
|
|
197
|
+
# An SSL cipher specification in cipher-spec is composed of 4 major attributes
|
|
198
|
+
# plus a few extra minor ones:
|
|
199
|
+
#
|
|
200
|
+
# Key Exchange Algorithm:
|
|
201
|
+
# RSA or Diffie-Hellman variants.
|
|
202
|
+
#
|
|
203
|
+
# Authentication Algorithm:
|
|
204
|
+
# RSA, Diffie-Hellman, DSS or none.
|
|
205
|
+
#
|
|
206
|
+
# Cipher/Encryption Algorithm:
|
|
207
|
+
# DES, Triple-DES, RC4, RC2, IDEA or none.
|
|
208
|
+
#
|
|
209
|
+
# MAC Digest Algorithm:
|
|
210
|
+
# MD5, SHA or SHA1.
|
|
211
|
+
#
|
|
212
|
+
# For more details refer to mod_ssl documentation.
|
|
213
|
+
#
|
|
214
|
+
# Example: RC4+RSA:+HIGH:
|
|
215
|
+
*/
|
|
216
|
+
const char SSL_CIPHER_SUITE[] = "SSLCipherSuite";
|
|
217
|
+
|
|
128
218
|
|
|
129
219
|
/// Container for setting dictionaries mapped to sessions.
|
|
130
220
|
class SessionSettings
|
|
131
221
|
{
|
|
132
222
|
public:
|
|
133
|
-
SessionSettings() {}
|
|
134
|
-
SessionSettings( std::istream& stream ) throw( ConfigError );
|
|
135
|
-
SessionSettings( const std::string& file ) throw( ConfigError );
|
|
223
|
+
SessionSettings() { m_resolveEnvVars = false; }
|
|
224
|
+
SessionSettings( std::istream& stream, bool resolveEnvVars = false ) throw( ConfigError );
|
|
225
|
+
SessionSettings( const std::string& file, bool resolveEnvVars = false ) throw( ConfigError );
|
|
136
226
|
|
|
137
227
|
/// Check if session setings are present
|
|
138
228
|
const bool has( const SessionID& ) const;
|
|
@@ -158,7 +248,9 @@ private:
|
|
|
158
248
|
|
|
159
249
|
Dictionaries m_settings;
|
|
160
250
|
Dictionary m_defaults;
|
|
251
|
+
bool m_resolveEnvVars; // while reading, replace $var, $(var) and ${var} by environment variable var
|
|
161
252
|
|
|
253
|
+
friend std::istream& operator>>( std::istream&, SessionSettings& ) throw( ConfigError );
|
|
162
254
|
friend std::ostream& operator<<( std::ostream&, const SessionSettings& );
|
|
163
255
|
};
|
|
164
256
|
/*! @} */
|
data/ext/quickfix/Settings.cpp
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
#include "config.h"
|
|
24
24
|
#endif
|
|
25
25
|
|
|
26
|
+
#include <cstring>
|
|
26
27
|
#include "Settings.h"
|
|
27
28
|
|
|
28
29
|
namespace FIX
|
|
@@ -61,13 +62,82 @@ std::pair<std::string, std::string> splitKeyValue( const std::string& line )
|
|
|
61
62
|
return std::pair<std::string, std::string>( key, value );
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
std::string resolveEnvVars(const std::string& str)
|
|
66
|
+
{
|
|
67
|
+
std::string resultStr;
|
|
68
|
+
size_t actPos = 0;
|
|
69
|
+
size_t sourceLen = str.length();
|
|
70
|
+
|
|
71
|
+
while (actPos < sourceLen)
|
|
72
|
+
{
|
|
73
|
+
char c = str[actPos++];
|
|
74
|
+
if (actPos < sourceLen)
|
|
75
|
+
{
|
|
76
|
+
// escape character
|
|
77
|
+
if (c == '\\')
|
|
78
|
+
{
|
|
79
|
+
c = str[actPos++];
|
|
80
|
+
switch (c)
|
|
81
|
+
{
|
|
82
|
+
case 't' : resultStr.append(1, '\t'); break;
|
|
83
|
+
case 'r' : resultStr.append(1, '\r'); break;
|
|
84
|
+
case 'n' : resultStr.append(1, '\n'); break;
|
|
85
|
+
default :
|
|
86
|
+
resultStr.append(1, c);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// variable substitution
|
|
93
|
+
if (c == '$')
|
|
94
|
+
{
|
|
95
|
+
bool inBraces = false;
|
|
96
|
+
c = str[actPos++];
|
|
97
|
+
if ((c == '(') || (c == '{'))
|
|
98
|
+
{
|
|
99
|
+
c = str[actPos++];
|
|
100
|
+
inBraces = true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// actPos now points at start of var name
|
|
104
|
+
if (actPos >= sourceLen)
|
|
105
|
+
break;
|
|
106
|
+
std::string varName;
|
|
107
|
+
while ( (actPos <= sourceLen) )
|
|
108
|
+
{
|
|
109
|
+
varName.append(1, c); // this must be done before overwriting c
|
|
110
|
+
c = str[actPos++];
|
|
111
|
+
if (std::strchr(" /:;,.=\"'?#+*()[]{}$&%\t\n", c))
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
if (inBraces && (actPos <= sourceLen) && ((c == ')') || (c == '}')))
|
|
115
|
+
;
|
|
116
|
+
else
|
|
117
|
+
--actPos;
|
|
118
|
+
// varName contains the name of the variable,
|
|
119
|
+
// actPos points to first char _after_ variable
|
|
120
|
+
const char *varValue = 0;
|
|
121
|
+
if (!varName.empty() && (0 != (varValue = getenv(varName.c_str()))))
|
|
122
|
+
resultStr.append(varValue);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// nothing special, just copy
|
|
128
|
+
resultStr.append(1, c);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return resultStr;
|
|
132
|
+
}
|
|
133
|
+
|
|
64
134
|
std::istream& operator>>( std::istream& stream, Settings& s )
|
|
65
135
|
{
|
|
66
136
|
char buffer[1024];
|
|
67
137
|
std::string line;
|
|
68
138
|
Settings::Sections::iterator section = s.m_sections.end();;
|
|
69
139
|
|
|
70
|
-
while( stream.getline(buffer,
|
|
140
|
+
while( stream.getline(buffer, sizeof(buffer)) )
|
|
71
141
|
{
|
|
72
142
|
line = string_strip( buffer );
|
|
73
143
|
if( isComment(line) )
|
|
@@ -83,7 +153,7 @@ std::istream& operator>>( std::istream& stream, Settings& s )
|
|
|
83
153
|
std::pair<std::string, std::string> keyValue = splitKeyValue( line );
|
|
84
154
|
if( section == s.m_sections.end() )
|
|
85
155
|
continue;
|
|
86
|
-
(*section).setString( keyValue.first, keyValue.second );
|
|
156
|
+
(*section).setString( keyValue.first, s.m_resolveEnvVars ? resolveEnvVars(keyValue.second) : keyValue.second );
|
|
87
157
|
}
|
|
88
158
|
}
|
|
89
159
|
return stream;
|
data/ext/quickfix/Settings.h
CHANGED
|
@@ -38,6 +38,8 @@ namespace FIX
|
|
|
38
38
|
class Settings
|
|
39
39
|
{
|
|
40
40
|
public:
|
|
41
|
+
Settings( bool resolveEnvVars = false ) : m_resolveEnvVars(resolveEnvVars) {}
|
|
42
|
+
|
|
41
43
|
typedef std::vector < Dictionary > Sections;
|
|
42
44
|
|
|
43
45
|
Sections get( const std::string& name ) const;
|
|
@@ -45,6 +47,7 @@ public:
|
|
|
45
47
|
friend std::istream& operator>>( std::istream&, Settings& );
|
|
46
48
|
private:
|
|
47
49
|
Sections m_sections;
|
|
50
|
+
bool m_resolveEnvVars;
|
|
48
51
|
};
|
|
49
52
|
|
|
50
53
|
std::istream& operator>>( std::istream&, Settings& );
|
data/ext/quickfix/SharedArray.h
CHANGED
|
@@ -22,14 +22,21 @@
|
|
|
22
22
|
#ifndef SHARED_ARRAY
|
|
23
23
|
#define SHARED_ARRAY
|
|
24
24
|
|
|
25
|
+
#include "config-all.h"
|
|
25
26
|
#include "AtomicCount.h"
|
|
26
27
|
|
|
27
28
|
namespace FIX
|
|
28
29
|
{
|
|
29
30
|
/// Shared array with atomic reference count
|
|
31
|
+
#ifndef NO_UNALIGNED_ACCESS
|
|
30
32
|
template<typename T>
|
|
31
33
|
class shared_array
|
|
32
34
|
{
|
|
35
|
+
enum
|
|
36
|
+
{
|
|
37
|
+
data_offset = ( sizeof(atomic_count) / sizeof(T) + 1 )
|
|
38
|
+
};
|
|
39
|
+
|
|
33
40
|
public:
|
|
34
41
|
shared_array()
|
|
35
42
|
: m_size(0)
|
|
@@ -67,16 +74,16 @@ namespace FIX
|
|
|
67
74
|
{ return m_buffer == 0; }
|
|
68
75
|
|
|
69
76
|
operator T* () const
|
|
70
|
-
{ return m_buffer; }
|
|
77
|
+
{ return &m_buffer[data_offset]; }
|
|
71
78
|
|
|
72
79
|
//optimized function to allocate storage for buffer and counter object at once
|
|
73
80
|
static shared_array create(const std::size_t nSize)
|
|
74
81
|
{
|
|
75
|
-
if(nSize
|
|
82
|
+
if(nSize == 0)
|
|
76
83
|
return shared_array();
|
|
77
84
|
|
|
78
85
|
//verify the needed buffer size to allocate counter object and nSize elements
|
|
79
|
-
const std::size_t sizeToAllocate =
|
|
86
|
+
const std::size_t sizeToAllocate = data_offset + nSize;
|
|
80
87
|
|
|
81
88
|
//allocate and zero-fill the buffer
|
|
82
89
|
T* storage = new T[ sizeToAllocate ];
|
|
@@ -84,7 +91,7 @@ namespace FIX
|
|
|
84
91
|
|
|
85
92
|
// create the counter object at the end of the storage
|
|
86
93
|
// with initial reference count set to 1
|
|
87
|
-
new (
|
|
94
|
+
new (storage) atomic_count( 1 );
|
|
88
95
|
|
|
89
96
|
return shared_array(storage, nSize);
|
|
90
97
|
}
|
|
@@ -100,7 +107,7 @@ namespace FIX
|
|
|
100
107
|
|
|
101
108
|
atomic_count* get_counter() const
|
|
102
109
|
{
|
|
103
|
-
return reinterpret_cast<atomic_count*>(
|
|
110
|
+
return reinterpret_cast<atomic_count*>( m_buffer );
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
void increment_reference_count() const
|
|
@@ -109,7 +116,7 @@ namespace FIX
|
|
|
109
116
|
++(*counter);
|
|
110
117
|
}
|
|
111
118
|
|
|
112
|
-
long decrement_reference_count()
|
|
119
|
+
long decrement_reference_count() const
|
|
113
120
|
{
|
|
114
121
|
atomic_count* counter = get_counter();
|
|
115
122
|
return --(*counter);
|
|
@@ -145,6 +152,133 @@ namespace FIX
|
|
|
145
152
|
std::size_t m_size;
|
|
146
153
|
T * m_buffer;
|
|
147
154
|
};
|
|
155
|
+
#else
|
|
156
|
+
template<typename T>
|
|
157
|
+
class shared_array
|
|
158
|
+
{
|
|
159
|
+
public:
|
|
160
|
+
shared_array()
|
|
161
|
+
: m_size(0)
|
|
162
|
+
, m_buffer(0)
|
|
163
|
+
, m_pCtr(0)
|
|
164
|
+
{}
|
|
165
|
+
|
|
166
|
+
shared_array(const shared_array& rhs)
|
|
167
|
+
: m_size(rhs.m_size)
|
|
168
|
+
, m_buffer(rhs.m_buffer)
|
|
169
|
+
{
|
|
170
|
+
rhs.attach();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
~shared_array()
|
|
174
|
+
{ release(); }
|
|
175
|
+
|
|
176
|
+
shared_array& operator=(const shared_array& rhs)
|
|
177
|
+
{
|
|
178
|
+
if( &rhs == this )
|
|
179
|
+
return *this;
|
|
180
|
+
|
|
181
|
+
rhs.attach();
|
|
182
|
+
release();
|
|
183
|
+
|
|
184
|
+
m_size = rhs.m_size;
|
|
185
|
+
m_buffer = rhs.m_buffer;
|
|
186
|
+
m_pCtr = rhs.m_pCtr;
|
|
187
|
+
|
|
188
|
+
return *this;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
std::size_t size() const
|
|
192
|
+
{ return m_size; }
|
|
193
|
+
|
|
194
|
+
bool empty() const
|
|
195
|
+
{ return m_buffer == 0; }
|
|
196
|
+
|
|
197
|
+
operator T* () const
|
|
198
|
+
{ return m_buffer; }
|
|
199
|
+
|
|
200
|
+
//optimized function to allocate storage for buffer and counter object at once
|
|
201
|
+
static shared_array create(const std::size_t nSize)
|
|
202
|
+
{
|
|
203
|
+
if(nSize <= 0)
|
|
204
|
+
return shared_array();
|
|
205
|
+
|
|
206
|
+
//verify the needed buffer size to allocate counter object and nSize elements
|
|
207
|
+
const std::size_t sizeToAllocate = (nSize * sizeof(T)) + sizeof(atomic_count) + 15;
|
|
208
|
+
|
|
209
|
+
//allocate and zero-fill the buffer
|
|
210
|
+
void * buf = std::malloc(sizeToAllocate);
|
|
211
|
+
memset(buf, 0, sizeToAllocate);
|
|
212
|
+
|
|
213
|
+
// create the counter object at the end of the storage
|
|
214
|
+
// with initial reference count set to 1
|
|
215
|
+
/* round up to multiple of alignment : add (alignment - 1) and then round down by masking */
|
|
216
|
+
void *ptr = (void *) (((uintptr_t)(buf) + nSize * sizeof(T) + 15) & ~ (uintptr_t)0x0F);
|
|
217
|
+
new (ptr) atomic_count( 1 );
|
|
218
|
+
|
|
219
|
+
T* storage = reinterpret_cast<T*>(buf);
|
|
220
|
+
return shared_array(storage, nSize, ptr);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private:
|
|
224
|
+
|
|
225
|
+
shared_array( T * buff, std::size_t nSize, void * pCtr )
|
|
226
|
+
: m_size(nSize)
|
|
227
|
+
, m_buffer(buff)
|
|
228
|
+
, m_pCtr(pCtr)
|
|
229
|
+
{
|
|
230
|
+
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
atomic_count* get_counter() const
|
|
234
|
+
{
|
|
235
|
+
return reinterpret_cast<atomic_count*>( m_pCtr );
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
void increment_reference_count() const
|
|
239
|
+
{
|
|
240
|
+
atomic_count* counter = get_counter();
|
|
241
|
+
++(*counter);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
long decrement_reference_count() const
|
|
245
|
+
{
|
|
246
|
+
atomic_count* counter = get_counter();
|
|
247
|
+
return --(*counter);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
void attach() const
|
|
251
|
+
{
|
|
252
|
+
if( !empty() )
|
|
253
|
+
increment_reference_count();
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
void release()
|
|
257
|
+
{
|
|
258
|
+
if( empty() )
|
|
259
|
+
return;
|
|
260
|
+
|
|
261
|
+
//free object if reference count has decreased to zero
|
|
262
|
+
if( decrement_reference_count() == 0)
|
|
263
|
+
{
|
|
264
|
+
T * tmpBuff = m_buffer;
|
|
265
|
+
atomic_count* tmpCounter = get_counter();
|
|
266
|
+
|
|
267
|
+
m_buffer = 0;
|
|
268
|
+
m_size = 0;
|
|
269
|
+
|
|
270
|
+
//explicitly call destructor for the counter object
|
|
271
|
+
tmpCounter->~atomic_count();
|
|
272
|
+
|
|
273
|
+
std::free(tmpBuff);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
std::size_t m_size;
|
|
278
|
+
T * m_buffer;
|
|
279
|
+
void * m_pCtr;
|
|
280
|
+
};
|
|
281
|
+
#endif
|
|
148
282
|
}
|
|
149
283
|
|
|
150
284
|
#endif
|