quickfix_ruby_ud 2.0.7-aarch64-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,30 @@
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_FIELDS_BASE_H
23
+ #define FIX_FIELDS_BASE_H
24
+
25
+ #include "Field.h"
26
+ #include "FixFields.h"
27
+
28
+ #undef Yield
29
+
30
+ #endif // FIX_FIELDS_BASE_H
@@ -0,0 +1,176 @@
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 "FileLog.h"
27
+
28
+ namespace FIX {
29
+ Log *FileLogFactory::create() {
30
+ if (++m_globalLogCount > 1) {
31
+ return m_globalLog;
32
+ }
33
+
34
+ if (m_path.size()) {
35
+ return new FileLog(m_path);
36
+ }
37
+
38
+ try {
39
+
40
+ const Dictionary &settings = m_settings.get();
41
+ std::string path = settings.getString(FILE_LOG_PATH);
42
+ std::string backupPath = path;
43
+
44
+ if (settings.has(FILE_LOG_BACKUP_PATH)) {
45
+ backupPath = settings.getString(FILE_LOG_BACKUP_PATH);
46
+ }
47
+
48
+ return m_globalLog = new FileLog(path, backupPath);
49
+ } catch (ConfigError &) {
50
+ m_globalLogCount--;
51
+ throw;
52
+ }
53
+ }
54
+
55
+ Log *FileLogFactory::create(const SessionID &s) {
56
+ if (m_path.size() && m_backupPath.size()) {
57
+ return new FileLog(m_path, m_backupPath, s);
58
+ }
59
+ if (m_path.size()) {
60
+ return new FileLog(m_path, s);
61
+ }
62
+
63
+ std::string path;
64
+ std::string backupPath;
65
+ Dictionary settings = m_settings.get(s);
66
+ path = settings.getString(FILE_LOG_PATH);
67
+ backupPath = path;
68
+ if (settings.has(FILE_LOG_BACKUP_PATH)) {
69
+ backupPath = settings.getString(FILE_LOG_BACKUP_PATH);
70
+ }
71
+
72
+ return new FileLog(path, backupPath, s);
73
+ }
74
+
75
+ void FileLogFactory::destroy(Log *pLog) {
76
+ if (pLog != m_globalLog || --m_globalLogCount == 0) {
77
+ delete pLog;
78
+ }
79
+ }
80
+
81
+ FileLog::FileLog(const std::string &path) { init(path, path, "GLOBAL"); }
82
+
83
+ FileLog::FileLog(const std::string &path, const std::string &backupPath) { init(path, backupPath, "GLOBAL"); }
84
+
85
+ FileLog::FileLog(const std::string &path, const SessionID &s) { init(path, path, generatePrefix(s)); }
86
+
87
+ FileLog::FileLog(const std::string &path, const std::string &backupPath, const SessionID &s) {
88
+ init(path, backupPath, generatePrefix(s));
89
+ }
90
+
91
+ std::string FileLog::generatePrefix(const SessionID &s) {
92
+ const std::string &begin = s.getBeginString().getString();
93
+ const std::string &sender = s.getSenderCompID().getString();
94
+ const std::string &target = s.getTargetCompID().getString();
95
+ const std::string &qualifier = s.getSessionQualifier();
96
+
97
+ std::string prefix = begin + "-" + sender + "-" + target;
98
+ if (qualifier.size()) {
99
+ prefix += "-" + qualifier;
100
+ }
101
+
102
+ return prefix;
103
+ }
104
+
105
+ void FileLog::init(std::string path, std::string backupPath, const std::string &prefix) {
106
+ file_mkdir(path.c_str());
107
+ file_mkdir(backupPath.c_str());
108
+
109
+ if (path.empty()) {
110
+ path = ".";
111
+ }
112
+ if (backupPath.empty()) {
113
+ backupPath = path;
114
+ }
115
+
116
+ m_fullPrefix = file_appendpath(path, prefix + ".");
117
+ m_fullBackupPrefix = file_appendpath(backupPath, prefix + ".");
118
+
119
+ m_messagesFileName = m_fullPrefix + "messages.current.log";
120
+ m_eventFileName = m_fullPrefix + "event.current.log";
121
+
122
+ m_messages.open(m_messagesFileName.c_str(), std::ios::out | std::ios::app);
123
+ if (!m_messages.is_open()) {
124
+ throw ConfigError("Could not open messages file: " + m_messagesFileName);
125
+ }
126
+ m_event.open(m_eventFileName.c_str(), std::ios::out | std::ios::app);
127
+ if (!m_event.is_open()) {
128
+ throw ConfigError("Could not open event file: " + m_eventFileName);
129
+ }
130
+ }
131
+
132
+ FileLog::~FileLog() {
133
+ m_messages.close();
134
+ m_event.close();
135
+ }
136
+
137
+ void FileLog::clear() {
138
+ m_messages.close();
139
+ m_event.close();
140
+
141
+ m_messages.open(m_messagesFileName.c_str(), std::ios::out | std::ios::trunc);
142
+ m_event.open(m_eventFileName.c_str(), std::ios::out | std::ios::trunc);
143
+ }
144
+
145
+ void FileLog::backup() {
146
+ m_messages.close();
147
+ m_event.close();
148
+
149
+ int i = 0;
150
+ while (true) {
151
+ std::stringstream messagesFileName;
152
+ std::stringstream eventFileName;
153
+
154
+ messagesFileName << m_fullBackupPrefix << "messages.backup." << ++i << ".log";
155
+ eventFileName << m_fullBackupPrefix << "event.backup." << i << ".log";
156
+ FILE *messagesLogFile = file_fopen(messagesFileName.str().c_str(), "r");
157
+ FILE *eventLogFile = file_fopen(eventFileName.str().c_str(), "r");
158
+
159
+ if (messagesLogFile == NULL && eventLogFile == NULL) {
160
+ file_rename(m_messagesFileName.c_str(), messagesFileName.str().c_str());
161
+ file_rename(m_eventFileName.c_str(), eventFileName.str().c_str());
162
+ m_messages.open(m_messagesFileName.c_str(), std::ios::out | std::ios::trunc);
163
+ m_event.open(m_eventFileName.c_str(), std::ios::out | std::ios::trunc);
164
+ return;
165
+ }
166
+
167
+ if (messagesLogFile != NULL) {
168
+ file_fclose(messagesLogFile);
169
+ }
170
+ if (eventLogFile != NULL) {
171
+ file_fclose(eventLogFile);
172
+ }
173
+ }
174
+ }
175
+
176
+ } // namespace FIX
@@ -0,0 +1,110 @@
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_FILELOG_H
23
+ #define FIX_FILELOG_H
24
+
25
+ #ifdef _MSC_VER
26
+ #pragma warning(disable : 4503 4355 4786 4290)
27
+ #endif
28
+
29
+ #include "Log.h"
30
+ #include "SessionSettings.h"
31
+ #include <fstream>
32
+
33
+ namespace FIX {
34
+ /**
35
+ * Creates a file based implementation of Log
36
+ *
37
+ * This stores all log events into flat files
38
+ */
39
+ class FileLogFactory : public LogFactory {
40
+ public:
41
+ FileLogFactory(const SessionSettings &settings)
42
+ : m_settings(settings),
43
+ m_globalLog(0),
44
+ m_globalLogCount(0) {};
45
+ FileLogFactory(const std::string &path)
46
+ : m_path(path),
47
+ m_backupPath(path),
48
+ m_globalLog(0),
49
+ m_globalLogCount(0) {};
50
+ FileLogFactory(const std::string &path, const std::string &backupPath)
51
+ : m_path(path),
52
+ m_backupPath(backupPath),
53
+ m_globalLog(0),
54
+ m_globalLogCount(0) {};
55
+
56
+ public:
57
+ Log *create();
58
+ Log *create(const SessionID &);
59
+ void destroy(Log *log);
60
+
61
+ private:
62
+ std::string m_path;
63
+ std::string m_backupPath;
64
+ SessionSettings m_settings;
65
+ Log *m_globalLog;
66
+ int m_globalLogCount;
67
+ };
68
+
69
+ /**
70
+ * File based implementation of Log
71
+ *
72
+ * Two files are created by this implementation. One for messages,
73
+ * and one for events.
74
+ *
75
+ */
76
+ class FileLog : public Log {
77
+ public:
78
+ FileLog(const std::string &path);
79
+ FileLog(const std::string &path, const std::string &backupPath);
80
+ FileLog(const std::string &path, const SessionID &sessionID);
81
+ FileLog(const std::string &path, const std::string &backupPath, const SessionID &sessionID);
82
+ virtual ~FileLog();
83
+
84
+ void clear();
85
+ void backup();
86
+
87
+ void onIncoming(const std::string &value) {
88
+ m_messages << UtcTimeStampConvertor::convert(UtcTimeStamp::now(), 9) << " : " << value << std::endl;
89
+ }
90
+ void onOutgoing(const std::string &value) {
91
+ m_messages << UtcTimeStampConvertor::convert(UtcTimeStamp::now(), 9) << " : " << value << std::endl;
92
+ }
93
+ void onEvent(const std::string &value) {
94
+ m_event << UtcTimeStampConvertor::convert(UtcTimeStamp::now(), 9) << " : " << value << std::endl;
95
+ }
96
+
97
+ private:
98
+ std::string generatePrefix(const SessionID &sessionID);
99
+ void init(std::string path, std::string backupPath, const std::string &prefix);
100
+
101
+ std::ofstream m_messages;
102
+ std::ofstream m_event;
103
+ std::string m_messagesFileName;
104
+ std::string m_eventFileName;
105
+ std::string m_fullPrefix;
106
+ std::string m_fullBackupPrefix;
107
+ };
108
+ } // namespace FIX
109
+
110
+ #endif // FIX_LOG_H
@@ -0,0 +1,369 @@
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 "FileStore.h"
27
+ #include "Parser.h"
28
+ #include "SessionID.h"
29
+ #include "Utility.h"
30
+ #include <fstream>
31
+ #include <inttypes.h>
32
+ #include <sys/stat.h>
33
+
34
+ namespace {
35
+ auto const seqNumFileFormat = "%" + std::to_string(std::numeric_limits<uint64_t>::digits10 + 1) + "."
36
+ + std::to_string(std::numeric_limits<uint64_t>::digits10 + 1) + SCNu64;
37
+
38
+ auto const seqNumPairFileFormat = (seqNumFileFormat + " : " + seqNumFileFormat);
39
+
40
+ auto constexpr sizeOf64BitSeqNumFile = 43;
41
+ } // namespace
42
+ namespace FIX {
43
+ FileStore::FileStore(const UtcTimeStamp &now, std::string path, const SessionID &sessionID)
44
+ : m_cache(now),
45
+ m_msgFile(0),
46
+ m_headerFile(0),
47
+ m_seqNumsFile(0),
48
+ m_sessionFile(0) {
49
+ file_mkdir(path.c_str());
50
+
51
+ if (path.empty()) {
52
+ path = ".";
53
+ }
54
+ const std::string &begin = sessionID.getBeginString().getString();
55
+ const std::string &sender = sessionID.getSenderCompID().getString();
56
+ const std::string &target = sessionID.getTargetCompID().getString();
57
+ const std::string &qualifier = sessionID.getSessionQualifier();
58
+
59
+ std::string sessionid = begin + "-" + sender + "-" + target;
60
+ if (qualifier.size()) {
61
+ sessionid += "-" + qualifier;
62
+ }
63
+
64
+ std::string prefix = file_appendpath(path, sessionid + ".");
65
+
66
+ m_msgFileName = prefix + "body";
67
+ m_headerFileName = prefix + "header";
68
+ m_seqNumsFileName = prefix + "seqnums";
69
+ m_sessionFileName = prefix + "session";
70
+
71
+ try {
72
+ open(false);
73
+ } catch (IOException &e) {
74
+ throw ConfigError(e.what());
75
+ }
76
+ }
77
+
78
+ FileStore::~FileStore() {
79
+ if (m_msgFile) {
80
+ fclose(m_msgFile);
81
+ }
82
+ if (m_headerFile) {
83
+ fclose(m_headerFile);
84
+ }
85
+ if (m_seqNumsFile) {
86
+ fclose(m_seqNumsFile);
87
+ }
88
+ if (m_sessionFile) {
89
+ fclose(m_sessionFile);
90
+ }
91
+ }
92
+
93
+ void FileStore::open(bool deleteFile) {
94
+ if (m_msgFile) {
95
+ fclose(m_msgFile);
96
+ }
97
+ if (m_headerFile) {
98
+ fclose(m_headerFile);
99
+ }
100
+ if (m_seqNumsFile) {
101
+ fclose(m_seqNumsFile);
102
+ }
103
+ if (m_sessionFile) {
104
+ fclose(m_sessionFile);
105
+ }
106
+
107
+ m_msgFile = 0;
108
+ m_headerFile = 0;
109
+ m_seqNumsFile = 0;
110
+ m_sessionFile = 0;
111
+
112
+ if (deleteFile) {
113
+ file_unlink(m_msgFileName.c_str());
114
+ file_unlink(m_headerFileName.c_str());
115
+ file_unlink(m_seqNumsFileName.c_str());
116
+ file_unlink(m_sessionFileName.c_str());
117
+ }
118
+
119
+ populateCache();
120
+ m_msgFile = file_fopen(m_msgFileName.c_str(), "r+");
121
+ if (!m_msgFile) {
122
+ m_msgFile = file_fopen(m_msgFileName.c_str(), "w+");
123
+ }
124
+ if (!m_msgFile) {
125
+ throw ConfigError("Could not open body file: " + m_msgFileName + " " + error_strerror());
126
+ }
127
+
128
+ m_headerFile = file_fopen(m_headerFileName.c_str(), "r+");
129
+ if (!m_headerFile) {
130
+ m_headerFile = file_fopen(m_headerFileName.c_str(), "w+");
131
+ }
132
+ if (!m_headerFile) {
133
+ throw ConfigError("Could not open header file: " + m_headerFileName + " " + error_strerror());
134
+ }
135
+
136
+ m_seqNumsFile = file_fopen(m_seqNumsFileName.c_str(), "r+");
137
+ if (!m_seqNumsFile) {
138
+ m_seqNumsFile = file_fopen(m_seqNumsFileName.c_str(), "w+");
139
+ }
140
+ if (!m_seqNumsFile) {
141
+ throw ConfigError("Could not open seqnums file: " + m_seqNumsFileName + " " + error_strerror());
142
+ }
143
+
144
+ bool setCreationTime = false;
145
+ m_sessionFile = file_fopen(m_sessionFileName.c_str(), "r");
146
+ if (!m_sessionFile) {
147
+ setCreationTime = true;
148
+ } else {
149
+ fclose(m_sessionFile);
150
+ }
151
+
152
+ m_sessionFile = file_fopen(m_sessionFileName.c_str(), "r+");
153
+ if (!m_sessionFile) {
154
+ m_sessionFile = file_fopen(m_sessionFileName.c_str(), "w+");
155
+ }
156
+ if (!m_sessionFile) {
157
+ throw ConfigError("Could not open session file " + error_strerror());
158
+ }
159
+ if (setCreationTime) {
160
+ setSession();
161
+ }
162
+
163
+ setNextSenderMsgSeqNum(getNextSenderMsgSeqNum());
164
+ setNextTargetMsgSeqNum(getNextTargetMsgSeqNum());
165
+ }
166
+
167
+ void FileStore::populateCache() {
168
+ FILE *headerFile = file_fopen(m_headerFileName.c_str(), "r+");
169
+ if (headerFile) {
170
+ SEQNUM msgSeqNum;
171
+ long offset;
172
+ std::size_t size;
173
+
174
+ while (FILE_FSCANF(headerFile, "%" SCNu64 ",%ld,%zu ", &msgSeqNum, &offset, &size) == 3) {
175
+ std::pair<NumToOffset::iterator, bool> it
176
+ = m_offsets.insert(NumToOffset::value_type(msgSeqNum, std::make_pair(offset, size)));
177
+
178
+ if (it.second == false) {
179
+ it.first->second = std::make_pair(offset, size);
180
+ }
181
+ }
182
+ fclose(headerFile);
183
+ }
184
+
185
+ struct stat seqNumsFileStat;
186
+ FILE *seqNumsFile = file_fopen(m_seqNumsFileName.c_str(), "r+");
187
+
188
+ if (seqNumsFile && stat(m_seqNumsFileName.c_str(), &seqNumsFileStat) == 0) {
189
+ if (seqNumsFileStat.st_size == sizeOf64BitSeqNumFile) {
190
+ SEQNUM sender, target;
191
+ if (FILE_FSCANF(seqNumsFile, "%" SCNu64 " : %" SCNu64, &sender, &target) == 2) {
192
+ m_cache.setNextSenderMsgSeqNum(sender);
193
+ m_cache.setNextTargetMsgSeqNum(target);
194
+ }
195
+ } else // try old int seq num file format
196
+ {
197
+ int sender, target;
198
+ if (FILE_FSCANF(seqNumsFile, "%d : %d", &sender, &target) == 2) {
199
+ m_cache.setNextSenderMsgSeqNum(sender);
200
+ m_cache.setNextTargetMsgSeqNum(target);
201
+ }
202
+ }
203
+ fclose(seqNumsFile);
204
+ }
205
+
206
+ FILE *sessionFile = file_fopen(m_sessionFileName.c_str(), "r+");
207
+ if (sessionFile) {
208
+ char time[22];
209
+ #ifdef HAVE_FSCANF_S
210
+ int result = FILE_FSCANF(sessionFile, "%s", time, 22);
211
+ #else
212
+ int result = FILE_FSCANF(sessionFile, "%s", time);
213
+ #endif
214
+ if (result == 1) {
215
+ m_cache.setCreationTime(UtcTimeStampConvertor::convert(time));
216
+ }
217
+ fclose(sessionFile);
218
+ }
219
+ }
220
+
221
+ MessageStore *FileStoreFactory::create(const UtcTimeStamp &now, const SessionID &sessionID) {
222
+ if (m_path.size()) {
223
+ return new FileStore(now, m_path, sessionID);
224
+ }
225
+
226
+ std::string path;
227
+ Dictionary settings = m_settings.get(sessionID);
228
+ path = settings.getString(FILE_STORE_PATH);
229
+ return new FileStore(now, path, sessionID);
230
+ }
231
+
232
+ void FileStoreFactory::destroy(MessageStore *pStore) { delete pStore; }
233
+
234
+ bool FileStore::set(SEQNUM msgSeqNum, const std::string &msg) EXCEPT(IOException) {
235
+ if (fseek(m_msgFile, 0, SEEK_END)) {
236
+ throw IOException("Cannot seek to end of " + m_msgFileName);
237
+ }
238
+ if (fseek(m_headerFile, 0, SEEK_END)) {
239
+ throw IOException("Cannot seek to end of " + m_headerFileName);
240
+ }
241
+
242
+ long offset = ftell(m_msgFile);
243
+ if (offset < 0) {
244
+ throw IOException("Unable to get file pointer position from " + m_msgFileName);
245
+ }
246
+ std::size_t size = msg.size();
247
+
248
+ if (fprintf(m_headerFile, "%" SCNu64 ",%ld,%zu ", msgSeqNum, offset, size) < 0) {
249
+ throw IOException("Unable to write to file " + m_headerFileName);
250
+ }
251
+ std::pair<NumToOffset::iterator, bool> it
252
+ = m_offsets.insert(NumToOffset::value_type(msgSeqNum, std::make_pair(offset, size)));
253
+ if (it.second == false) {
254
+ it.first->second = std::make_pair(offset, size);
255
+ }
256
+ fwrite(msg.c_str(), sizeof(char), msg.size(), m_msgFile);
257
+ if (ferror(m_msgFile)) {
258
+ throw IOException("Unable to write to file " + m_msgFileName);
259
+ }
260
+ if (fflush(m_msgFile) == EOF) {
261
+ throw IOException("Unable to flush file " + m_msgFileName);
262
+ }
263
+ if (fflush(m_headerFile) == EOF) {
264
+ throw IOException("Unable to flush file " + m_headerFileName);
265
+ }
266
+ return true;
267
+ }
268
+
269
+ void FileStore::get(SEQNUM begin, SEQNUM end, std::vector<std::string> &result) const EXCEPT(IOException) {
270
+ result.clear();
271
+ std::string msg;
272
+ for (auto i = begin; i <= end && i != 0; ++i) {
273
+ if (get(i, msg)) {
274
+ result.push_back(msg);
275
+ }
276
+ }
277
+ }
278
+
279
+ SEQNUM FileStore::getNextSenderMsgSeqNum() const EXCEPT(IOException) { return m_cache.getNextSenderMsgSeqNum(); }
280
+
281
+ SEQNUM FileStore::getNextTargetMsgSeqNum() const EXCEPT(IOException) { return m_cache.getNextTargetMsgSeqNum(); }
282
+
283
+ void FileStore::setNextSenderMsgSeqNum(SEQNUM value) EXCEPT(IOException) {
284
+ m_cache.setNextSenderMsgSeqNum(value);
285
+ setSeqNum();
286
+ }
287
+
288
+ void FileStore::setNextTargetMsgSeqNum(SEQNUM value) EXCEPT(IOException) {
289
+ m_cache.setNextTargetMsgSeqNum(value);
290
+ setSeqNum();
291
+ }
292
+
293
+ void FileStore::incrNextSenderMsgSeqNum() EXCEPT(IOException) {
294
+ m_cache.incrNextSenderMsgSeqNum();
295
+ setSeqNum();
296
+ }
297
+
298
+ void FileStore::incrNextTargetMsgSeqNum() EXCEPT(IOException) {
299
+ m_cache.incrNextTargetMsgSeqNum();
300
+ setSeqNum();
301
+ }
302
+
303
+ UtcTimeStamp FileStore::getCreationTime() const EXCEPT(IOException) { return m_cache.getCreationTime(); }
304
+
305
+ void FileStore::reset(const UtcTimeStamp &now) EXCEPT(IOException) {
306
+ try {
307
+ m_cache.reset(now);
308
+ m_offsets.clear();
309
+ open(true);
310
+ setSession();
311
+ } catch (std::exception &e) {
312
+ throw IOException(e.what());
313
+ }
314
+ }
315
+
316
+ void FileStore::refresh() EXCEPT(IOException) {
317
+ try {
318
+ m_cache.reset(UtcTimeStamp::now());
319
+ m_offsets.clear();
320
+ open(false);
321
+ } catch (std::exception &e) {
322
+ throw IOException(e.what());
323
+ }
324
+ }
325
+
326
+ void FileStore::setSeqNum() {
327
+ rewind(m_seqNumsFile);
328
+ fprintf(m_seqNumsFile, seqNumPairFileFormat.c_str(), getNextSenderMsgSeqNum(), getNextTargetMsgSeqNum());
329
+ if (ferror(m_seqNumsFile)) {
330
+ throw IOException("Unable to write to file " + m_seqNumsFileName);
331
+ }
332
+ if (fflush(m_seqNumsFile)) {
333
+ throw IOException("Unable to flush file " + m_seqNumsFileName);
334
+ }
335
+ }
336
+
337
+ void FileStore::setSession() {
338
+ rewind(m_sessionFile);
339
+ fprintf(m_sessionFile, "%s", UtcTimeStampConvertor::convert(m_cache.getCreationTime()).c_str());
340
+ if (ferror(m_sessionFile)) {
341
+ throw IOException("Unable to write to file " + m_sessionFileName);
342
+ }
343
+ if (fflush(m_sessionFile)) {
344
+ throw IOException("Unable to flush file " + m_sessionFileName);
345
+ }
346
+ }
347
+
348
+ bool FileStore::get(SEQNUM msgSeqNum, std::string &msg) const EXCEPT(IOException) {
349
+ NumToOffset::const_iterator find = m_offsets.find(msgSeqNum);
350
+ if (find == m_offsets.end()) {
351
+ return false;
352
+ }
353
+ const OffsetSize &offset = find->second;
354
+ if (fseek(m_msgFile, offset.first, SEEK_SET)) {
355
+ throw IOException("Unable to seek in file " + m_msgFileName);
356
+ }
357
+ char *buffer = new char[offset.second + 1];
358
+ size_t result = fread(buffer, sizeof(char), offset.second, m_msgFile);
359
+ if (ferror(m_msgFile) || result != (size_t)offset.second) {
360
+ delete[] buffer;
361
+ throw IOException("Unable to read from file " + m_msgFileName);
362
+ }
363
+ buffer[offset.second] = 0;
364
+ msg = buffer;
365
+ delete[] buffer;
366
+ return true;
367
+ }
368
+
369
+ } // namespace FIX