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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df5047d3c81911491ebbf1d707c5ac0385d4a39d
|
4
|
+
data.tar.gz: 1558e66c08562f551af3d1d5a7589d09b6018ec3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7923a274db5a89bbd5e730d6bee308c4d9a7a853b52938f4f5a2a1b20cac2a9891ee0b0371be75895c5853a7a48ab3c613608d8fedac9bf3e80b3465dfb85de5
|
7
|
+
data.tar.gz: 8c0fd54ae7116b8b55d2ce21670ecab11dea76a204cbf5c4aa68901f72271e4ec1c5b1c393b17e39fe2b52c5d9b1adfee23e71c69e20655d2a8ed162dfcf43c0
|
data/ext/quickfix/Acceptor.h
CHANGED
@@ -114,7 +114,9 @@ private:
|
|
114
114
|
SessionIDs m_sessionIDs;
|
115
115
|
Application& m_application;
|
116
116
|
MessageStoreFactory& m_messageStoreFactory;
|
117
|
+
protected:
|
117
118
|
SessionSettings m_settings;
|
119
|
+
private:
|
118
120
|
LogFactory* m_pLogFactory;
|
119
121
|
Log* m_pLog;
|
120
122
|
NullLog m_nullLog;
|
data/ext/quickfix/AtomicCount.h
CHANGED
@@ -22,7 +22,11 @@
|
|
22
22
|
#ifndef ATOMIC_COUNT
|
23
23
|
#define ATOMIC_COUNT
|
24
24
|
|
25
|
+
#include "Utility.h"
|
26
|
+
|
27
|
+
#if defined(__SUNPRO_CC) || defined(__TOS_AIX__)
|
25
28
|
#include "Mutex.h"
|
29
|
+
#endif
|
26
30
|
|
27
31
|
namespace FIX
|
28
32
|
{
|
@@ -55,7 +59,7 @@ typedef boost::detail::atomic_count atomic_count;
|
|
55
59
|
|
56
60
|
operator long() const
|
57
61
|
{
|
58
|
-
return
|
62
|
+
return ::InterlockedExchangeAdd(const_cast<long volatile *>( &m_counter ), 0 );
|
59
63
|
}
|
60
64
|
|
61
65
|
private:
|
@@ -66,30 +70,75 @@ typedef boost::detail::atomic_count atomic_count;
|
|
66
70
|
long volatile m_counter;
|
67
71
|
};
|
68
72
|
|
73
|
+
#elif defined(__SUNPRO_CC) || defined(__TOS_AIX__)
|
74
|
+
|
75
|
+
// general purpose atomic counter using mutexes
|
76
|
+
class atomic_count
|
77
|
+
{
|
78
|
+
public:
|
79
|
+
explicit atomic_count( long v ): m_counter( v )
|
80
|
+
{
|
81
|
+
}
|
82
|
+
|
83
|
+
long operator++()
|
84
|
+
{
|
85
|
+
Locker _lock(m_mutex);
|
86
|
+
return ++m_counter;
|
87
|
+
}
|
88
|
+
|
89
|
+
long operator--()
|
90
|
+
{
|
91
|
+
Locker _lock(m_mutex);
|
92
|
+
return --m_counter;
|
93
|
+
}
|
94
|
+
|
95
|
+
operator long() const
|
96
|
+
{
|
97
|
+
return static_cast<long const volatile &>( m_counter );
|
98
|
+
}
|
99
|
+
|
100
|
+
private:
|
101
|
+
|
102
|
+
atomic_count( atomic_count const & );
|
103
|
+
atomic_count & operator=( atomic_count const & );
|
104
|
+
|
105
|
+
Mutex m_mutex;
|
106
|
+
long m_counter;
|
107
|
+
};
|
108
|
+
|
69
109
|
#else
|
70
|
-
|
110
|
+
|
111
|
+
//
|
112
|
+
// boost/detail/atomic_count_gcc_x86.hpp
|
113
|
+
//
|
114
|
+
// atomic_count for g++ on 486+/AMD64
|
115
|
+
//
|
116
|
+
// Copyright 2007 Peter Dimov
|
117
|
+
//
|
118
|
+
// Distributed under the Boost Software License, Version 1.0. (See
|
119
|
+
// accompanying file LICENSE_1_0.txt or copy at
|
120
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
121
|
+
//
|
122
|
+
|
71
123
|
class atomic_count
|
72
124
|
{
|
73
125
|
public:
|
74
|
-
|
75
|
-
{
|
76
|
-
}
|
126
|
+
|
127
|
+
explicit atomic_count( long v ) : value_(static_cast<int>(v)) {}
|
77
128
|
|
78
129
|
long operator++()
|
79
130
|
{
|
80
|
-
|
81
|
-
return ++m_counter;
|
131
|
+
return atomic_exchange_and_add( &value_, 1 ) + 1;
|
82
132
|
}
|
83
133
|
|
84
134
|
long operator--()
|
85
135
|
{
|
86
|
-
|
87
|
-
return --m_counter;
|
136
|
+
return atomic_exchange_and_add( &value_, -1 ) - 1;
|
88
137
|
}
|
89
138
|
|
90
139
|
operator long() const
|
91
140
|
{
|
92
|
-
return
|
141
|
+
return atomic_exchange_and_add( &value_, 0 );
|
93
142
|
}
|
94
143
|
|
95
144
|
private:
|
@@ -97,8 +146,29 @@ typedef boost::detail::atomic_count atomic_count;
|
|
97
146
|
atomic_count( atomic_count const & );
|
98
147
|
atomic_count & operator=( atomic_count const & );
|
99
148
|
|
100
|
-
|
101
|
-
|
149
|
+
mutable int value_;
|
150
|
+
|
151
|
+
private:
|
152
|
+
|
153
|
+
static int atomic_exchange_and_add(int * pw, int dv)
|
154
|
+
{
|
155
|
+
// int r = *pw;
|
156
|
+
// *pw += dv;
|
157
|
+
// return r;
|
158
|
+
|
159
|
+
int r;
|
160
|
+
|
161
|
+
__asm__ __volatile__
|
162
|
+
(
|
163
|
+
"lock\n\t"
|
164
|
+
"xadd %1, %0":
|
165
|
+
"+m"(*pw), "=r"(r) : // outputs (%0, %1)
|
166
|
+
"1"(dv) : // inputs (%2 == %1)
|
167
|
+
"memory", "cc" // clobbers
|
168
|
+
);
|
169
|
+
|
170
|
+
return r;
|
171
|
+
}
|
102
172
|
};
|
103
173
|
|
104
174
|
#endif
|
data/ext/quickfix/DOMDocument.h
CHANGED
@@ -26,9 +26,11 @@
|
|
26
26
|
#include <map>
|
27
27
|
#include <iostream>
|
28
28
|
#include <memory>
|
29
|
+
#include "Utility.h"
|
29
30
|
|
30
31
|
namespace FIX
|
31
32
|
{
|
33
|
+
#include "Utility.h"
|
32
34
|
/// Interface that represents attribute from underlying XML parser.
|
33
35
|
class DOMAttributes
|
34
36
|
{
|
@@ -40,7 +42,7 @@ namespace FIX
|
|
40
42
|
virtual bool get( const std::string&, std::string& ) = 0;
|
41
43
|
virtual map toMap() = 0;
|
42
44
|
};
|
43
|
-
typedef
|
45
|
+
typedef SmartPtr<DOMAttributes> DOMAttributesPtr;
|
44
46
|
|
45
47
|
/// Interface that represents node from underlying XML parser.
|
46
48
|
class DOMNode
|
@@ -48,13 +50,13 @@ namespace FIX
|
|
48
50
|
public:
|
49
51
|
virtual ~DOMNode() {}
|
50
52
|
|
51
|
-
virtual
|
52
|
-
virtual
|
53
|
-
virtual
|
53
|
+
virtual SmartPtr<DOMNode> getFirstChildNode() = 0;
|
54
|
+
virtual SmartPtr<DOMNode> getNextSiblingNode() = 0;
|
55
|
+
virtual SmartPtr<DOMAttributes> getAttributes() = 0;
|
54
56
|
virtual std::string getName() = 0;
|
55
57
|
virtual std::string getText() = 0;
|
56
58
|
};
|
57
|
-
typedef
|
59
|
+
typedef SmartPtr<DOMNode> DOMNodePtr;
|
58
60
|
|
59
61
|
/// Interface that represents document of underlying XML parser.
|
60
62
|
class DOMDocument
|
@@ -66,9 +68,9 @@ namespace FIX
|
|
66
68
|
virtual bool load( const std::string& ) = 0;
|
67
69
|
virtual bool xml( std::ostream& ) = 0;
|
68
70
|
|
69
|
-
virtual
|
71
|
+
virtual SmartPtr<DOMNode> getNode( const std::string& ) = 0;
|
70
72
|
};
|
71
|
-
typedef
|
73
|
+
typedef SmartPtr<DOMDocument> DOMDocumentPtr;
|
72
74
|
}
|
73
75
|
|
74
76
|
#endif
|
@@ -40,22 +40,21 @@ namespace FIX
|
|
40
40
|
{
|
41
41
|
DataDictionary::DataDictionary()
|
42
42
|
: m_hasVersion( false ), m_checkFieldsOutOfOrder( true ),
|
43
|
-
m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true )
|
43
|
+
m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ), m_allowUnknownMessageFields( false ), m_storeMsgFieldsOrder(false)
|
44
44
|
{}
|
45
45
|
|
46
|
-
DataDictionary::DataDictionary( std::istream& stream )
|
46
|
+
DataDictionary::DataDictionary( std::istream& stream, bool preserveMsgFldsOrder )
|
47
47
|
throw( ConfigError )
|
48
48
|
: m_hasVersion( false ), m_checkFieldsOutOfOrder( true ),
|
49
|
-
m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true )
|
49
|
+
m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ), m_allowUnknownMessageFields( false ), m_storeMsgFieldsOrder(preserveMsgFldsOrder)
|
50
50
|
{
|
51
51
|
readFromStream( stream );
|
52
52
|
}
|
53
53
|
|
54
|
-
DataDictionary::DataDictionary( const std::string& url )
|
54
|
+
DataDictionary::DataDictionary( const std::string& url, bool preserveMsgFldsOrder )
|
55
55
|
throw( ConfigError )
|
56
56
|
: m_hasVersion( false ), m_checkFieldsOutOfOrder( true ),
|
57
|
-
m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ),
|
58
|
-
m_orderedFieldsArray(0)
|
57
|
+
m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ), m_allowUnknownMessageFields( false ), m_storeMsgFieldsOrder(preserveMsgFldsOrder), m_orderedFieldsArray(0)
|
59
58
|
{
|
60
59
|
readFromURL( url );
|
61
60
|
}
|
@@ -83,7 +82,9 @@ DataDictionary& DataDictionary::operator=( const DataDictionary& rhs )
|
|
83
82
|
m_hasVersion = rhs.m_hasVersion;
|
84
83
|
m_checkFieldsOutOfOrder = rhs.m_checkFieldsOutOfOrder;
|
85
84
|
m_checkFieldsHaveValues = rhs.m_checkFieldsHaveValues;
|
85
|
+
m_storeMsgFieldsOrder = rhs.m_storeMsgFieldsOrder;
|
86
86
|
m_checkUserDefinedFields = rhs.m_checkUserDefinedFields;
|
87
|
+
m_allowUnknownMessageFields = rhs.m_allowUnknownMessageFields;
|
87
88
|
m_beginString = rhs.m_beginString;
|
88
89
|
m_messageFields = rhs.m_messageFields;
|
89
90
|
m_requiredFields = rhs.m_requiredFields;
|
@@ -99,6 +100,11 @@ DataDictionary& DataDictionary::operator=( const DataDictionary& rhs )
|
|
99
100
|
m_names = rhs.m_names;
|
100
101
|
m_valueNames = rhs.m_valueNames;
|
101
102
|
m_dataFields = rhs.m_dataFields;
|
103
|
+
m_headerOrderedFields = rhs.m_headerOrderedFields;
|
104
|
+
m_headerOrder = rhs.m_headerOrder;
|
105
|
+
m_trailerOrderedFields = rhs.m_trailerOrderedFields;
|
106
|
+
m_trailerOrder = rhs.m_trailerOrder;
|
107
|
+
m_messageOrderedFields = rhs.m_messageOrderedFields;
|
102
108
|
|
103
109
|
FieldToGroup::const_iterator i = rhs.m_groups.begin();
|
104
110
|
for ( ; i != rhs.m_groups.end(); ++i )
|
@@ -121,7 +127,15 @@ throw( FIX::Exception )
|
|
121
127
|
{
|
122
128
|
const Header& header = message.getHeader();
|
123
129
|
const BeginString& beginString = FIELD_GET_REF( header, BeginString );
|
130
|
+
#ifdef HAVE_EMX
|
131
|
+
const std::string & msgType = message.getSubMessageType();
|
132
|
+
if (msgType.empty())
|
133
|
+
{
|
134
|
+
throw InvalidMessageType("empty subMsgType, check Tag 9426/MESSAGE_ID");
|
135
|
+
}
|
136
|
+
#else
|
124
137
|
const MsgType& msgType = FIELD_GET_REF( header, MsgType );
|
138
|
+
#endif
|
125
139
|
if ( pSessionDD != 0 && pSessionDD->m_hasVersion )
|
126
140
|
{
|
127
141
|
if( pSessionDD->getVersion() != beginString )
|
@@ -160,11 +174,11 @@ void DataDictionary::iterate( const FieldMap& map, const MsgType& msgType ) cons
|
|
160
174
|
{
|
161
175
|
int lastField = 0;
|
162
176
|
|
163
|
-
FieldMap::
|
177
|
+
FieldMap::const_iterator i;
|
164
178
|
for ( i = map.begin(); i != map.end(); ++i )
|
165
179
|
{
|
166
|
-
const FieldBase& field = i
|
167
|
-
if( i != map.begin() && (field.
|
180
|
+
const FieldBase& field = (*i);
|
181
|
+
if( i != map.begin() && (field.getTag() == lastField) )
|
168
182
|
throw RepeatedTag( lastField );
|
169
183
|
checkHasValue( field );
|
170
184
|
|
@@ -184,14 +198,14 @@ void DataDictionary::iterate( const FieldMap& map, const MsgType& msgType ) cons
|
|
184
198
|
checkGroupCount( field, map, msgType );
|
185
199
|
}
|
186
200
|
}
|
187
|
-
lastField = field.
|
201
|
+
lastField = field.getTag();
|
188
202
|
}
|
189
203
|
}
|
190
204
|
|
191
205
|
void DataDictionary::readFromURL( const std::string& url )
|
192
206
|
throw( ConfigError )
|
193
207
|
{
|
194
|
-
DOMDocumentPtr pDoc
|
208
|
+
DOMDocumentPtr pDoc(new PUGIXML_DOMDocument());
|
195
209
|
|
196
210
|
if(!pDoc->load(url))
|
197
211
|
throw ConfigError(url + ": Could not parse data dictionary file");
|
@@ -209,7 +223,7 @@ throw( ConfigError )
|
|
209
223
|
void DataDictionary::readFromStream( std::istream& stream )
|
210
224
|
throw( ConfigError )
|
211
225
|
{
|
212
|
-
DOMDocumentPtr pDoc
|
226
|
+
DOMDocumentPtr pDoc(new PUGIXML_DOMDocument());
|
213
227
|
|
214
228
|
if(!pDoc->load(stream))
|
215
229
|
throw ConfigError("Could not parse data dictionary stream");
|
@@ -217,7 +231,7 @@ throw( ConfigError )
|
|
217
231
|
readFromDocument( pDoc );
|
218
232
|
}
|
219
233
|
|
220
|
-
void DataDictionary::readFromDocument( DOMDocumentPtr pDoc )
|
234
|
+
void DataDictionary::readFromDocument( const DOMDocumentPtr &pDoc )
|
221
235
|
throw( ConfigError )
|
222
236
|
{
|
223
237
|
// VERSION
|
@@ -441,6 +455,55 @@ message_order const& DataDictionary::getOrderedFields() const
|
|
441
455
|
return m_orderedFieldsArray;
|
442
456
|
}
|
443
457
|
|
458
|
+
message_order const& DataDictionary::getHeaderOrderedFields() const throw( ConfigError )
|
459
|
+
{
|
460
|
+
if( m_headerOrder ) return m_headerOrder;
|
461
|
+
|
462
|
+
if (m_headerOrderedFields.size() == 0)
|
463
|
+
throw ConfigError("<Header> does not have a stored message order");
|
464
|
+
|
465
|
+
int * tmp = new int[m_headerOrderedFields.size() + 1];
|
466
|
+
int * i = tmp;
|
467
|
+
|
468
|
+
OrderedFields::const_iterator iter;
|
469
|
+
for( iter = m_headerOrderedFields.begin(); iter != m_headerOrderedFields.end(); *(i++) = *(iter++) ) {}
|
470
|
+
*i = 0;
|
471
|
+
|
472
|
+
m_headerOrder = message_order(tmp);
|
473
|
+
delete [] tmp;
|
474
|
+
|
475
|
+
return m_headerOrder;
|
476
|
+
}
|
477
|
+
|
478
|
+
message_order const& DataDictionary::getTrailerOrderedFields() const throw( ConfigError )
|
479
|
+
{
|
480
|
+
if( m_trailerOrder ) return m_trailerOrder;
|
481
|
+
|
482
|
+
if (m_trailerOrderedFields.size() == 0)
|
483
|
+
throw ConfigError("<Trailer> does not have a stored message order");
|
484
|
+
|
485
|
+
int * tmp = new int[m_trailerOrderedFields.size() + 1];
|
486
|
+
int * i = tmp;
|
487
|
+
|
488
|
+
OrderedFields::const_iterator iter;
|
489
|
+
for( iter = m_trailerOrderedFields.begin(); iter != m_trailerOrderedFields.end(); *(i++) = *(iter++) ) {}
|
490
|
+
*i = 0;
|
491
|
+
|
492
|
+
m_trailerOrder = message_order(tmp);
|
493
|
+
delete [] tmp;
|
494
|
+
|
495
|
+
return m_trailerOrder;
|
496
|
+
}
|
497
|
+
|
498
|
+
const message_order &DataDictionary::getMessageOrderedFields(const std::string & msgType) const throw( ConfigError )
|
499
|
+
{
|
500
|
+
MsgTypeToOrderedFields::const_iterator iter = m_messageOrderedFields.find(msgType);
|
501
|
+
if (iter == m_messageOrderedFields.end())
|
502
|
+
throw ConfigError("<Message> " + msgType + " does not have a stored message order");
|
503
|
+
|
504
|
+
return iter->second.getMessageOrder();
|
505
|
+
}
|
506
|
+
|
444
507
|
int DataDictionary::lookupXMLFieldNumber( DOMDocument* pDoc, DOMNode* pNode ) const
|
445
508
|
{
|
446
509
|
DOMAttributesPtr attrs = pNode->getAttributes();
|
@@ -474,7 +537,7 @@ int DataDictionary::addXMLComponentFields( DOMDocument* pDoc, DOMNode* pNode,
|
|
474
537
|
DOMNodePtr pComponentNode =
|
475
538
|
pDoc->getNode("/fix/components/component[@name='" + name + "']");
|
476
539
|
if(pComponentNode.get() == 0)
|
477
|
-
throw ConfigError("Component not found");
|
540
|
+
throw ConfigError("Component not found: " + name);
|
478
541
|
|
479
542
|
DOMNodePtr pComponentFieldNode = pComponentNode->getFirstChildNode();
|
480
543
|
while(pComponentFieldNode.get())
|
@@ -54,6 +54,46 @@ class DataDictionary
|
|
54
54
|
typedef std::set < int > Fields;
|
55
55
|
typedef std::map < int, bool > NonBodyFields;
|
56
56
|
typedef std::vector< int > OrderedFields;
|
57
|
+
|
58
|
+
struct MessageFieldsOrderHolder
|
59
|
+
{
|
60
|
+
MessageFieldsOrderHolder()
|
61
|
+
{}
|
62
|
+
|
63
|
+
~MessageFieldsOrderHolder()
|
64
|
+
{}
|
65
|
+
|
66
|
+
void push_back(int field)
|
67
|
+
{
|
68
|
+
m_orderedFlds.push_back(field);
|
69
|
+
}
|
70
|
+
|
71
|
+
const message_order & getMessageOrder() const
|
72
|
+
{
|
73
|
+
if (m_msgOrder)
|
74
|
+
return m_msgOrder;
|
75
|
+
|
76
|
+
int * tmp = new int[m_orderedFlds.size() + 1];
|
77
|
+
int * i = tmp;
|
78
|
+
|
79
|
+
OrderedFields::const_iterator iter;
|
80
|
+
for( iter = m_orderedFlds.begin(); iter != m_orderedFlds.end(); *(i++) = *(iter++) ) {}
|
81
|
+
*i = 0;
|
82
|
+
|
83
|
+
m_msgOrder = message_order(tmp);
|
84
|
+
delete [] tmp;
|
85
|
+
|
86
|
+
return m_msgOrder;
|
87
|
+
}
|
88
|
+
|
89
|
+
private:
|
90
|
+
|
91
|
+
mutable message_order m_msgOrder;
|
92
|
+
OrderedFields m_orderedFlds;
|
93
|
+
};
|
94
|
+
|
95
|
+
typedef std::map<std::string, MessageFieldsOrderHolder > MsgTypeToOrderedFields;
|
96
|
+
|
57
97
|
typedef message_order OrderedFieldsArray;
|
58
98
|
typedef std::map < int, TYPE::Type > FieldTypes;
|
59
99
|
typedef std::set < std::string > Values;
|
@@ -72,15 +112,18 @@ class DataDictionary
|
|
72
112
|
public:
|
73
113
|
DataDictionary();
|
74
114
|
DataDictionary( const DataDictionary& copy );
|
75
|
-
DataDictionary(
|
76
|
-
DataDictionary(
|
115
|
+
DataDictionary(std::istream& stream , bool preserveMsgFldsOrder = false) throw( ConfigError );
|
116
|
+
DataDictionary(const std::string& url , bool preserveMsgFldsOrder = false) throw( ConfigError );
|
77
117
|
virtual ~DataDictionary();
|
78
118
|
|
79
119
|
void readFromURL( const std::string& url ) throw( ConfigError );
|
80
|
-
void readFromDocument( DOMDocumentPtr pDoc ) throw( ConfigError );
|
120
|
+
void readFromDocument( const DOMDocumentPtr &pDoc ) throw( ConfigError );
|
81
121
|
void readFromStream( std::istream& stream ) throw( ConfigError );
|
82
122
|
|
83
123
|
message_order const& getOrderedFields() const;
|
124
|
+
message_order const& getHeaderOrderedFields() const throw( ConfigError );
|
125
|
+
message_order const& getTrailerOrderedFields() const throw( ConfigError );
|
126
|
+
message_order const& getMessageOrderedFields(const std::string & msgType) const throw( ConfigError );
|
84
127
|
|
85
128
|
// storage functions
|
86
129
|
void setVersion( const std::string& beginString )
|
@@ -152,6 +195,11 @@ public:
|
|
152
195
|
|
153
196
|
void addMsgField( const std::string& msgType, int field )
|
154
197
|
{
|
198
|
+
if (m_storeMsgFieldsOrder)
|
199
|
+
{
|
200
|
+
m_messageOrderedFields[ msgType ].push_back(field);
|
201
|
+
}
|
202
|
+
|
155
203
|
m_messageFields[ msgType ].insert( field );
|
156
204
|
}
|
157
205
|
|
@@ -164,6 +212,11 @@ public:
|
|
164
212
|
|
165
213
|
void addHeaderField( int field, bool required )
|
166
214
|
{
|
215
|
+
if (m_storeMsgFieldsOrder)
|
216
|
+
{
|
217
|
+
m_headerOrderedFields.push_back(field);
|
218
|
+
}
|
219
|
+
|
167
220
|
m_headerFields[ field ] = required;
|
168
221
|
}
|
169
222
|
|
@@ -174,6 +227,11 @@ public:
|
|
174
227
|
|
175
228
|
void addTrailerField( int field, bool required )
|
176
229
|
{
|
230
|
+
if (m_storeMsgFieldsOrder)
|
231
|
+
{
|
232
|
+
m_trailerOrderedFields.push_back(field);
|
233
|
+
}
|
234
|
+
|
177
235
|
m_trailerFields[ field ] = required;
|
178
236
|
}
|
179
237
|
|
@@ -303,6 +361,12 @@ public:
|
|
303
361
|
{ m_checkFieldsHaveValues = value; }
|
304
362
|
void checkUserDefinedFields( bool value )
|
305
363
|
{ m_checkUserDefinedFields = value; }
|
364
|
+
void allowUnknownMsgFields( bool value )
|
365
|
+
{ m_allowUnknownMessageFields = value; }
|
366
|
+
void preserveMessageFieldsOrder( bool value )
|
367
|
+
{ m_storeMsgFieldsOrder = value; }
|
368
|
+
bool isMessageFieldsOrderPreserved() const
|
369
|
+
{ return m_storeMsgFieldsOrder; }
|
306
370
|
|
307
371
|
/// Validate a message.
|
308
372
|
static void validate( const Message& message,
|
@@ -330,7 +394,9 @@ private:
|
|
330
394
|
/// If we need to check for the tag in the dictionary
|
331
395
|
bool shouldCheckTag( const FieldBase& field ) const
|
332
396
|
{
|
333
|
-
if(
|
397
|
+
if( m_allowUnknownMessageFields && field.getTag() < FIELD::UserMin )
|
398
|
+
return false;
|
399
|
+
else if( !m_checkUserDefinedFields && field.getTag() >= FIELD::UserMin )
|
334
400
|
return false;
|
335
401
|
else
|
336
402
|
return true;
|
@@ -340,8 +406,8 @@ private:
|
|
340
406
|
void checkValidTagNumber( const FieldBase& field ) const
|
341
407
|
throw( InvalidTagNumber )
|
342
408
|
{
|
343
|
-
if( m_fields.find( field.
|
344
|
-
throw InvalidTagNumber( field.
|
409
|
+
if( m_fields.find( field.getTag() ) == m_fields.end() )
|
410
|
+
throw InvalidTagNumber( field.getTag() );
|
345
411
|
}
|
346
412
|
|
347
413
|
void checkValidFormat( const FieldBase& field ) const
|
@@ -350,7 +416,7 @@ private:
|
|
350
416
|
try
|
351
417
|
{
|
352
418
|
TYPE::Type type = TYPE::Unknown;
|
353
|
-
getFieldType( field.
|
419
|
+
getFieldType( field.getTag(), type );
|
354
420
|
switch ( type )
|
355
421
|
{
|
356
422
|
case TYPE::String:
|
@@ -417,17 +483,17 @@ private:
|
|
417
483
|
}
|
418
484
|
}
|
419
485
|
catch ( FieldConvertError& )
|
420
|
-
{ throw IncorrectDataFormat( field.
|
486
|
+
{ throw IncorrectDataFormat( field.getTag(), field.getString() ); }
|
421
487
|
}
|
422
488
|
|
423
489
|
void checkValue( const FieldBase& field ) const
|
424
490
|
throw( IncorrectTagValue )
|
425
491
|
{
|
426
|
-
if ( !hasFieldValue( field.
|
492
|
+
if ( !hasFieldValue( field.getTag() ) ) return ;
|
427
493
|
|
428
494
|
const std::string& value = field.getString();
|
429
|
-
if ( !isFieldValue( field.
|
430
|
-
throw IncorrectTagValue( field.
|
495
|
+
if ( !isFieldValue( field.getTag(), value ) )
|
496
|
+
throw IncorrectTagValue( field.getTag() );
|
431
497
|
}
|
432
498
|
|
433
499
|
/// Check if a field has a value.
|
@@ -435,7 +501,7 @@ private:
|
|
435
501
|
throw( NoTagValue )
|
436
502
|
{
|
437
503
|
if ( m_checkFieldsHaveValues && !field.getString().length() )
|
438
|
-
throw NoTagValue( field.
|
504
|
+
throw NoTagValue( field.getTag() );
|
439
505
|
}
|
440
506
|
|
441
507
|
/// Check if a field is in this message type.
|
@@ -443,8 +509,8 @@ private:
|
|
443
509
|
( const FieldBase& field, const MsgType& msgType ) const
|
444
510
|
throw( TagNotDefinedForMessage )
|
445
511
|
{
|
446
|
-
if ( !isMsgField( msgType, field.
|
447
|
-
throw TagNotDefinedForMessage( field.
|
512
|
+
if ( !isMsgField( msgType, field.getTag() ) )
|
513
|
+
throw TagNotDefinedForMessage( field.getTag() );
|
448
514
|
}
|
449
515
|
|
450
516
|
/// Check if group count matches number of groups in
|
@@ -452,7 +518,7 @@ private:
|
|
452
518
|
( const FieldBase& field, const FieldMap& fieldMap, const MsgType& msgType ) const
|
453
519
|
throw( RepeatingGroupCountMismatch )
|
454
520
|
{
|
455
|
-
int fieldNum = field.
|
521
|
+
int fieldNum = field.getTag();
|
456
522
|
if( isGroup(msgType, fieldNum) )
|
457
523
|
{
|
458
524
|
if( (int)fieldMap.groupCount(fieldNum)
|
@@ -492,7 +558,7 @@ private:
|
|
492
558
|
throw RequiredTagMissing( *iF );
|
493
559
|
}
|
494
560
|
|
495
|
-
FieldMap::
|
561
|
+
FieldMap::g_const_iterator groups;
|
496
562
|
for( groups = body.g_begin(); groups != body.g_end(); ++groups )
|
497
563
|
{
|
498
564
|
int delim;
|
@@ -517,6 +583,9 @@ private:
|
|
517
583
|
bool m_checkFieldsOutOfOrder;
|
518
584
|
bool m_checkFieldsHaveValues;
|
519
585
|
bool m_checkUserDefinedFields;
|
586
|
+
bool m_allowUnknownMessageFields;
|
587
|
+
bool m_storeMsgFieldsOrder;
|
588
|
+
|
520
589
|
BeginString m_beginString;
|
521
590
|
MsgTypeToField m_messageFields;
|
522
591
|
MsgTypeToField m_requiredFields;
|
@@ -533,6 +602,11 @@ private:
|
|
533
602
|
ValueToName m_valueNames;
|
534
603
|
FieldToGroup m_groups;
|
535
604
|
MsgFields m_dataFields;
|
605
|
+
OrderedFields m_headerOrderedFields;
|
606
|
+
mutable OrderedFieldsArray m_headerOrder;
|
607
|
+
OrderedFields m_trailerOrderedFields;
|
608
|
+
mutable OrderedFieldsArray m_trailerOrder;
|
609
|
+
MsgTypeToOrderedFields m_messageOrderedFields;
|
536
610
|
};
|
537
611
|
}
|
538
612
|
|