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,254 @@
|
|
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 "FieldMap.h"
|
27
|
+
#include <algorithm>
|
28
|
+
#include <deque>
|
29
|
+
#include <iterator>
|
30
|
+
|
31
|
+
namespace FIX {
|
32
|
+
|
33
|
+
FieldMap::FieldMap(const message_order &order, int size)
|
34
|
+
: m_order(order) {
|
35
|
+
m_fields.reserve(size);
|
36
|
+
}
|
37
|
+
|
38
|
+
FieldMap::FieldMap(const message_order &order /*= message_order(message_order::normal)*/)
|
39
|
+
: m_order(order) {
|
40
|
+
m_fields.reserve(DEFAULT_SIZE);
|
41
|
+
}
|
42
|
+
|
43
|
+
FieldMap::FieldMap(const int order[])
|
44
|
+
: m_order(message_order(order)) {
|
45
|
+
m_fields.reserve(DEFAULT_SIZE);
|
46
|
+
}
|
47
|
+
|
48
|
+
FieldMap::FieldMap(const FieldMap ©) { *this = copy; }
|
49
|
+
|
50
|
+
FieldMap::FieldMap(FieldMap &&rhs)
|
51
|
+
: m_fields(std::move(rhs.m_fields)),
|
52
|
+
m_groups(std::move(rhs.m_groups)),
|
53
|
+
m_order(std::move(rhs.m_order)) {}
|
54
|
+
|
55
|
+
FieldMap::~FieldMap() { clear(); }
|
56
|
+
|
57
|
+
FieldMap &FieldMap::operator=(const FieldMap &rhs) {
|
58
|
+
clear();
|
59
|
+
|
60
|
+
m_fields = rhs.m_fields;
|
61
|
+
m_order = rhs.m_order;
|
62
|
+
|
63
|
+
for (auto const &tagWithGroups : rhs.m_groups) {
|
64
|
+
for (auto const &group : tagWithGroups.second) {
|
65
|
+
m_groups[tagWithGroups.first].push_back(new FieldMap(*group));
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
return *this;
|
70
|
+
}
|
71
|
+
|
72
|
+
FieldMap &FieldMap::operator=(FieldMap &&rhs) {
|
73
|
+
m_fields = std::move(rhs.m_fields);
|
74
|
+
m_groups = std::move(rhs.m_groups);
|
75
|
+
m_order = std::move(rhs.m_order);
|
76
|
+
return *this;
|
77
|
+
}
|
78
|
+
|
79
|
+
void FieldMap::addGroup(int field, const FieldMap &group, bool setCount) {
|
80
|
+
FieldMap *pGroup = new FieldMap(group);
|
81
|
+
|
82
|
+
addGroupPtr(field, pGroup, setCount);
|
83
|
+
}
|
84
|
+
|
85
|
+
void FieldMap::addGroupPtr(int tag, FieldMap *group, bool setCount) {
|
86
|
+
if (group == 0) {
|
87
|
+
return;
|
88
|
+
}
|
89
|
+
|
90
|
+
std::vector<FieldMap *> &groups = m_groups[tag];
|
91
|
+
groups.push_back(group);
|
92
|
+
|
93
|
+
if (setCount) {
|
94
|
+
setField(IntField(tag, (int)groups.size()));
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
void FieldMap::replaceGroup(int num, int tag, const FieldMap &group) {
|
99
|
+
Groups::const_iterator tagWithGroups = m_groups.find(tag);
|
100
|
+
if (tagWithGroups == m_groups.end()) {
|
101
|
+
return;
|
102
|
+
}
|
103
|
+
if (num <= 0) {
|
104
|
+
return;
|
105
|
+
}
|
106
|
+
if (tagWithGroups->second.size() < static_cast<unsigned>(num)) {
|
107
|
+
return;
|
108
|
+
}
|
109
|
+
*(*(tagWithGroups->second.begin() + (num - 1))) = group;
|
110
|
+
}
|
111
|
+
|
112
|
+
void FieldMap::removeGroup(int num, int tag) {
|
113
|
+
Groups::iterator tagWithGroups = m_groups.find(tag);
|
114
|
+
if (tagWithGroups == m_groups.end()) {
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
if (num <= 0) {
|
118
|
+
return;
|
119
|
+
}
|
120
|
+
std::vector<FieldMap *> &groups = tagWithGroups->second;
|
121
|
+
if (groups.size() < static_cast<unsigned>(num)) {
|
122
|
+
return;
|
123
|
+
}
|
124
|
+
|
125
|
+
std::vector<FieldMap *>::iterator group = groups.begin();
|
126
|
+
std::advance(group, (num - 1));
|
127
|
+
|
128
|
+
delete (*group);
|
129
|
+
groups.erase(group);
|
130
|
+
|
131
|
+
if (groups.size() == 0) {
|
132
|
+
m_groups.erase(tagWithGroups);
|
133
|
+
removeField(tag);
|
134
|
+
} else {
|
135
|
+
IntField groupCount(tag, (int)groups.size());
|
136
|
+
setField(groupCount);
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
void FieldMap::removeGroup(int tag) {
|
141
|
+
Groups::iterator tagWithGroups = m_groups.find(tag);
|
142
|
+
if (tagWithGroups == m_groups.end()) {
|
143
|
+
return;
|
144
|
+
}
|
145
|
+
|
146
|
+
std::vector<FieldMap *> toDelete;
|
147
|
+
toDelete.swap(tagWithGroups->second);
|
148
|
+
|
149
|
+
m_groups.erase(tagWithGroups);
|
150
|
+
|
151
|
+
std::for_each(toDelete.begin(), toDelete.end(), [](FieldMap *group) { delete group; });
|
152
|
+
|
153
|
+
removeField(tag);
|
154
|
+
}
|
155
|
+
|
156
|
+
void FieldMap::removeField(int tag) {
|
157
|
+
Fields::iterator field = findTag(tag);
|
158
|
+
if (field != m_fields.end()) {
|
159
|
+
m_fields.erase(field);
|
160
|
+
removeGroup(tag);
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
bool FieldMap::hasGroup(int num, int tag) const { return (int)groupCount(tag) >= num; }
|
165
|
+
|
166
|
+
bool FieldMap::hasGroup(int tag) const { return m_groups.find(tag) != m_groups.end(); }
|
167
|
+
|
168
|
+
size_t FieldMap::groupCount(int tag) const {
|
169
|
+
Groups::const_iterator tagWithGroups = m_groups.find(tag);
|
170
|
+
return tagWithGroups == m_groups.end() ? 0 : tagWithGroups->second.size();
|
171
|
+
}
|
172
|
+
|
173
|
+
void FieldMap::clear() {
|
174
|
+
m_fields.clear();
|
175
|
+
|
176
|
+
for (auto const &tagWithGroups : m_groups) {
|
177
|
+
for (auto const &group : tagWithGroups.second) {
|
178
|
+
delete group;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
m_groups.clear();
|
183
|
+
}
|
184
|
+
|
185
|
+
bool FieldMap::isEmpty() { return m_fields.empty(); }
|
186
|
+
|
187
|
+
size_t FieldMap::totalFields() const {
|
188
|
+
size_t result = m_fields.size();
|
189
|
+
|
190
|
+
for (auto const &tagWithGroups : m_groups) {
|
191
|
+
for (auto const &group : tagWithGroups.second) {
|
192
|
+
result += group->totalFields();
|
193
|
+
}
|
194
|
+
}
|
195
|
+
return result;
|
196
|
+
}
|
197
|
+
|
198
|
+
std::string &FieldMap::calculateString(std::string &result) const {
|
199
|
+
for (auto const &field : m_fields) {
|
200
|
+
result += field.getFixString();
|
201
|
+
|
202
|
+
// add groups if they exist
|
203
|
+
if (!m_groups.size()) {
|
204
|
+
continue;
|
205
|
+
}
|
206
|
+
|
207
|
+
Groups::const_iterator tagWithGroups = m_groups.find(field.getTag());
|
208
|
+
if (tagWithGroups == m_groups.end()) {
|
209
|
+
continue;
|
210
|
+
}
|
211
|
+
|
212
|
+
for (auto const &group : tagWithGroups->second) {
|
213
|
+
group->calculateString(result);
|
214
|
+
}
|
215
|
+
}
|
216
|
+
return result;
|
217
|
+
}
|
218
|
+
|
219
|
+
int FieldMap::calculateLength(int beginStringField, int bodyLengthField, int checkSumField) const {
|
220
|
+
int result = 0;
|
221
|
+
|
222
|
+
for (auto const &field : m_fields) {
|
223
|
+
const int tag = field.getTag();
|
224
|
+
if (tag != beginStringField && tag != bodyLengthField && tag != checkSumField) {
|
225
|
+
result += field.getLength();
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
for (auto const &tagWithGroups : m_groups) {
|
230
|
+
for (auto const &group : tagWithGroups.second) {
|
231
|
+
result += group->calculateLength();
|
232
|
+
}
|
233
|
+
}
|
234
|
+
return result;
|
235
|
+
}
|
236
|
+
|
237
|
+
int FieldMap::calculateTotal(int checkSumField) const {
|
238
|
+
int result = 0;
|
239
|
+
|
240
|
+
for (auto const &field : m_fields) {
|
241
|
+
if (field.getTag() != checkSumField) {
|
242
|
+
result += field.getTotal();
|
243
|
+
}
|
244
|
+
}
|
245
|
+
|
246
|
+
for (auto const &tagWithGroups : m_groups) {
|
247
|
+
for (auto const &group : tagWithGroups.second) {
|
248
|
+
result += group->calculateTotal();
|
249
|
+
}
|
250
|
+
}
|
251
|
+
return result;
|
252
|
+
}
|
253
|
+
|
254
|
+
} // namespace FIX
|
@@ -0,0 +1,327 @@
|
|
1
|
+
/* -*- C++ -*- */
|
2
|
+
|
3
|
+
/****************************************************************************
|
4
|
+
** Copyright (c) 2001-2014
|
5
|
+
**
|
6
|
+
** This file is part of the QuickFIX FIX Engine
|
7
|
+
**
|
8
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
9
|
+
** license as defined by quickfixengine.org and appearing in the file
|
10
|
+
** LICENSE included in the packaging of this file.
|
11
|
+
**
|
12
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
13
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
14
|
+
**
|
15
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
16
|
+
**
|
17
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
18
|
+
** not clear to you.
|
19
|
+
**
|
20
|
+
****************************************************************************/
|
21
|
+
|
22
|
+
#ifndef FIX_FIELDMAP
|
23
|
+
#define FIX_FIELDMAP
|
24
|
+
|
25
|
+
#ifdef _MSC_VER
|
26
|
+
#pragma warning(disable : 4786)
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#include "Exceptions.h"
|
30
|
+
#include "Field.h"
|
31
|
+
#include "MessageSorters.h"
|
32
|
+
#include "Utility.h"
|
33
|
+
#include <algorithm>
|
34
|
+
#include <map>
|
35
|
+
#include <sstream>
|
36
|
+
#include <vector>
|
37
|
+
|
38
|
+
namespace FIX {
|
39
|
+
/**
|
40
|
+
* Stores and organizes a collection of Fields.
|
41
|
+
*
|
42
|
+
* This is the basis for a message, header, and trailer. This collection
|
43
|
+
* class uses a sorter to keep the fields in a particular order.
|
44
|
+
*/
|
45
|
+
class FieldMap {
|
46
|
+
|
47
|
+
class sorter {
|
48
|
+
public:
|
49
|
+
explicit sorter(const message_order &order)
|
50
|
+
: m_order(order) {}
|
51
|
+
|
52
|
+
bool operator()(int tag, const FieldBase &right) const { return m_order(tag, right.getTag()); }
|
53
|
+
|
54
|
+
bool operator()(const FieldBase &left, int tag) const { return m_order(left.getTag(), tag); }
|
55
|
+
|
56
|
+
bool operator()(const FieldBase &left, const FieldBase &right) const {
|
57
|
+
return m_order(left.getTag(), right.getTag());
|
58
|
+
}
|
59
|
+
|
60
|
+
private:
|
61
|
+
const message_order &m_order;
|
62
|
+
};
|
63
|
+
|
64
|
+
class finder {
|
65
|
+
public:
|
66
|
+
explicit finder(int tag)
|
67
|
+
: m_tag(tag) {}
|
68
|
+
|
69
|
+
bool operator()(const FieldBase &field) const { return m_tag == field.getTag(); }
|
70
|
+
|
71
|
+
private:
|
72
|
+
int m_tag;
|
73
|
+
};
|
74
|
+
|
75
|
+
enum {
|
76
|
+
DEFAULT_SIZE = 16
|
77
|
+
};
|
78
|
+
|
79
|
+
protected:
|
80
|
+
FieldMap(const message_order &order, int size);
|
81
|
+
|
82
|
+
public:
|
83
|
+
typedef std::vector<FieldBase, ALLOCATOR<FieldBase>> Fields;
|
84
|
+
typedef std::
|
85
|
+
map<int, std::vector<FieldMap *>, std::less<int>, ALLOCATOR<std::pair<const int, std::vector<FieldMap *>>>>
|
86
|
+
Groups;
|
87
|
+
|
88
|
+
typedef Fields::iterator iterator;
|
89
|
+
typedef Fields::const_iterator const_iterator;
|
90
|
+
typedef Fields::value_type value_type;
|
91
|
+
typedef Groups::iterator g_iterator;
|
92
|
+
typedef Groups::const_iterator g_const_iterator;
|
93
|
+
typedef Groups::value_type g_value_type;
|
94
|
+
|
95
|
+
FieldMap(const message_order &order = message_order(message_order::normal));
|
96
|
+
|
97
|
+
FieldMap(const int order[]);
|
98
|
+
|
99
|
+
FieldMap(const FieldMap ©);
|
100
|
+
FieldMap(FieldMap &&rhs);
|
101
|
+
|
102
|
+
virtual ~FieldMap();
|
103
|
+
|
104
|
+
FieldMap &operator=(const FieldMap &rhs);
|
105
|
+
FieldMap &operator=(FieldMap &&rhs);
|
106
|
+
|
107
|
+
/// Set a field without type checking
|
108
|
+
void setField(const FieldBase &field, bool overwrite = true) EXCEPT(RepeatedTag) {
|
109
|
+
if (!overwrite) {
|
110
|
+
addField(field);
|
111
|
+
} else {
|
112
|
+
Fields::iterator foundField = findTag(field.getTag());
|
113
|
+
if (foundField == m_fields.end()) {
|
114
|
+
addField(field);
|
115
|
+
} else {
|
116
|
+
foundField->setString(field.getString());
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
/// Set a field without a field class
|
122
|
+
void setField(int tag, const std::string &value) EXCEPT(RepeatedTag, NoTagValue) {
|
123
|
+
FieldBase fieldBase(tag, value);
|
124
|
+
setField(fieldBase);
|
125
|
+
}
|
126
|
+
|
127
|
+
/// Get a field if set
|
128
|
+
bool getFieldIfSet(FieldBase &field) const {
|
129
|
+
Fields::const_iterator foundField = findTag(field.getTag());
|
130
|
+
if (foundField == m_fields.end()) {
|
131
|
+
return false;
|
132
|
+
}
|
133
|
+
field = (*foundField);
|
134
|
+
return true;
|
135
|
+
}
|
136
|
+
|
137
|
+
/// Get a field without type checking
|
138
|
+
FieldBase &getField(FieldBase &field) const EXCEPT(FieldNotFound) {
|
139
|
+
field = getFieldRef(field.getTag());
|
140
|
+
return field;
|
141
|
+
}
|
142
|
+
|
143
|
+
/// Get a field without type checking
|
144
|
+
template <typename T> const T &getField() const EXCEPT(FieldNotFound) {
|
145
|
+
return *reinterpret_cast<const T *>(&getFieldRef(T::tag));
|
146
|
+
}
|
147
|
+
|
148
|
+
/// Get a field without a field class
|
149
|
+
const std::string &getField(int tag) const EXCEPT(FieldNotFound) { return getFieldRef(tag).getString(); }
|
150
|
+
|
151
|
+
/// Get direct access to a field through a reference
|
152
|
+
const FieldBase &getFieldRef(int tag) const EXCEPT(FieldNotFound) {
|
153
|
+
Fields::const_iterator field = findTag(tag);
|
154
|
+
if (field == m_fields.end()) {
|
155
|
+
throw FieldNotFound(tag);
|
156
|
+
}
|
157
|
+
return (*field);
|
158
|
+
}
|
159
|
+
|
160
|
+
/// Get direct access to a field through a pointer
|
161
|
+
const FieldBase *const getFieldPtr(int tag) const EXCEPT(FieldNotFound) { return &getFieldRef(tag); }
|
162
|
+
|
163
|
+
/// Check to see if a field is set
|
164
|
+
bool isSetField(const FieldBase &field) const { return isSetField(field.getTag()); }
|
165
|
+
/// Check to see if a field is set by referencing its number
|
166
|
+
bool isSetField(int tag) const { return findTag(tag) != m_fields.end(); }
|
167
|
+
|
168
|
+
/// Remove a field. If field is not present, this is a no-op.
|
169
|
+
void removeField(int tag);
|
170
|
+
|
171
|
+
/// Add a group.
|
172
|
+
void addGroup(int tag, const FieldMap &group, bool setCount = true);
|
173
|
+
|
174
|
+
/// Acquire ownership of Group object
|
175
|
+
void addGroupPtr(int tag, FieldMap *group, bool setCount = true);
|
176
|
+
|
177
|
+
/// Replace a specific instance of a group.
|
178
|
+
void replaceGroup(int num, int tag, const FieldMap &group);
|
179
|
+
|
180
|
+
/// Get a specific instance of a group.
|
181
|
+
FieldMap &getGroup(int num, int tag, FieldMap &group) const EXCEPT(FieldNotFound) {
|
182
|
+
return group = getGroupRef(num, tag);
|
183
|
+
}
|
184
|
+
|
185
|
+
/// Get direct access to a field through a reference
|
186
|
+
FieldMap &getGroupRef(int num, int tag) const EXCEPT(FieldNotFound) {
|
187
|
+
Groups::const_iterator tagWithGroups = m_groups.find(tag);
|
188
|
+
if (tagWithGroups == m_groups.end()) {
|
189
|
+
throw FieldNotFound(tag);
|
190
|
+
}
|
191
|
+
if (num <= 0) {
|
192
|
+
throw FieldNotFound(tag);
|
193
|
+
}
|
194
|
+
if (tagWithGroups->second.size() < static_cast<unsigned>(num)) {
|
195
|
+
throw FieldNotFound(tag);
|
196
|
+
}
|
197
|
+
return *(*(tagWithGroups->second.begin() + (num - 1)));
|
198
|
+
}
|
199
|
+
|
200
|
+
/// Get direct access to a field through a pointer
|
201
|
+
FieldMap *getGroupPtr(int num, int tag) const EXCEPT(FieldNotFound) { return &getGroupRef(num, tag); }
|
202
|
+
|
203
|
+
const Groups &groups() const { return m_groups; }
|
204
|
+
|
205
|
+
/// Remove a specific instance of a group.
|
206
|
+
void removeGroup(int num, int tag);
|
207
|
+
/// Remove all instances of a group.
|
208
|
+
void removeGroup(int tag);
|
209
|
+
|
210
|
+
/// Check to see any instance of a group exists
|
211
|
+
bool hasGroup(int tag) const;
|
212
|
+
/// Check to see if a specific instance of a group exists
|
213
|
+
bool hasGroup(int num, int tag) const;
|
214
|
+
/// Count the number of instance of a group
|
215
|
+
size_t groupCount(int tag) const;
|
216
|
+
|
217
|
+
/// Clear all fields from the map
|
218
|
+
void clear();
|
219
|
+
/// Check if map contains any fields
|
220
|
+
bool isEmpty();
|
221
|
+
|
222
|
+
size_t totalFields() const;
|
223
|
+
|
224
|
+
std::string &calculateString(std::string &) const;
|
225
|
+
|
226
|
+
int calculateLength(
|
227
|
+
int beginStringField = FIELD::BeginString,
|
228
|
+
int bodyLengthField = FIELD::BodyLength,
|
229
|
+
int checkSumField = FIELD::CheckSum) const;
|
230
|
+
|
231
|
+
int calculateTotal(int checkSumField = FIELD::CheckSum) const;
|
232
|
+
|
233
|
+
iterator begin() { return m_fields.begin(); }
|
234
|
+
iterator end() { return m_fields.end(); }
|
235
|
+
const_iterator begin() const { return m_fields.begin(); }
|
236
|
+
const_iterator end() const { return m_fields.end(); }
|
237
|
+
g_iterator g_begin() { return m_groups.begin(); }
|
238
|
+
g_iterator g_end() { return m_groups.end(); }
|
239
|
+
g_const_iterator g_begin() const { return m_groups.begin(); }
|
240
|
+
g_const_iterator g_end() const { return m_groups.end(); }
|
241
|
+
|
242
|
+
protected:
|
243
|
+
friend class Message;
|
244
|
+
|
245
|
+
void addField(const FieldBase &field) {
|
246
|
+
Fields::iterator iter = findPositionFor(field.getTag());
|
247
|
+
if (iter == m_fields.end()) {
|
248
|
+
m_fields.push_back(field);
|
249
|
+
} else {
|
250
|
+
m_fields.insert(iter, field);
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
254
|
+
// used to find data length fields during message decoding
|
255
|
+
// message fields are not yet sorted so regular find*** functions might return wrong results
|
256
|
+
const FieldBase &reverse_find(int tag) const {
|
257
|
+
Fields::const_reverse_iterator field = std::find_if(m_fields.rbegin(), m_fields.rend(), finder(tag));
|
258
|
+
if (field == m_fields.rend()) {
|
259
|
+
throw FieldNotFound(tag);
|
260
|
+
}
|
261
|
+
|
262
|
+
return *field;
|
263
|
+
}
|
264
|
+
|
265
|
+
// append field to message without sorting
|
266
|
+
// only applicable during message decoding
|
267
|
+
void appendField(const FieldBase &field) { m_fields.push_back(field); }
|
268
|
+
|
269
|
+
// sort fields after message decoding
|
270
|
+
void sortFields() { std::sort(m_fields.begin(), m_fields.end(), sorter(m_order)); }
|
271
|
+
|
272
|
+
private:
|
273
|
+
Fields::const_iterator findTag(int tag) const { return lookup(m_fields.begin(), m_fields.end(), tag); }
|
274
|
+
|
275
|
+
Fields::iterator findTag(int tag) { return lookup(m_fields.begin(), m_fields.end(), tag); }
|
276
|
+
|
277
|
+
template <typename Iterator> Iterator lookup(Iterator begin, Iterator end, int tag) const {
|
278
|
+
#if defined(__SUNPRO_CC)
|
279
|
+
std::size_t numElements;
|
280
|
+
std::distance(begin, end, numElements);
|
281
|
+
#else
|
282
|
+
std::size_t numElements = std::distance(begin, end);
|
283
|
+
#endif
|
284
|
+
if (numElements < 16) {
|
285
|
+
return std::find_if(begin, end, finder(tag));
|
286
|
+
}
|
287
|
+
|
288
|
+
Iterator field = std::lower_bound(begin, end, tag, sorter(m_order));
|
289
|
+
if (field != end && field->getTag() == tag) {
|
290
|
+
return field;
|
291
|
+
}
|
292
|
+
|
293
|
+
return end;
|
294
|
+
}
|
295
|
+
|
296
|
+
Fields::iterator findPositionFor(int tag) {
|
297
|
+
if (m_fields.empty()) {
|
298
|
+
return m_fields.end();
|
299
|
+
}
|
300
|
+
|
301
|
+
const FieldBase &lastField = m_fields.back();
|
302
|
+
if (m_order(lastField.getTag(), tag) || lastField.getTag() == tag) {
|
303
|
+
return m_fields.end();
|
304
|
+
}
|
305
|
+
|
306
|
+
return std::upper_bound(m_fields.begin(), m_fields.end(), tag, sorter(m_order));
|
307
|
+
}
|
308
|
+
|
309
|
+
Fields m_fields;
|
310
|
+
Groups m_groups;
|
311
|
+
message_order m_order;
|
312
|
+
};
|
313
|
+
/*! @} */
|
314
|
+
} // namespace FIX
|
315
|
+
|
316
|
+
#define FIELD_SET(MAP, FIELD) \
|
317
|
+
bool isSet(const FIELD &field) const { return (MAP).isSetField(field); } \
|
318
|
+
void set(const FIELD &field) { (MAP).setField(field); } \
|
319
|
+
FIELD &get(FIELD &field) const { return (FIELD &)(MAP).getField(field); } \
|
320
|
+
bool getIfSet(FIELD &field) const { return (MAP).getFieldIfSet(field); }
|
321
|
+
|
322
|
+
#define FIELD_GET_PTR(MAP, FLD) (const FIX::FLD *)MAP.getFieldPtr(FIX::FIELD::FLD)
|
323
|
+
#define FIELD_GET_REF(MAP, FLD) (const FIX::FLD &)MAP.getFieldRef(FIX::FIELD::FLD)
|
324
|
+
#define FIELD_THROW_IF_NOT_FOUND(MAP, FLD) \
|
325
|
+
if (!(MAP).isSetField(FIX::FIELD::FLD)) \
|
326
|
+
throw FieldNotFound(FIX::FIELD::FLD)
|
327
|
+
#endif // FIX_FIELDMAP
|
@@ -0,0 +1,44 @@
|
|
1
|
+
/* -*- C++ -*- */
|
2
|
+
|
3
|
+
/****************************************************************************
|
4
|
+
** Copyright (c) 2001-2014
|
5
|
+
**
|
6
|
+
** This file is part of the QuickFIX FIX Engine
|
7
|
+
**
|
8
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
9
|
+
** license as defined by quickfixengine.org and appearing in the file
|
10
|
+
** LICENSE included in the packaging of this file.
|
11
|
+
**
|
12
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
13
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
14
|
+
**
|
15
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
16
|
+
**
|
17
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
18
|
+
** not clear to you.
|
19
|
+
**
|
20
|
+
****************************************************************************/
|
21
|
+
|
22
|
+
#ifndef FIX_FIELDNUMBERS_BASE_H
|
23
|
+
#define FIX_FIELDNUMBERS_BASE_H
|
24
|
+
|
25
|
+
#include "FixFieldNumbers.h"
|
26
|
+
#include <iostream>
|
27
|
+
|
28
|
+
namespace FIX {
|
29
|
+
namespace FIELD {
|
30
|
+
const int FIX40_LastField = PrevClosePx;
|
31
|
+
const int FIX41_LastField = PegDifference;
|
32
|
+
const int FIX42_LastField = EncodedListStatusText;
|
33
|
+
const int FIX43_LastField = SideComplianceID;
|
34
|
+
const int FIX44_LastField = LegInterestAccrualDate;
|
35
|
+
const int FIX50_LastField = ExchangeSpecialInstructions;
|
36
|
+
const int NormalMin = 1;
|
37
|
+
const int NormalMax = 4999;
|
38
|
+
const int UserMin = 5000;
|
39
|
+
const int UserMax = 9999;
|
40
|
+
const int InternalMin = 10000;
|
41
|
+
} // namespace FIELD
|
42
|
+
} // namespace FIX
|
43
|
+
|
44
|
+
#endif // FIX_FIELDNUMBERS_BASE_H
|
@@ -0,0 +1,62 @@
|
|
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 "FieldTypes.h"
|
27
|
+
|
28
|
+
#ifdef HAVE_FTIME
|
29
|
+
#include <sys/timeb.h>
|
30
|
+
#endif
|
31
|
+
|
32
|
+
namespace FIX {
|
33
|
+
|
34
|
+
DateTime DateTime::nowUtc() {
|
35
|
+
#if defined(_POSIX_SOURCE) || defined(HAVE_GETTIMEOFDAY)
|
36
|
+
struct timeval tv;
|
37
|
+
gettimeofday(&tv, 0);
|
38
|
+
return fromUtcTimeT(tv.tv_sec, tv.tv_usec, 6);
|
39
|
+
#elif defined(HAVE_FTIME)
|
40
|
+
timeb tb;
|
41
|
+
ftime(&tb);
|
42
|
+
return fromUtcTimeT(tb.time, tb.millitm);
|
43
|
+
#else
|
44
|
+
return fromUtcTimeT(::time(0), 0);
|
45
|
+
#endif
|
46
|
+
}
|
47
|
+
|
48
|
+
DateTime DateTime::nowLocal() {
|
49
|
+
#if defined(_POSIX_SOURCE) || defined(HAVE_GETTIMEOFDAY)
|
50
|
+
struct timeval tv;
|
51
|
+
gettimeofday(&tv, 0);
|
52
|
+
return fromLocalTimeT(tv.tv_sec, tv.tv_usec, 6);
|
53
|
+
#elif defined(HAVE_FTIME)
|
54
|
+
timeb tb;
|
55
|
+
ftime(&tb);
|
56
|
+
return fromLocalTimeT(tb.time, tb.millitm);
|
57
|
+
#else
|
58
|
+
return fromLocalTimeT(::time(0), 0);
|
59
|
+
#endif
|
60
|
+
}
|
61
|
+
|
62
|
+
} // namespace FIX
|