quickfix_ruby_ud 2.0.7-x86_64-linux
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 +7 -0
- data/ext/quickfix/Acceptor.cpp +257 -0
- data/ext/quickfix/Acceptor.h +127 -0
- data/ext/quickfix/Allocator.h +9 -0
- data/ext/quickfix/Application.h +137 -0
- data/ext/quickfix/DOMDocument.h +70 -0
- data/ext/quickfix/DataDictionary.cpp +679 -0
- data/ext/quickfix/DataDictionary.h +607 -0
- data/ext/quickfix/DataDictionaryProvider.cpp +66 -0
- data/ext/quickfix/DataDictionaryProvider.h +67 -0
- data/ext/quickfix/DatabaseConnectionID.h +98 -0
- data/ext/quickfix/DatabaseConnectionPool.h +84 -0
- data/ext/quickfix/Dictionary.cpp +157 -0
- data/ext/quickfix/Dictionary.h +89 -0
- data/ext/quickfix/Event.h +89 -0
- data/ext/quickfix/Except.h +39 -0
- data/ext/quickfix/Exceptions.h +257 -0
- data/ext/quickfix/Field.h +654 -0
- data/ext/quickfix/FieldConvertors.cpp +86 -0
- data/ext/quickfix/FieldConvertors.h +800 -0
- data/ext/quickfix/FieldMap.cpp +254 -0
- data/ext/quickfix/FieldMap.h +327 -0
- data/ext/quickfix/FieldNumbers.h +44 -0
- data/ext/quickfix/FieldTypes.cpp +62 -0
- data/ext/quickfix/FieldTypes.h +817 -0
- data/ext/quickfix/Fields.h +30 -0
- data/ext/quickfix/FileLog.cpp +176 -0
- data/ext/quickfix/FileLog.h +110 -0
- data/ext/quickfix/FileStore.cpp +369 -0
- data/ext/quickfix/FileStore.h +131 -0
- data/ext/quickfix/FixCommonFields.h +13 -0
- data/ext/quickfix/FixFieldNumbers.h +6132 -0
- data/ext/quickfix/FixFields.h +6133 -0
- data/ext/quickfix/FixValues.h +5790 -0
- data/ext/quickfix/Group.cpp +44 -0
- data/ext/quickfix/Group.h +78 -0
- data/ext/quickfix/HostDetailsProvider.cpp +79 -0
- data/ext/quickfix/HostDetailsProvider.h +44 -0
- data/ext/quickfix/HtmlBuilder.h +178 -0
- data/ext/quickfix/HttpConnection.cpp +914 -0
- data/ext/quickfix/HttpConnection.h +74 -0
- data/ext/quickfix/HttpMessage.cpp +229 -0
- data/ext/quickfix/HttpMessage.h +112 -0
- data/ext/quickfix/HttpParser.cpp +49 -0
- data/ext/quickfix/HttpParser.h +49 -0
- data/ext/quickfix/HttpServer.cpp +152 -0
- data/ext/quickfix/HttpServer.h +76 -0
- data/ext/quickfix/Initiator.cpp +310 -0
- data/ext/quickfix/Initiator.h +151 -0
- data/ext/quickfix/Log.cpp +71 -0
- data/ext/quickfix/Log.h +254 -0
- data/ext/quickfix/Message.cpp +617 -0
- data/ext/quickfix/Message.h +419 -0
- data/ext/quickfix/MessageCracker.h +171 -0
- data/ext/quickfix/MessageSorters.cpp +101 -0
- data/ext/quickfix/MessageSorters.h +185 -0
- data/ext/quickfix/MessageStore.cpp +182 -0
- data/ext/quickfix/MessageStore.h +164 -0
- data/ext/quickfix/Mutex.h +120 -0
- data/ext/quickfix/MySQLConnection.h +187 -0
- data/ext/quickfix/MySQLLog.cpp +262 -0
- data/ext/quickfix/MySQLLog.h +158 -0
- data/ext/quickfix/MySQLStore.cpp +323 -0
- data/ext/quickfix/MySQLStore.h +161 -0
- data/ext/quickfix/MySQLStubs.h +203 -0
- data/ext/quickfix/NullStore.cpp +40 -0
- data/ext/quickfix/NullStore.h +89 -0
- data/ext/quickfix/OdbcConnection.h +241 -0
- data/ext/quickfix/OdbcLog.cpp +230 -0
- data/ext/quickfix/OdbcLog.h +109 -0
- data/ext/quickfix/OdbcStore.cpp +313 -0
- data/ext/quickfix/OdbcStore.h +124 -0
- data/ext/quickfix/PUGIXML_DOMDocument.cpp +112 -0
- data/ext/quickfix/PUGIXML_DOMDocument.h +81 -0
- data/ext/quickfix/Parser.cpp +111 -0
- data/ext/quickfix/Parser.h +50 -0
- data/ext/quickfix/PostgreSQLConnection.h +163 -0
- data/ext/quickfix/PostgreSQLLog.cpp +263 -0
- data/ext/quickfix/PostgreSQLLog.h +157 -0
- data/ext/quickfix/PostgreSQLStore.cpp +327 -0
- data/ext/quickfix/PostgreSQLStore.h +160 -0
- data/ext/quickfix/PostgreSQLStubs.h +203 -0
- data/ext/quickfix/Queue.h +66 -0
- data/ext/quickfix/QuickfixRuby.cpp +131900 -0
- data/ext/quickfix/QuickfixRuby.h +56 -0
- data/ext/quickfix/Responder.h +41 -0
- data/ext/quickfix/SSLSocketAcceptor.cpp +409 -0
- data/ext/quickfix/SSLSocketAcceptor.h +186 -0
- data/ext/quickfix/SSLSocketConnection.cpp +434 -0
- data/ext/quickfix/SSLSocketConnection.h +221 -0
- data/ext/quickfix/SSLSocketInitiator.cpp +558 -0
- data/ext/quickfix/SSLSocketInitiator.h +203 -0
- data/ext/quickfix/SSLStubs.h +129 -0
- data/ext/quickfix/Session.cpp +1437 -0
- data/ext/quickfix/Session.h +343 -0
- data/ext/quickfix/SessionFactory.cpp +314 -0
- data/ext/quickfix/SessionFactory.h +84 -0
- data/ext/quickfix/SessionID.h +136 -0
- data/ext/quickfix/SessionSettings.cpp +165 -0
- data/ext/quickfix/SessionSettings.h +283 -0
- data/ext/quickfix/SessionState.h +260 -0
- data/ext/quickfix/Settings.cpp +160 -0
- data/ext/quickfix/Settings.h +56 -0
- data/ext/quickfix/SharedArray.h +274 -0
- data/ext/quickfix/SocketAcceptor.cpp +216 -0
- data/ext/quickfix/SocketAcceptor.h +77 -0
- data/ext/quickfix/SocketConnection.cpp +256 -0
- data/ext/quickfix/SocketConnection.h +102 -0
- data/ext/quickfix/SocketConnector.cpp +112 -0
- data/ext/quickfix/SocketConnector.h +76 -0
- data/ext/quickfix/SocketInitiator.cpp +241 -0
- data/ext/quickfix/SocketInitiator.h +76 -0
- data/ext/quickfix/SocketMonitor.h +26 -0
- data/ext/quickfix/SocketMonitor_UNIX.cpp +238 -0
- data/ext/quickfix/SocketMonitor_UNIX.h +101 -0
- data/ext/quickfix/SocketMonitor_WIN32.cpp +248 -0
- data/ext/quickfix/SocketMonitor_WIN32.h +99 -0
- data/ext/quickfix/SocketServer.cpp +163 -0
- data/ext/quickfix/SocketServer.h +100 -0
- data/ext/quickfix/ThreadedSSLSocketAcceptor.cpp +436 -0
- data/ext/quickfix/ThreadedSSLSocketAcceptor.h +209 -0
- data/ext/quickfix/ThreadedSSLSocketConnection.cpp +364 -0
- data/ext/quickfix/ThreadedSSLSocketConnection.h +191 -0
- data/ext/quickfix/ThreadedSSLSocketInitiator.cpp +434 -0
- data/ext/quickfix/ThreadedSSLSocketInitiator.h +193 -0
- data/ext/quickfix/ThreadedSocketAcceptor.cpp +242 -0
- data/ext/quickfix/ThreadedSocketAcceptor.h +95 -0
- data/ext/quickfix/ThreadedSocketConnection.cpp +227 -0
- data/ext/quickfix/ThreadedSocketConnection.h +89 -0
- data/ext/quickfix/ThreadedSocketInitiator.cpp +238 -0
- data/ext/quickfix/ThreadedSocketInitiator.h +78 -0
- data/ext/quickfix/TimeRange.cpp +227 -0
- data/ext/quickfix/TimeRange.h +215 -0
- data/ext/quickfix/Utility.cpp +639 -0
- data/ext/quickfix/Utility.h +255 -0
- data/ext/quickfix/UtilitySSL.cpp +1612 -0
- data/ext/quickfix/UtilitySSL.h +274 -0
- data/ext/quickfix/Values.h +63 -0
- data/ext/quickfix/config-all.h +10 -0
- data/ext/quickfix/config.h +10 -0
- data/ext/quickfix/config_unix.h +178 -0
- data/ext/quickfix/config_windows.h +0 -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 +374 -0
- data/ext/quickfix/extconf.rb +76 -0
- data/ext/quickfix/index.h +37 -0
- data/ext/quickfix/pugiconfig.hpp +77 -0
- data/ext/quickfix/pugixml.cpp +13237 -0
- data/ext/quickfix/pugixml.hpp +1516 -0
- data/ext/quickfix/scope_guard.hpp +215 -0
- data/ext/quickfix/stdint_msvc.h +254 -0
- data/ext/quickfix/strptime.h +7 -0
- data/lib/2.4/quickfix.so +0 -0
- data/lib/2.5/quickfix.so +0 -0
- data/lib/2.6/quickfix.so +0 -0
- data/lib/2.7/quickfix.so +0 -0
- data/lib/3.0/quickfix.so +0 -0
- data/lib/3.1/quickfix.so +0 -0
- data/lib/3.2/quickfix.so +0 -0
- data/lib/3.3/quickfix.so +0 -0
- data/lib/3.4/quickfix.so +0 -0
- data/lib/quickfix40.rb +274 -0
- data/lib/quickfix41.rb +351 -0
- data/lib/quickfix42.rb +1184 -0
- data/lib/quickfix43.rb +3504 -0
- data/lib/quickfix44.rb +14040 -0
- data/lib/quickfix50.rb +20051 -0
- data/lib/quickfix50sp1.rb +23596 -0
- data/lib/quickfix50sp2.rb +412444 -0
- data/lib/quickfix_fields.rb +79393 -0
- data/lib/quickfix_ruby.rb +82 -0
- data/lib/quickfixt11.rb +65 -0
- data/spec/FIX40.xml +862 -0
- data/spec/FIX41.xml +1282 -0
- data/spec/FIX42.xml +2743 -0
- data/spec/FIX43.xml +4230 -0
- data/spec/FIX44.xml +6600 -0
- data/spec/FIX50.xml +8142 -0
- data/spec/FIX50SP1.xml +9506 -0
- data/spec/FIX50SP2.xml +26069 -0
- data/spec/FIXT11.xml +252 -0
- data/test/DataDictionaryTestCase.rb +268 -0
- data/test/DictionaryTestCase.rb +112 -0
- data/test/FieldBaseTestCase.rb +24 -0
- data/test/MessageStoreTestCase.rb +19 -0
- data/test/MessageTestCase.rb +368 -0
- data/test/SessionSettingsTestCase.rb +41 -0
- metadata +247 -0
@@ -0,0 +1,679 @@
|
|
1
|
+
/****************************************************************************
|
2
|
+
** Copyright (c) 2001-2014
|
3
|
+
**
|
4
|
+
** This file is part of the QuickFIX FIX Engine
|
5
|
+
**
|
6
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
7
|
+
** license as defined by quickfixengine.org and appearing in the file
|
8
|
+
** LICENSE included in the packaging of this file.
|
9
|
+
**
|
10
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
11
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
12
|
+
**
|
13
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
14
|
+
**
|
15
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
16
|
+
** not clear to you.
|
17
|
+
**
|
18
|
+
****************************************************************************/
|
19
|
+
|
20
|
+
#ifdef _MSC_VER
|
21
|
+
#include "stdafx.h"
|
22
|
+
#else
|
23
|
+
#include "config.h"
|
24
|
+
#endif
|
25
|
+
|
26
|
+
#include "DataDictionary.h"
|
27
|
+
#include "Message.h"
|
28
|
+
#include <fstream>
|
29
|
+
#include <memory>
|
30
|
+
|
31
|
+
#include "PUGIXML_DOMDocument.h"
|
32
|
+
|
33
|
+
#ifdef _MSC_VER
|
34
|
+
#define RESET_AUTO_PTR(OLD, NEW) OLD = NEW;
|
35
|
+
#else
|
36
|
+
#define RESET_AUTO_PTR(OLD, NEW) OLD.reset(NEW.release());
|
37
|
+
#endif
|
38
|
+
|
39
|
+
namespace FIX {
|
40
|
+
DataDictionary::DataDictionary()
|
41
|
+
: m_hasVersion(false),
|
42
|
+
m_checkFieldsOutOfOrder(true),
|
43
|
+
m_checkFieldsHaveValues(true),
|
44
|
+
m_checkUserDefinedFields(true),
|
45
|
+
m_allowUnknownMessageFields(false),
|
46
|
+
m_storeMsgFieldsOrder(false) {}
|
47
|
+
|
48
|
+
DataDictionary::DataDictionary(std::istream &stream, bool preserveMsgFldsOrder) EXCEPT(ConfigError)
|
49
|
+
: m_hasVersion(false),
|
50
|
+
m_checkFieldsOutOfOrder(true),
|
51
|
+
m_checkFieldsHaveValues(true),
|
52
|
+
m_checkUserDefinedFields(true),
|
53
|
+
m_allowUnknownMessageFields(false),
|
54
|
+
m_storeMsgFieldsOrder(preserveMsgFldsOrder) {
|
55
|
+
readFromStream(stream);
|
56
|
+
}
|
57
|
+
|
58
|
+
DataDictionary::DataDictionary(const std::string &url, bool preserveMsgFldsOrder) EXCEPT(ConfigError)
|
59
|
+
: m_hasVersion(false),
|
60
|
+
m_checkFieldsOutOfOrder(true),
|
61
|
+
m_checkFieldsHaveValues(true),
|
62
|
+
m_checkUserDefinedFields(true),
|
63
|
+
m_allowUnknownMessageFields(false),
|
64
|
+
m_storeMsgFieldsOrder(preserveMsgFldsOrder),
|
65
|
+
m_orderedFieldsArray(0) {
|
66
|
+
readFromURL(url);
|
67
|
+
}
|
68
|
+
|
69
|
+
DataDictionary::DataDictionary(const DataDictionary ©) { *this = copy; }
|
70
|
+
|
71
|
+
DataDictionary::~DataDictionary() {
|
72
|
+
FieldToGroup::iterator i;
|
73
|
+
for (i = m_groups.begin(); i != m_groups.end(); ++i) {
|
74
|
+
const FieldPresenceMap &presenceMap = i->second;
|
75
|
+
|
76
|
+
FieldPresenceMap::const_iterator iter = presenceMap.begin();
|
77
|
+
for (; iter != presenceMap.end(); ++iter) {
|
78
|
+
delete iter->second.second;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
DataDictionary &DataDictionary::operator=(const DataDictionary &rhs) {
|
84
|
+
m_hasVersion = rhs.m_hasVersion;
|
85
|
+
m_checkFieldsOutOfOrder = rhs.m_checkFieldsOutOfOrder;
|
86
|
+
m_checkFieldsHaveValues = rhs.m_checkFieldsHaveValues;
|
87
|
+
m_storeMsgFieldsOrder = rhs.m_storeMsgFieldsOrder;
|
88
|
+
m_checkUserDefinedFields = rhs.m_checkUserDefinedFields;
|
89
|
+
m_allowUnknownMessageFields = rhs.m_allowUnknownMessageFields;
|
90
|
+
m_beginString = rhs.m_beginString;
|
91
|
+
m_messageFields = rhs.m_messageFields;
|
92
|
+
m_requiredFields = rhs.m_requiredFields;
|
93
|
+
m_messages = rhs.m_messages;
|
94
|
+
m_fields = rhs.m_fields;
|
95
|
+
m_orderedFields = rhs.m_orderedFields;
|
96
|
+
m_orderedFieldsArray = rhs.m_orderedFieldsArray;
|
97
|
+
m_headerFields = rhs.m_headerFields;
|
98
|
+
m_trailerFields = rhs.m_trailerFields;
|
99
|
+
m_fieldTypes = rhs.m_fieldTypes;
|
100
|
+
m_fieldValues = rhs.m_fieldValues;
|
101
|
+
m_fieldNames = rhs.m_fieldNames;
|
102
|
+
m_names = rhs.m_names;
|
103
|
+
m_valueNames = rhs.m_valueNames;
|
104
|
+
m_dataFields = rhs.m_dataFields;
|
105
|
+
m_headerOrderedFields = rhs.m_headerOrderedFields;
|
106
|
+
m_headerOrder = rhs.m_headerOrder;
|
107
|
+
m_trailerOrderedFields = rhs.m_trailerOrderedFields;
|
108
|
+
m_trailerOrder = rhs.m_trailerOrder;
|
109
|
+
m_messageOrderedFields = rhs.m_messageOrderedFields;
|
110
|
+
|
111
|
+
FieldToGroup::const_iterator i = rhs.m_groups.begin();
|
112
|
+
for (; i != rhs.m_groups.end(); ++i) {
|
113
|
+
const FieldPresenceMap &presenceMap = i->second;
|
114
|
+
|
115
|
+
FieldPresenceMap::const_iterator iter = presenceMap.begin();
|
116
|
+
for (; iter != presenceMap.end(); ++iter) {
|
117
|
+
addGroup(iter->first, i->first, iter->second.first, *iter->second.second);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
return *this;
|
121
|
+
}
|
122
|
+
|
123
|
+
void DataDictionary::validate(
|
124
|
+
const Message &message,
|
125
|
+
const DataDictionary *const pSessionDD,
|
126
|
+
const DataDictionary *const pAppDD) EXCEPT(FIX::Exception) {
|
127
|
+
const Header &header = message.getHeader();
|
128
|
+
const BeginString &beginString = FIELD_GET_REF(header, BeginString);
|
129
|
+
const MsgType &msgType = FIELD_GET_REF(header, MsgType);
|
130
|
+
|
131
|
+
if (pSessionDD != 0 && pSessionDD->m_hasVersion) {
|
132
|
+
if (pSessionDD->getVersion() != beginString) {
|
133
|
+
throw UnsupportedVersion();
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
int field = 0;
|
138
|
+
if ((pSessionDD != 0 && pSessionDD->m_checkFieldsOutOfOrder) || (pAppDD != 0 && pAppDD->m_checkFieldsOutOfOrder)) {
|
139
|
+
if (!message.hasValidStructure(field)) {
|
140
|
+
throw TagOutOfOrder(field);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
if (pAppDD != 0 && pAppDD->m_hasVersion) {
|
145
|
+
pAppDD->checkMsgType(msgType);
|
146
|
+
pAppDD->checkHasRequired(message.getHeader(), message, message.getTrailer(), msgType);
|
147
|
+
}
|
148
|
+
|
149
|
+
if (pSessionDD != 0) {
|
150
|
+
pSessionDD->iterate(message.getHeader(), msgType);
|
151
|
+
pSessionDD->iterate(message.getTrailer(), msgType);
|
152
|
+
}
|
153
|
+
|
154
|
+
if (pAppDD != 0) {
|
155
|
+
pAppDD->iterate(message, msgType);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
void DataDictionary::iterate(const FieldMap &map, const MsgType &msgType) const {
|
160
|
+
int lastField = 0;
|
161
|
+
|
162
|
+
FieldMap::const_iterator i;
|
163
|
+
for (i = map.begin(); i != map.end(); ++i) {
|
164
|
+
const FieldBase &field = (*i);
|
165
|
+
if (i != map.begin() && (field.getTag() == lastField)) {
|
166
|
+
throw RepeatedTag(lastField);
|
167
|
+
}
|
168
|
+
checkHasValue(field);
|
169
|
+
|
170
|
+
if (m_hasVersion) {
|
171
|
+
checkValidFormat(field);
|
172
|
+
checkValue(field);
|
173
|
+
}
|
174
|
+
|
175
|
+
if (m_beginString.getValue().length() && shouldCheckTag(field)) {
|
176
|
+
checkValidTagNumber(field);
|
177
|
+
if (!Message::isHeaderField(field, this) && !Message::isTrailerField(field, this)) {
|
178
|
+
checkIsInMessage(field, msgType);
|
179
|
+
checkGroupCount(field, map, msgType);
|
180
|
+
}
|
181
|
+
}
|
182
|
+
lastField = field.getTag();
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
186
|
+
void DataDictionary::readFromURL(const std::string &url) EXCEPT(ConfigError) {
|
187
|
+
DOMDocumentPtr pDoc(new PUGIXML_DOMDocument());
|
188
|
+
|
189
|
+
if (!pDoc->load(url)) {
|
190
|
+
throw ConfigError(url + ": Could not parse data dictionary file");
|
191
|
+
}
|
192
|
+
|
193
|
+
try {
|
194
|
+
readFromDocument(pDoc);
|
195
|
+
} catch (ConfigError &e) {
|
196
|
+
throw ConfigError(url + ": " + e.what());
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
void DataDictionary::readFromStream(std::istream &stream) EXCEPT(ConfigError) {
|
201
|
+
DOMDocumentPtr pDoc(new PUGIXML_DOMDocument());
|
202
|
+
|
203
|
+
if (!pDoc->load(stream)) {
|
204
|
+
throw ConfigError("Could not parse data dictionary stream");
|
205
|
+
}
|
206
|
+
|
207
|
+
readFromDocument(pDoc);
|
208
|
+
}
|
209
|
+
|
210
|
+
void DataDictionary::readFromDocument(const DOMDocumentPtr &pDoc) EXCEPT(ConfigError) {
|
211
|
+
// VERSION
|
212
|
+
DOMNodePtr pFixNode = pDoc->getNode("/fix");
|
213
|
+
if (!pFixNode.get()) {
|
214
|
+
throw ConfigError("Could not parse data dictionary file"
|
215
|
+
", or no <fix> node found at root");
|
216
|
+
}
|
217
|
+
DOMAttributesPtr attrs = pFixNode->getAttributes();
|
218
|
+
std::string type = "FIX";
|
219
|
+
if (attrs->get("type", type)) {
|
220
|
+
if (type != "FIX" && type != "FIXT") {
|
221
|
+
throw ConfigError("type attribute must be FIX or FIXT");
|
222
|
+
}
|
223
|
+
}
|
224
|
+
std::string major;
|
225
|
+
if (!attrs->get("major", major)) {
|
226
|
+
throw ConfigError("major attribute not found on <fix>");
|
227
|
+
}
|
228
|
+
std::string minor;
|
229
|
+
if (!attrs->get("minor", minor)) {
|
230
|
+
throw ConfigError("minor attribute not found on <fix>");
|
231
|
+
}
|
232
|
+
setVersion(type + "." + major + "." + minor);
|
233
|
+
|
234
|
+
// FIELDS
|
235
|
+
DOMNodePtr pFieldsNode = pDoc->getNode("/fix/fields");
|
236
|
+
if (!pFieldsNode.get()) {
|
237
|
+
throw ConfigError("<fields> section not found in data dictionary");
|
238
|
+
}
|
239
|
+
|
240
|
+
DOMNodePtr pFieldNode = pFieldsNode->getFirstChildNode();
|
241
|
+
if (!pFieldNode.get()) {
|
242
|
+
throw ConfigError("No fields defined");
|
243
|
+
}
|
244
|
+
|
245
|
+
while (pFieldNode.get()) {
|
246
|
+
if (pFieldNode->getName() == "field") {
|
247
|
+
DOMAttributesPtr attrs = pFieldNode->getAttributes();
|
248
|
+
std::string name;
|
249
|
+
if (!attrs->get("name", name)) {
|
250
|
+
throw ConfigError("<field> does not have a name attribute");
|
251
|
+
}
|
252
|
+
std::string number;
|
253
|
+
if (!attrs->get("number", number)) {
|
254
|
+
throw ConfigError("<field> " + name + " does not have a number attribute");
|
255
|
+
}
|
256
|
+
int num = atoi(number.c_str());
|
257
|
+
std::string type;
|
258
|
+
if (!attrs->get("type", type)) {
|
259
|
+
throw ConfigError("<field> " + name + " does not have a type attribute");
|
260
|
+
}
|
261
|
+
addField(num);
|
262
|
+
addFieldType(num, XMLTypeToType(type));
|
263
|
+
addFieldName(num, name);
|
264
|
+
|
265
|
+
DOMNodePtr pFieldValueNode = pFieldNode->getFirstChildNode();
|
266
|
+
while (pFieldValueNode.get()) {
|
267
|
+
if (pFieldValueNode->getName() == "value") {
|
268
|
+
DOMAttributesPtr attrs = pFieldValueNode->getAttributes();
|
269
|
+
std::string enumeration;
|
270
|
+
if (!attrs->get("enum", enumeration)) {
|
271
|
+
throw ConfigError("<value> does not have enum attribute in field " + name);
|
272
|
+
}
|
273
|
+
addFieldValue(num, enumeration);
|
274
|
+
std::string description;
|
275
|
+
if (attrs->get("description", description)) {
|
276
|
+
addValueName(num, enumeration, description);
|
277
|
+
}
|
278
|
+
}
|
279
|
+
RESET_AUTO_PTR(pFieldValueNode, pFieldValueNode->getNextSiblingNode());
|
280
|
+
}
|
281
|
+
}
|
282
|
+
RESET_AUTO_PTR(pFieldNode, pFieldNode->getNextSiblingNode());
|
283
|
+
}
|
284
|
+
|
285
|
+
// HEADER
|
286
|
+
if (type == "FIXT" || (type == "FIX" && major < "5")) {
|
287
|
+
DOMNodePtr pHeaderNode = pDoc->getNode("/fix/header");
|
288
|
+
if (!pHeaderNode.get()) {
|
289
|
+
throw ConfigError("<header> section not found in data dictionary");
|
290
|
+
}
|
291
|
+
|
292
|
+
DOMNodePtr pHeaderFieldNode = pHeaderNode->getFirstChildNode();
|
293
|
+
if (!pHeaderFieldNode.get()) {
|
294
|
+
throw ConfigError("No header fields defined");
|
295
|
+
}
|
296
|
+
|
297
|
+
while (pHeaderFieldNode.get()) {
|
298
|
+
if (pHeaderFieldNode->getName() == "field" || pHeaderFieldNode->getName() == "group") {
|
299
|
+
DOMAttributesPtr attrs = pHeaderFieldNode->getAttributes();
|
300
|
+
std::string name;
|
301
|
+
if (!attrs->get("name", name)) {
|
302
|
+
throw ConfigError("<field> does not have a name attribute");
|
303
|
+
}
|
304
|
+
std::string required;
|
305
|
+
attrs->get("required", required);
|
306
|
+
bool isRequired = (required == "Y" || required == "y");
|
307
|
+
addHeaderField(lookupXMLFieldNumber(pDoc.get(), name), isRequired);
|
308
|
+
}
|
309
|
+
if (pHeaderFieldNode->getName() == "group") {
|
310
|
+
DOMAttributesPtr attrs = pHeaderFieldNode->getAttributes();
|
311
|
+
std::string required;
|
312
|
+
attrs->get("required", required);
|
313
|
+
bool isRequired = (required == "Y" || required == "y");
|
314
|
+
addXMLGroup(pDoc.get(), pHeaderFieldNode.get(), "_header_", *this, isRequired);
|
315
|
+
}
|
316
|
+
|
317
|
+
RESET_AUTO_PTR(pHeaderFieldNode, pHeaderFieldNode->getNextSiblingNode());
|
318
|
+
}
|
319
|
+
}
|
320
|
+
|
321
|
+
// TRAILER
|
322
|
+
if (type == "FIXT" || (type == "FIX" && major < "5")) {
|
323
|
+
DOMNodePtr pTrailerNode = pDoc->getNode("/fix/trailer");
|
324
|
+
if (!pTrailerNode.get()) {
|
325
|
+
throw ConfigError("<trailer> section not found in data dictionary");
|
326
|
+
}
|
327
|
+
|
328
|
+
DOMNodePtr pTrailerFieldNode = pTrailerNode->getFirstChildNode();
|
329
|
+
if (!pTrailerFieldNode.get()) {
|
330
|
+
throw ConfigError("No trailer fields defined");
|
331
|
+
}
|
332
|
+
|
333
|
+
while (pTrailerFieldNode.get()) {
|
334
|
+
if (pTrailerFieldNode->getName() == "field" || pTrailerFieldNode->getName() == "group") {
|
335
|
+
DOMAttributesPtr attrs = pTrailerFieldNode->getAttributes();
|
336
|
+
std::string name;
|
337
|
+
if (!attrs->get("name", name)) {
|
338
|
+
throw ConfigError("<field> does not have a name attribute");
|
339
|
+
}
|
340
|
+
std::string required;
|
341
|
+
attrs->get("required", required);
|
342
|
+
bool isRequired = (required == "Y" || required == "y");
|
343
|
+
addTrailerField(lookupXMLFieldNumber(pDoc.get(), name), isRequired);
|
344
|
+
}
|
345
|
+
if (pTrailerFieldNode->getName() == "group") {
|
346
|
+
DOMAttributesPtr attrs = pTrailerFieldNode->getAttributes();
|
347
|
+
std::string required;
|
348
|
+
attrs->get("required", required);
|
349
|
+
bool isRequired = (required == "Y" || required == "y");
|
350
|
+
addXMLGroup(pDoc.get(), pTrailerFieldNode.get(), "_trailer_", *this, isRequired);
|
351
|
+
}
|
352
|
+
|
353
|
+
RESET_AUTO_PTR(pTrailerFieldNode, pTrailerFieldNode->getNextSiblingNode());
|
354
|
+
}
|
355
|
+
}
|
356
|
+
|
357
|
+
// MSGTYPE
|
358
|
+
DOMNodePtr pMessagesNode = pDoc->getNode("/fix/messages");
|
359
|
+
if (!pMessagesNode.get()) {
|
360
|
+
throw ConfigError("<messages> section not found in data dictionary");
|
361
|
+
}
|
362
|
+
|
363
|
+
DOMNodePtr pMessageNode = pMessagesNode->getFirstChildNode();
|
364
|
+
if (!pMessageNode.get()) {
|
365
|
+
throw ConfigError("No messages defined");
|
366
|
+
}
|
367
|
+
|
368
|
+
while (pMessageNode.get()) {
|
369
|
+
if (pMessageNode->getName() == "message") {
|
370
|
+
DOMAttributesPtr attrs = pMessageNode->getAttributes();
|
371
|
+
std::string msgtype;
|
372
|
+
if (!attrs->get("msgtype", msgtype)) {
|
373
|
+
throw ConfigError("<message> does not have a msgtype attribute");
|
374
|
+
}
|
375
|
+
addMsgType(msgtype);
|
376
|
+
|
377
|
+
std::string name;
|
378
|
+
if (attrs->get("name", name)) {
|
379
|
+
addValueName(35, msgtype, name);
|
380
|
+
}
|
381
|
+
|
382
|
+
DOMNodePtr pMessageFieldNode = pMessageNode->getFirstChildNode();
|
383
|
+
while (pMessageFieldNode.get()) {
|
384
|
+
if (pMessageFieldNode->getName() == "field" || pMessageFieldNode->getName() == "group") {
|
385
|
+
DOMAttributesPtr attrs = pMessageFieldNode->getAttributes();
|
386
|
+
std::string name;
|
387
|
+
if (!attrs->get("name", name)) {
|
388
|
+
throw ConfigError("<field> does not have a name attribute");
|
389
|
+
}
|
390
|
+
int num = lookupXMLFieldNumber(pDoc.get(), name);
|
391
|
+
addMsgField(msgtype, num);
|
392
|
+
|
393
|
+
std::string required;
|
394
|
+
if (attrs->get("required", required) && (required == "Y" || required == "y")) {
|
395
|
+
addRequiredField(msgtype, num);
|
396
|
+
}
|
397
|
+
} else if (pMessageFieldNode->getName() == "component") {
|
398
|
+
DOMAttributesPtr attrs = pMessageFieldNode->getAttributes();
|
399
|
+
std::string required;
|
400
|
+
attrs->get("required", required);
|
401
|
+
bool isRequired = (required == "Y" || required == "y");
|
402
|
+
addXMLComponentFields(pDoc.get(), pMessageFieldNode.get(), msgtype, *this, isRequired);
|
403
|
+
}
|
404
|
+
if (pMessageFieldNode->getName() == "group") {
|
405
|
+
DOMAttributesPtr attrs = pMessageFieldNode->getAttributes();
|
406
|
+
std::string required;
|
407
|
+
attrs->get("required", required);
|
408
|
+
bool isRequired = (required == "Y" || required == "y");
|
409
|
+
addXMLGroup(pDoc.get(), pMessageFieldNode.get(), msgtype, *this, isRequired);
|
410
|
+
}
|
411
|
+
RESET_AUTO_PTR(pMessageFieldNode, pMessageFieldNode->getNextSiblingNode());
|
412
|
+
}
|
413
|
+
}
|
414
|
+
RESET_AUTO_PTR(pMessageNode, pMessageNode->getNextSiblingNode());
|
415
|
+
}
|
416
|
+
}
|
417
|
+
|
418
|
+
message_order const &DataDictionary::getOrderedFields() const {
|
419
|
+
if (m_orderedFieldsArray) {
|
420
|
+
return m_orderedFieldsArray;
|
421
|
+
}
|
422
|
+
|
423
|
+
return m_orderedFieldsArray = message_order(m_orderedFields.data(), m_orderedFields.size());
|
424
|
+
}
|
425
|
+
|
426
|
+
message_order const &DataDictionary::getHeaderOrderedFields() const EXCEPT(ConfigError) {
|
427
|
+
if (m_headerOrder) {
|
428
|
+
return m_headerOrder;
|
429
|
+
}
|
430
|
+
|
431
|
+
if (m_headerOrderedFields.size() == 0) {
|
432
|
+
throw ConfigError("<Header> does not have a stored message order");
|
433
|
+
}
|
434
|
+
|
435
|
+
return m_headerOrder = message_order(m_headerOrderedFields.data(), m_headerOrderedFields.size());
|
436
|
+
}
|
437
|
+
|
438
|
+
message_order const &DataDictionary::getTrailerOrderedFields() const EXCEPT(ConfigError) {
|
439
|
+
if (m_trailerOrder) {
|
440
|
+
return m_trailerOrder;
|
441
|
+
}
|
442
|
+
|
443
|
+
if (m_trailerOrderedFields.size() == 0) {
|
444
|
+
throw ConfigError("<Trailer> does not have a stored message order");
|
445
|
+
}
|
446
|
+
|
447
|
+
return m_trailerOrder = message_order(m_trailerOrderedFields.data(), m_trailerOrderedFields.size());
|
448
|
+
}
|
449
|
+
|
450
|
+
const message_order &DataDictionary::getMessageOrderedFields(const std::string &msgType) const EXCEPT(ConfigError) {
|
451
|
+
MsgTypeToOrderedFields::const_iterator iter = m_messageOrderedFields.find(msgType);
|
452
|
+
if (iter == m_messageOrderedFields.end()) {
|
453
|
+
throw ConfigError("<Message> " + msgType + " does not have a stored message order");
|
454
|
+
}
|
455
|
+
|
456
|
+
return iter->second.getMessageOrder();
|
457
|
+
}
|
458
|
+
|
459
|
+
int DataDictionary::lookupXMLFieldNumber(DOMDocument *pDoc, DOMNode *pNode) const {
|
460
|
+
DOMAttributesPtr attrs = pNode->getAttributes();
|
461
|
+
std::string name;
|
462
|
+
if (!attrs->get("name", name)) {
|
463
|
+
throw ConfigError("No name given to field");
|
464
|
+
}
|
465
|
+
return lookupXMLFieldNumber(pDoc, name);
|
466
|
+
}
|
467
|
+
|
468
|
+
int DataDictionary::lookupXMLFieldNumber(DOMDocument *pDoc, const std::string &name) const {
|
469
|
+
NameToField::const_iterator i = m_names.find(name);
|
470
|
+
if (i == m_names.end()) {
|
471
|
+
throw ConfigError("Field " + name + " not defined in fields section");
|
472
|
+
}
|
473
|
+
return i->second;
|
474
|
+
}
|
475
|
+
|
476
|
+
int DataDictionary::addXMLComponentFields(
|
477
|
+
DOMDocument *pDoc,
|
478
|
+
DOMNode *pNode,
|
479
|
+
const std::string &msgtype,
|
480
|
+
DataDictionary &DD,
|
481
|
+
bool componentRequired) {
|
482
|
+
int firstField = 0;
|
483
|
+
|
484
|
+
DOMAttributesPtr attrs = pNode->getAttributes();
|
485
|
+
std::string name;
|
486
|
+
if (!attrs->get("name", name)) {
|
487
|
+
throw ConfigError("No name given to component");
|
488
|
+
}
|
489
|
+
|
490
|
+
DOMNodePtr pComponentNode = pDoc->getNode("/fix/components/component[@name='" + name + "']");
|
491
|
+
if (pComponentNode.get() == 0) {
|
492
|
+
throw ConfigError("Component not found: " + name);
|
493
|
+
}
|
494
|
+
|
495
|
+
DOMNodePtr pComponentFieldNode = pComponentNode->getFirstChildNode();
|
496
|
+
while (pComponentFieldNode.get()) {
|
497
|
+
if (pComponentFieldNode->getName() == "field" || pComponentFieldNode->getName() == "group") {
|
498
|
+
DOMAttributesPtr attrs = pComponentFieldNode->getAttributes();
|
499
|
+
std::string name;
|
500
|
+
if (!attrs->get("name", name)) {
|
501
|
+
throw ConfigError("No name given to field");
|
502
|
+
}
|
503
|
+
int field = lookupXMLFieldNumber(pDoc, name);
|
504
|
+
if (firstField == 0) {
|
505
|
+
firstField = field;
|
506
|
+
}
|
507
|
+
|
508
|
+
std::string required;
|
509
|
+
if (attrs->get("required", required) && (required == "Y" || required == "y") && componentRequired) {
|
510
|
+
addRequiredField(msgtype, field);
|
511
|
+
}
|
512
|
+
|
513
|
+
DD.addField(field);
|
514
|
+
DD.addMsgField(msgtype, field);
|
515
|
+
}
|
516
|
+
if (pComponentFieldNode->getName() == "component") {
|
517
|
+
DOMAttributesPtr attrs = pComponentFieldNode->getAttributes();
|
518
|
+
std::string required;
|
519
|
+
attrs->get("required", required);
|
520
|
+
bool isRequired = (required == "Y" || required == "y");
|
521
|
+
addXMLComponentFields(pDoc, pComponentFieldNode.get(), msgtype, DD, isRequired);
|
522
|
+
}
|
523
|
+
if (pComponentFieldNode->getName() == "group") {
|
524
|
+
DOMAttributesPtr attrs = pComponentFieldNode->getAttributes();
|
525
|
+
std::string required;
|
526
|
+
attrs->get("required", required);
|
527
|
+
bool isRequired = (required == "Y" || required == "y");
|
528
|
+
addXMLGroup(pDoc, pComponentFieldNode.get(), msgtype, DD, isRequired);
|
529
|
+
}
|
530
|
+
RESET_AUTO_PTR(pComponentFieldNode, pComponentFieldNode->getNextSiblingNode());
|
531
|
+
}
|
532
|
+
return firstField;
|
533
|
+
}
|
534
|
+
|
535
|
+
void DataDictionary::addXMLGroup(
|
536
|
+
DOMDocument *pDoc,
|
537
|
+
DOMNode *pNode,
|
538
|
+
const std::string &msgtype,
|
539
|
+
DataDictionary &DD,
|
540
|
+
bool groupRequired) {
|
541
|
+
DOMAttributesPtr attrs = pNode->getAttributes();
|
542
|
+
std::string name;
|
543
|
+
if (!attrs->get("name", name)) {
|
544
|
+
throw ConfigError("No name given to group");
|
545
|
+
}
|
546
|
+
int group = lookupXMLFieldNumber(pDoc, name);
|
547
|
+
int delim = 0;
|
548
|
+
int field = 0;
|
549
|
+
DataDictionary groupDD;
|
550
|
+
DOMNodePtr node = pNode->getFirstChildNode();
|
551
|
+
while (node.get()) {
|
552
|
+
if (node->getName() == "field") {
|
553
|
+
field = lookupXMLFieldNumber(pDoc, node.get());
|
554
|
+
groupDD.addField(field);
|
555
|
+
|
556
|
+
DOMAttributesPtr attrs = node->getAttributes();
|
557
|
+
std::string required;
|
558
|
+
if (attrs->get("required", required) && (required == "Y" || required == "y") && groupRequired) {
|
559
|
+
groupDD.addRequiredField(msgtype, field);
|
560
|
+
}
|
561
|
+
} else if (node->getName() == "component") {
|
562
|
+
field = addXMLComponentFields(pDoc, node.get(), msgtype, groupDD, false);
|
563
|
+
} else if (node->getName() == "group") {
|
564
|
+
field = lookupXMLFieldNumber(pDoc, node.get());
|
565
|
+
groupDD.addField(field);
|
566
|
+
DOMAttributesPtr attrs = node->getAttributes();
|
567
|
+
std::string required;
|
568
|
+
if (attrs->get("required", required) && (required == "Y" || required == "y") && groupRequired) {
|
569
|
+
groupDD.addRequiredField(msgtype, field);
|
570
|
+
}
|
571
|
+
bool isRequired = false;
|
572
|
+
if (attrs->get("required", required)) {
|
573
|
+
isRequired = (required == "Y" || required == "y");
|
574
|
+
}
|
575
|
+
addXMLGroup(pDoc, node.get(), msgtype, groupDD, isRequired);
|
576
|
+
}
|
577
|
+
if (delim == 0) {
|
578
|
+
delim = field;
|
579
|
+
}
|
580
|
+
RESET_AUTO_PTR(node, node->getNextSiblingNode());
|
581
|
+
}
|
582
|
+
|
583
|
+
if (delim) {
|
584
|
+
DD.addGroup(msgtype, group, delim, groupDD);
|
585
|
+
}
|
586
|
+
}
|
587
|
+
|
588
|
+
TYPE::Type DataDictionary::XMLTypeToType(const std::string &type) const {
|
589
|
+
if (m_beginString < "FIX.4.2" && type == "CHAR") {
|
590
|
+
return TYPE::String;
|
591
|
+
}
|
592
|
+
|
593
|
+
if (type == "STRING") {
|
594
|
+
return TYPE::String;
|
595
|
+
}
|
596
|
+
if (type == "CHAR") {
|
597
|
+
return TYPE::Char;
|
598
|
+
}
|
599
|
+
if (type == "PRICE") {
|
600
|
+
return TYPE::Price;
|
601
|
+
}
|
602
|
+
if (type == "INT") {
|
603
|
+
return TYPE::Int;
|
604
|
+
}
|
605
|
+
if (type == "AMT") {
|
606
|
+
return TYPE::Amt;
|
607
|
+
}
|
608
|
+
if (type == "QTY") {
|
609
|
+
return TYPE::Qty;
|
610
|
+
}
|
611
|
+
if (type == "CURRENCY") {
|
612
|
+
return TYPE::Currency;
|
613
|
+
}
|
614
|
+
if (type == "MULTIPLEVALUESTRING") {
|
615
|
+
return TYPE::MultipleValueString;
|
616
|
+
}
|
617
|
+
if (type == "MULTIPLESTRINGVALUE") {
|
618
|
+
return TYPE::MultipleStringValue;
|
619
|
+
}
|
620
|
+
if (type == "MULTIPLECHARVALUE") {
|
621
|
+
return TYPE::MultipleCharValue;
|
622
|
+
}
|
623
|
+
if (type == "EXCHANGE") {
|
624
|
+
return TYPE::Exchange;
|
625
|
+
}
|
626
|
+
if (type == "UTCTIMESTAMP") {
|
627
|
+
return TYPE::UtcTimeStamp;
|
628
|
+
}
|
629
|
+
if (type == "BOOLEAN") {
|
630
|
+
return TYPE::Boolean;
|
631
|
+
}
|
632
|
+
if (type == "LOCALMKTDATE") {
|
633
|
+
return TYPE::LocalMktDate;
|
634
|
+
}
|
635
|
+
if (type == "DATA") {
|
636
|
+
return TYPE::Data;
|
637
|
+
}
|
638
|
+
if (type == "FLOAT") {
|
639
|
+
return TYPE::Float;
|
640
|
+
}
|
641
|
+
if (type == "PRICEOFFSET") {
|
642
|
+
return TYPE::PriceOffset;
|
643
|
+
}
|
644
|
+
if (type == "MONTHYEAR") {
|
645
|
+
return TYPE::MonthYear;
|
646
|
+
}
|
647
|
+
if (type == "DAYOFMONTH") {
|
648
|
+
return TYPE::DayOfMonth;
|
649
|
+
}
|
650
|
+
if (type == "UTCDATE") {
|
651
|
+
return TYPE::UtcDate;
|
652
|
+
}
|
653
|
+
if (type == "UTCDATEONLY") {
|
654
|
+
return TYPE::UtcDateOnly;
|
655
|
+
}
|
656
|
+
if (type == "UTCTIMEONLY") {
|
657
|
+
return TYPE::UtcTimeOnly;
|
658
|
+
}
|
659
|
+
if (type == "NUMINGROUP") {
|
660
|
+
return TYPE::NumInGroup;
|
661
|
+
}
|
662
|
+
if (type == "PERCENTAGE") {
|
663
|
+
return TYPE::Percentage;
|
664
|
+
}
|
665
|
+
if (type == "SEQNUM") {
|
666
|
+
return TYPE::SeqNum;
|
667
|
+
}
|
668
|
+
if (type == "LENGTH") {
|
669
|
+
return TYPE::Length;
|
670
|
+
}
|
671
|
+
if (type == "COUNTRY") {
|
672
|
+
return TYPE::Country;
|
673
|
+
}
|
674
|
+
if (type == "TIME") {
|
675
|
+
return TYPE::UtcTimeStamp;
|
676
|
+
}
|
677
|
+
return TYPE::Unknown;
|
678
|
+
}
|
679
|
+
} // namespace FIX
|