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
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
|
|