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.
Files changed (205) hide show
  1. checksums.yaml +7 -0
  2. data/ext/quickfix/Acceptor.cpp +257 -0
  3. data/ext/quickfix/Acceptor.h +127 -0
  4. data/ext/quickfix/Allocator.h +9 -0
  5. data/ext/quickfix/Application.h +137 -0
  6. data/ext/quickfix/DOMDocument.h +70 -0
  7. data/ext/quickfix/DataDictionary.cpp +679 -0
  8. data/ext/quickfix/DataDictionary.h +607 -0
  9. data/ext/quickfix/DataDictionaryProvider.cpp +66 -0
  10. data/ext/quickfix/DataDictionaryProvider.h +67 -0
  11. data/ext/quickfix/DatabaseConnectionID.h +98 -0
  12. data/ext/quickfix/DatabaseConnectionPool.h +84 -0
  13. data/ext/quickfix/Dictionary.cpp +157 -0
  14. data/ext/quickfix/Dictionary.h +89 -0
  15. data/ext/quickfix/Event.h +89 -0
  16. data/ext/quickfix/Except.h +39 -0
  17. data/ext/quickfix/Exceptions.h +257 -0
  18. data/ext/quickfix/Field.h +654 -0
  19. data/ext/quickfix/FieldConvertors.cpp +86 -0
  20. data/ext/quickfix/FieldConvertors.h +800 -0
  21. data/ext/quickfix/FieldMap.cpp +254 -0
  22. data/ext/quickfix/FieldMap.h +327 -0
  23. data/ext/quickfix/FieldNumbers.h +44 -0
  24. data/ext/quickfix/FieldTypes.cpp +62 -0
  25. data/ext/quickfix/FieldTypes.h +817 -0
  26. data/ext/quickfix/Fields.h +30 -0
  27. data/ext/quickfix/FileLog.cpp +176 -0
  28. data/ext/quickfix/FileLog.h +110 -0
  29. data/ext/quickfix/FileStore.cpp +369 -0
  30. data/ext/quickfix/FileStore.h +131 -0
  31. data/ext/quickfix/FixCommonFields.h +13 -0
  32. data/ext/quickfix/FixFieldNumbers.h +6132 -0
  33. data/ext/quickfix/FixFields.h +6133 -0
  34. data/ext/quickfix/FixValues.h +5790 -0
  35. data/ext/quickfix/Group.cpp +44 -0
  36. data/ext/quickfix/Group.h +78 -0
  37. data/ext/quickfix/HostDetailsProvider.cpp +79 -0
  38. data/ext/quickfix/HostDetailsProvider.h +44 -0
  39. data/ext/quickfix/HtmlBuilder.h +178 -0
  40. data/ext/quickfix/HttpConnection.cpp +914 -0
  41. data/ext/quickfix/HttpConnection.h +74 -0
  42. data/ext/quickfix/HttpMessage.cpp +229 -0
  43. data/ext/quickfix/HttpMessage.h +112 -0
  44. data/ext/quickfix/HttpParser.cpp +49 -0
  45. data/ext/quickfix/HttpParser.h +49 -0
  46. data/ext/quickfix/HttpServer.cpp +152 -0
  47. data/ext/quickfix/HttpServer.h +76 -0
  48. data/ext/quickfix/Initiator.cpp +310 -0
  49. data/ext/quickfix/Initiator.h +151 -0
  50. data/ext/quickfix/Log.cpp +71 -0
  51. data/ext/quickfix/Log.h +254 -0
  52. data/ext/quickfix/Message.cpp +617 -0
  53. data/ext/quickfix/Message.h +419 -0
  54. data/ext/quickfix/MessageCracker.h +171 -0
  55. data/ext/quickfix/MessageSorters.cpp +101 -0
  56. data/ext/quickfix/MessageSorters.h +185 -0
  57. data/ext/quickfix/MessageStore.cpp +182 -0
  58. data/ext/quickfix/MessageStore.h +164 -0
  59. data/ext/quickfix/Mutex.h +120 -0
  60. data/ext/quickfix/MySQLConnection.h +187 -0
  61. data/ext/quickfix/MySQLLog.cpp +262 -0
  62. data/ext/quickfix/MySQLLog.h +158 -0
  63. data/ext/quickfix/MySQLStore.cpp +323 -0
  64. data/ext/quickfix/MySQLStore.h +161 -0
  65. data/ext/quickfix/MySQLStubs.h +203 -0
  66. data/ext/quickfix/NullStore.cpp +40 -0
  67. data/ext/quickfix/NullStore.h +89 -0
  68. data/ext/quickfix/OdbcConnection.h +241 -0
  69. data/ext/quickfix/OdbcLog.cpp +230 -0
  70. data/ext/quickfix/OdbcLog.h +109 -0
  71. data/ext/quickfix/OdbcStore.cpp +313 -0
  72. data/ext/quickfix/OdbcStore.h +124 -0
  73. data/ext/quickfix/PUGIXML_DOMDocument.cpp +112 -0
  74. data/ext/quickfix/PUGIXML_DOMDocument.h +81 -0
  75. data/ext/quickfix/Parser.cpp +111 -0
  76. data/ext/quickfix/Parser.h +50 -0
  77. data/ext/quickfix/PostgreSQLConnection.h +163 -0
  78. data/ext/quickfix/PostgreSQLLog.cpp +263 -0
  79. data/ext/quickfix/PostgreSQLLog.h +157 -0
  80. data/ext/quickfix/PostgreSQLStore.cpp +327 -0
  81. data/ext/quickfix/PostgreSQLStore.h +160 -0
  82. data/ext/quickfix/PostgreSQLStubs.h +203 -0
  83. data/ext/quickfix/Queue.h +66 -0
  84. data/ext/quickfix/QuickfixRuby.cpp +131900 -0
  85. data/ext/quickfix/QuickfixRuby.h +56 -0
  86. data/ext/quickfix/Responder.h +41 -0
  87. data/ext/quickfix/SSLSocketAcceptor.cpp +409 -0
  88. data/ext/quickfix/SSLSocketAcceptor.h +186 -0
  89. data/ext/quickfix/SSLSocketConnection.cpp +434 -0
  90. data/ext/quickfix/SSLSocketConnection.h +221 -0
  91. data/ext/quickfix/SSLSocketInitiator.cpp +558 -0
  92. data/ext/quickfix/SSLSocketInitiator.h +203 -0
  93. data/ext/quickfix/SSLStubs.h +129 -0
  94. data/ext/quickfix/Session.cpp +1437 -0
  95. data/ext/quickfix/Session.h +343 -0
  96. data/ext/quickfix/SessionFactory.cpp +314 -0
  97. data/ext/quickfix/SessionFactory.h +84 -0
  98. data/ext/quickfix/SessionID.h +136 -0
  99. data/ext/quickfix/SessionSettings.cpp +165 -0
  100. data/ext/quickfix/SessionSettings.h +283 -0
  101. data/ext/quickfix/SessionState.h +260 -0
  102. data/ext/quickfix/Settings.cpp +160 -0
  103. data/ext/quickfix/Settings.h +56 -0
  104. data/ext/quickfix/SharedArray.h +274 -0
  105. data/ext/quickfix/SocketAcceptor.cpp +216 -0
  106. data/ext/quickfix/SocketAcceptor.h +77 -0
  107. data/ext/quickfix/SocketConnection.cpp +256 -0
  108. data/ext/quickfix/SocketConnection.h +102 -0
  109. data/ext/quickfix/SocketConnector.cpp +112 -0
  110. data/ext/quickfix/SocketConnector.h +76 -0
  111. data/ext/quickfix/SocketInitiator.cpp +241 -0
  112. data/ext/quickfix/SocketInitiator.h +76 -0
  113. data/ext/quickfix/SocketMonitor.h +26 -0
  114. data/ext/quickfix/SocketMonitor_UNIX.cpp +238 -0
  115. data/ext/quickfix/SocketMonitor_UNIX.h +101 -0
  116. data/ext/quickfix/SocketMonitor_WIN32.cpp +248 -0
  117. data/ext/quickfix/SocketMonitor_WIN32.h +99 -0
  118. data/ext/quickfix/SocketServer.cpp +163 -0
  119. data/ext/quickfix/SocketServer.h +100 -0
  120. data/ext/quickfix/ThreadedSSLSocketAcceptor.cpp +436 -0
  121. data/ext/quickfix/ThreadedSSLSocketAcceptor.h +209 -0
  122. data/ext/quickfix/ThreadedSSLSocketConnection.cpp +364 -0
  123. data/ext/quickfix/ThreadedSSLSocketConnection.h +191 -0
  124. data/ext/quickfix/ThreadedSSLSocketInitiator.cpp +434 -0
  125. data/ext/quickfix/ThreadedSSLSocketInitiator.h +193 -0
  126. data/ext/quickfix/ThreadedSocketAcceptor.cpp +242 -0
  127. data/ext/quickfix/ThreadedSocketAcceptor.h +95 -0
  128. data/ext/quickfix/ThreadedSocketConnection.cpp +227 -0
  129. data/ext/quickfix/ThreadedSocketConnection.h +89 -0
  130. data/ext/quickfix/ThreadedSocketInitiator.cpp +238 -0
  131. data/ext/quickfix/ThreadedSocketInitiator.h +78 -0
  132. data/ext/quickfix/TimeRange.cpp +227 -0
  133. data/ext/quickfix/TimeRange.h +215 -0
  134. data/ext/quickfix/Utility.cpp +639 -0
  135. data/ext/quickfix/Utility.h +255 -0
  136. data/ext/quickfix/UtilitySSL.cpp +1612 -0
  137. data/ext/quickfix/UtilitySSL.h +274 -0
  138. data/ext/quickfix/Values.h +63 -0
  139. data/ext/quickfix/config-all.h +10 -0
  140. data/ext/quickfix/config.h +10 -0
  141. data/ext/quickfix/config_unix.h +178 -0
  142. data/ext/quickfix/config_windows.h +0 -0
  143. data/ext/quickfix/dirent_windows.h +838 -0
  144. data/ext/quickfix/double-conversion/bignum-dtoa.cc +641 -0
  145. data/ext/quickfix/double-conversion/bignum-dtoa.h +84 -0
  146. data/ext/quickfix/double-conversion/bignum.cc +766 -0
  147. data/ext/quickfix/double-conversion/bignum.h +144 -0
  148. data/ext/quickfix/double-conversion/cached-powers.cc +176 -0
  149. data/ext/quickfix/double-conversion/cached-powers.h +64 -0
  150. data/ext/quickfix/double-conversion/diy-fp.cc +57 -0
  151. data/ext/quickfix/double-conversion/diy-fp.h +118 -0
  152. data/ext/quickfix/double-conversion/double-conversion.cc +994 -0
  153. data/ext/quickfix/double-conversion/double-conversion.h +543 -0
  154. data/ext/quickfix/double-conversion/fast-dtoa.cc +665 -0
  155. data/ext/quickfix/double-conversion/fast-dtoa.h +88 -0
  156. data/ext/quickfix/double-conversion/fixed-dtoa.cc +404 -0
  157. data/ext/quickfix/double-conversion/fixed-dtoa.h +56 -0
  158. data/ext/quickfix/double-conversion/ieee.h +402 -0
  159. data/ext/quickfix/double-conversion/strtod.cc +557 -0
  160. data/ext/quickfix/double-conversion/strtod.h +45 -0
  161. data/ext/quickfix/double-conversion/utils.h +374 -0
  162. data/ext/quickfix/extconf.rb +76 -0
  163. data/ext/quickfix/index.h +37 -0
  164. data/ext/quickfix/pugiconfig.hpp +77 -0
  165. data/ext/quickfix/pugixml.cpp +13237 -0
  166. data/ext/quickfix/pugixml.hpp +1516 -0
  167. data/ext/quickfix/scope_guard.hpp +215 -0
  168. data/ext/quickfix/stdint_msvc.h +254 -0
  169. data/ext/quickfix/strptime.h +7 -0
  170. data/lib/2.4/quickfix.so +0 -0
  171. data/lib/2.5/quickfix.so +0 -0
  172. data/lib/2.6/quickfix.so +0 -0
  173. data/lib/2.7/quickfix.so +0 -0
  174. data/lib/3.0/quickfix.so +0 -0
  175. data/lib/3.1/quickfix.so +0 -0
  176. data/lib/3.2/quickfix.so +0 -0
  177. data/lib/3.3/quickfix.so +0 -0
  178. data/lib/3.4/quickfix.so +0 -0
  179. data/lib/quickfix40.rb +274 -0
  180. data/lib/quickfix41.rb +351 -0
  181. data/lib/quickfix42.rb +1184 -0
  182. data/lib/quickfix43.rb +3504 -0
  183. data/lib/quickfix44.rb +14040 -0
  184. data/lib/quickfix50.rb +20051 -0
  185. data/lib/quickfix50sp1.rb +23596 -0
  186. data/lib/quickfix50sp2.rb +412444 -0
  187. data/lib/quickfix_fields.rb +79393 -0
  188. data/lib/quickfix_ruby.rb +82 -0
  189. data/lib/quickfixt11.rb +65 -0
  190. data/spec/FIX40.xml +862 -0
  191. data/spec/FIX41.xml +1282 -0
  192. data/spec/FIX42.xml +2743 -0
  193. data/spec/FIX43.xml +4230 -0
  194. data/spec/FIX44.xml +6600 -0
  195. data/spec/FIX50.xml +8142 -0
  196. data/spec/FIX50SP1.xml +9506 -0
  197. data/spec/FIX50SP2.xml +26069 -0
  198. data/spec/FIXT11.xml +252 -0
  199. data/test/DataDictionaryTestCase.rb +268 -0
  200. data/test/DictionaryTestCase.rb +112 -0
  201. data/test/FieldBaseTestCase.rb +24 -0
  202. data/test/MessageStoreTestCase.rb +19 -0
  203. data/test/MessageTestCase.rb +368 -0
  204. data/test/SessionSettingsTestCase.rb +41 -0
  205. 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 &copy) { *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