quickfix_ruby 1.14.3.1 → 1.15.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|