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,639 @@
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 "Utility.h"
27
+
28
+ #ifdef USING_STREAMS
29
+ #include <stropts.h>
30
+ #include <sys/conf.h>
31
+ #endif
32
+ #include <algorithm>
33
+ #include <cstdarg>
34
+ #include <fstream>
35
+ #include <iostream>
36
+ #include <math.h>
37
+ #include <sstream>
38
+ #include <stdio.h>
39
+ #include <string.h>
40
+
41
+ namespace FIX {
42
+ std::string error_strerror(decltype(errno) error_number) {
43
+ return "(errno[" + std::to_string(error_number) + "]:" + std::strerror(error_number) + ")";
44
+ }
45
+
46
+ std::string error_strerror() { return error_strerror(errno); }
47
+
48
+ #ifdef _MSC_VER
49
+ std::string error_wsaerror(int wsa_error_number) {
50
+ auto format = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS
51
+ | FORMAT_MESSAGE_MAX_WIDTH_MASK;
52
+ LPSTR buffer = NULL;
53
+
54
+ FormatMessageA(format, 0, wsa_error_number, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL);
55
+
56
+ return "(wsaerror[" + std::to_string(wsa_error_number) + "]:" + buffer + ")";
57
+ }
58
+
59
+ std::string error_wsaerror() { return error_wsaerror(WSAGetLastError()); }
60
+ #endif
61
+
62
+ void string_replace(const std::string &oldValue, const std::string &newValue, std::string &value) {
63
+ for (std::string::size_type pos = value.find(oldValue); pos != std::string::npos; pos = value.find(oldValue, pos)) {
64
+ value.replace(pos, oldValue.size(), newValue);
65
+ pos += newValue.size();
66
+ }
67
+ }
68
+
69
+ char *string_concat(const char *a, ...) {
70
+ char *cp, *argp, *res;
71
+
72
+ /* Pass one --- find length of required string */
73
+
74
+ std::size_t len = 0;
75
+ va_list adummy;
76
+
77
+ if (a == 0) {
78
+ return 0;
79
+ }
80
+
81
+ va_start(adummy, a);
82
+
83
+ len = strlen(a);
84
+ while ((cp = va_arg(adummy, char *)) != 0) {
85
+ len += strlen(cp);
86
+ }
87
+
88
+ va_end(adummy);
89
+
90
+ /* Allocate the required string */
91
+
92
+ res = new char[len + 1];
93
+ cp = res;
94
+ *cp = '\0';
95
+
96
+ /* Pass two --- copy the argument strings into the result space */
97
+
98
+ va_start(adummy, a);
99
+
100
+ strcpy(cp, a);
101
+ cp += strlen(a);
102
+ while ((argp = va_arg(adummy, char *)) != 0) {
103
+ strcpy(cp, argp);
104
+ cp += strlen(argp);
105
+ }
106
+
107
+ va_end(adummy);
108
+
109
+ /* Return the result string */
110
+
111
+ return res;
112
+ }
113
+
114
+ std::string string_toUpper(const std::string &value) {
115
+ std::string copy = value;
116
+ std::transform(copy.begin(), copy.end(), copy.begin(), toupper);
117
+ return copy;
118
+ }
119
+
120
+ std::string string_toLower(const std::string &value) {
121
+ std::string copy = value;
122
+ std::transform(copy.begin(), copy.end(), copy.begin(), tolower);
123
+ return copy;
124
+ }
125
+
126
+ std::string string_strip(const std::string &value) {
127
+ if (!value.size()) {
128
+ return value;
129
+ }
130
+
131
+ size_t startPos = value.find_first_not_of(" \t\r\n");
132
+ size_t endPos = value.find_last_not_of(" \t\r\n");
133
+
134
+ if (startPos == std::string::npos) {
135
+ return value;
136
+ }
137
+
138
+ return std::string(value, startPos, endPos - startPos + 1);
139
+ }
140
+
141
+ std::set<std::string> string_split(const std::string &value, const char delimiter) {
142
+ std::set<std::string> subStrings;
143
+ std::size_t start = 0;
144
+ for (std::size_t pos = 0; pos < value.size(); ++pos) {
145
+ if (value[pos] == delimiter) {
146
+ if (pos - start > 1) {
147
+ subStrings.insert(value.substr(start, pos - start));
148
+ }
149
+ start = pos + 1;
150
+ }
151
+ }
152
+ if (start < value.size()) {
153
+ subStrings.insert(value.substr(start, value.size() - start));
154
+ }
155
+ return subStrings;
156
+ }
157
+
158
+ void socket_init() {
159
+ #ifdef _MSC_VER
160
+ WORD version = MAKEWORD(2, 2);
161
+ WSADATA data;
162
+ WSAStartup(version, &data);
163
+ #else
164
+ struct sigaction sa;
165
+ sa.sa_handler = SIG_IGN;
166
+ sigemptyset(&sa.sa_mask);
167
+ sa.sa_flags = 0;
168
+ sigaction(SIGPIPE, &sa, 0);
169
+ #endif
170
+ }
171
+
172
+ void socket_term() {
173
+ #ifdef _MSC_VER
174
+ WSACleanup();
175
+ #endif
176
+ }
177
+
178
+ std::string socket_error() {
179
+ #ifdef _MSC_VER
180
+ return error_wsaerror();
181
+ #else
182
+ return error_strerror();
183
+ #endif
184
+ }
185
+
186
+ int socket_bind(socket_handle socket, const char *hostname, int port) {
187
+ sockaddr_in address;
188
+ socklen_t socklen;
189
+
190
+ address.sin_family = PF_INET;
191
+ address.sin_port = htons(port);
192
+ if (!hostname || !*hostname) {
193
+ address.sin_addr.s_addr = INADDR_ANY;
194
+ } else {
195
+ address.sin_addr.s_addr = inet_addr(hostname);
196
+ }
197
+ socklen = sizeof(address);
198
+
199
+ return bind(socket, reinterpret_cast<sockaddr *>(&address), socklen);
200
+ }
201
+
202
+ socket_handle socket_createAcceptor(int port, bool reuse) {
203
+ socket_handle socket = ::socket(PF_INET, SOCK_STREAM, 0);
204
+ if (socket == INVALID_SOCKET_HANDLE) {
205
+ return INVALID_SOCKET_HANDLE;
206
+ }
207
+
208
+ sockaddr_in address;
209
+ socklen_t socklen;
210
+
211
+ address.sin_family = PF_INET;
212
+ address.sin_port = htons(port);
213
+ address.sin_addr.s_addr = INADDR_ANY;
214
+ socklen = sizeof(address);
215
+ if (reuse) {
216
+ socket_setsockopt(socket, SO_REUSEADDR);
217
+ }
218
+
219
+ int result = bind(socket, reinterpret_cast<sockaddr *>(&address), socklen);
220
+
221
+ if (result == BIND_SOCKET_ERROR) {
222
+ return INVALID_SOCKET_HANDLE;
223
+ }
224
+ result = listen(socket, SOMAXCONN);
225
+ if (result == LISTEN_SOCKET_ERROR) {
226
+ return INVALID_SOCKET_HANDLE;
227
+ }
228
+ return socket;
229
+ }
230
+
231
+ socket_handle socket_createConnector() { return ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); }
232
+
233
+ int socket_connect(socket_handle socket, const char *address, int port) {
234
+ const char *hostname = socket_hostname(address);
235
+ if (hostname == 0) {
236
+ #ifdef _MSC_VER
237
+ // In a case of Windows + MSVC, select() does not fire a write event for
238
+ // a bare socket (no connection ever attempted). Therefore the later
239
+ // logic, which is based on unconditional continuation with select(),
240
+ // leads to a deadlock (the select never gets back) for the connecting session.
241
+ // So keep going ahead with a bad address to issue a faulty connect.
242
+ hostname = address;
243
+ #else
244
+ return -1;
245
+ #endif
246
+ }
247
+
248
+ sockaddr_in addr;
249
+ addr.sin_family = PF_INET;
250
+ addr.sin_port = htons(port);
251
+ addr.sin_addr.s_addr = inet_addr(hostname);
252
+
253
+ int result = connect(socket, reinterpret_cast<sockaddr *>(&addr), sizeof(addr));
254
+
255
+ return result;
256
+ }
257
+
258
+ socket_handle socket_accept(socket_handle s) {
259
+ if (!socket_isValid(s)) {
260
+ return INVALID_SOCKET_HANDLE;
261
+ }
262
+ return accept(s, 0, 0);
263
+ }
264
+
265
+ ssize_t socket_recv(socket_handle s, char *buf, size_t length) {
266
+ #ifdef _MSC_VER
267
+ return recv(s, buf, static_cast<int>(length), 0);
268
+ #else
269
+ return recv(s, buf, length, 0);
270
+ #endif
271
+ }
272
+
273
+ ssize_t socket_send(socket_handle s, const char *msg, size_t length) {
274
+ #ifdef _MSC_VER
275
+ return send(s, msg, static_cast<int>(length), 0);
276
+ #else
277
+ return send(s, msg, length, 0);
278
+ #endif
279
+ }
280
+
281
+ void socket_close(socket_handle s) {
282
+ shutdown(s, 2);
283
+ #ifdef _MSC_VER
284
+ closesocket(s);
285
+ #else
286
+ close(s);
287
+ #endif
288
+ }
289
+
290
+ std::string socket_get_last_error() {
291
+ std::stringstream errorMessage;
292
+ #ifdef _MSC_VER
293
+ int winsockErrorCode = WSAGetLastError();
294
+
295
+ char *s = NULL;
296
+ FormatMessageA(
297
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
298
+ NULL,
299
+ winsockErrorCode,
300
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
301
+ (LPSTR)&s,
302
+ 0,
303
+ NULL);
304
+ errorMessage << "Winsock error " << winsockErrorCode << ": " << s;
305
+ LocalFree(s);
306
+ #else
307
+ int errorNumber = errno;
308
+ errorMessage << "Winsock error " << errorNumber << ": " << strerror(errorNumber);
309
+ #endif
310
+ return errorMessage.str();
311
+ }
312
+
313
+ bool socket_fionread(socket_handle s, int &bytes) {
314
+ bytes = 0;
315
+ #if defined(_MSC_VER)
316
+ return ::ioctlsocket(s, FIONREAD, &((unsigned long &)bytes)) == 0;
317
+ #elif defined(USING_STREAMS)
318
+ return ::ioctl(s, I_NREAD, &bytes) >= 0;
319
+ #else
320
+ return ::ioctl(s, FIONREAD, &bytes) == 0;
321
+ #endif
322
+ }
323
+
324
+ bool socket_disconnected(socket_handle s) {
325
+ char byte;
326
+ return ::recv(s, &byte, sizeof(byte), MSG_PEEK) <= 0;
327
+ }
328
+
329
+ int socket_setsockopt(socket_handle s, int opt) {
330
+ #ifdef _MSC_VER
331
+ BOOL optval = TRUE;
332
+ #else
333
+ int optval = 1;
334
+ #endif
335
+ return socket_setsockopt(s, opt, optval);
336
+ }
337
+
338
+ int socket_setsockopt(socket_handle s, int opt, int optval) {
339
+ int level = SOL_SOCKET;
340
+ if (opt == TCP_NODELAY) {
341
+ level = IPPROTO_TCP;
342
+ }
343
+
344
+ #ifdef _MSC_VER
345
+ return ::setsockopt(s, level, opt, (char *)&optval, sizeof(optval));
346
+ #else
347
+ return ::setsockopt(s, level, opt, &optval, sizeof(optval));
348
+ #endif
349
+ }
350
+
351
+ int socket_getsockopt(socket_handle s, int opt, int &optval) {
352
+ int level = SOL_SOCKET;
353
+ if (opt == TCP_NODELAY) {
354
+ level = IPPROTO_TCP;
355
+ }
356
+
357
+ #ifdef _MSC_VER
358
+ int length = sizeof(int);
359
+ #else
360
+ socklen_t length = sizeof(socklen_t);
361
+ #endif
362
+
363
+ return ::getsockopt(s, level, opt, (char *)&optval, &length);
364
+ }
365
+
366
+ #ifndef _MSC_VER
367
+ int socket_fcntl(int s, int opt, int arg) { return ::fcntl(s, opt, arg); }
368
+
369
+ int socket_getfcntlflag(int s, int arg) { return socket_fcntl(s, F_GETFL, arg); }
370
+
371
+ int socket_setfcntlflag(int s, int arg) { return socket_fcntl(s, F_SETFL, arg); }
372
+ #endif
373
+
374
+ void socket_setnonblock(socket_handle socket) {
375
+ #ifdef _MSC_VER
376
+ u_long opt = 1;
377
+ ::ioctlsocket(socket, FIONBIO, &opt);
378
+ #else
379
+ socket_setfcntlflag(socket, O_NONBLOCK);
380
+ #endif
381
+ }
382
+ bool socket_isValid(socket_handle socket) {
383
+ #ifdef _MSC_VER
384
+ return socket != INVALID_SOCKET_HANDLE;
385
+ #else
386
+ return socket >= 0;
387
+ #endif
388
+ }
389
+
390
+ #ifndef _MSC_VER
391
+ bool socket_isBad(int s) {
392
+ struct stat buf;
393
+ fstat(s, &buf);
394
+ return errno == EBADF;
395
+ }
396
+ #endif
397
+
398
+ void socket_invalidate(socket_handle &socket) { socket = INVALID_SOCKET_HANDLE; }
399
+
400
+ short socket_hostport(socket_handle socket) {
401
+ struct sockaddr_in addr;
402
+ socklen_t len = sizeof(addr);
403
+ if (getsockname(socket, (struct sockaddr *)&addr, &len) != 0) {
404
+ return 0;
405
+ }
406
+
407
+ return ntohs(addr.sin_port);
408
+ }
409
+
410
+ const char *socket_hostname(socket_handle socket) {
411
+ struct sockaddr_in addr;
412
+ socklen_t len = sizeof(addr);
413
+ if (getsockname(socket, (struct sockaddr *)&addr, &len) != 0) {
414
+ return 0;
415
+ }
416
+
417
+ return inet_ntoa(addr.sin_addr);
418
+ }
419
+
420
+ const char *socket_hostname(const char *name) {
421
+ struct hostent *host_ptr = 0;
422
+ struct in_addr **paddr;
423
+ struct in_addr saddr;
424
+
425
+ #if (GETHOSTBYNAME_R_INPUTS_RESULT || GETHOSTBYNAME_R_RETURNS_RESULT)
426
+ hostent host;
427
+ char buf[1024];
428
+ int error;
429
+ #endif
430
+
431
+ saddr.s_addr = inet_addr(name);
432
+ if (saddr.s_addr != (unsigned)-1) {
433
+ return name;
434
+ }
435
+
436
+ #if GETHOSTBYNAME_R_INPUTS_RESULT
437
+ gethostbyname_r(name, &host, buf, sizeof(buf), &host_ptr, &error);
438
+ #elif GETHOSTBYNAME_R_RETURNS_RESULT
439
+ host_ptr = gethostbyname_r(name, &host, buf, sizeof(buf), &error);
440
+ #else
441
+ host_ptr = gethostbyname(name);
442
+ #endif
443
+
444
+ if (host_ptr == 0) {
445
+ return 0;
446
+ }
447
+
448
+ paddr = (struct in_addr **)host_ptr->h_addr_list;
449
+ return inet_ntoa(**paddr);
450
+ }
451
+
452
+ const char *socket_peername(socket_handle socket) {
453
+ struct sockaddr_in addr;
454
+ socklen_t len = sizeof(addr);
455
+ if (getpeername(socket, (struct sockaddr *)&addr, &len) < 0) {
456
+ return "UNKNOWN";
457
+ }
458
+ char *result = inet_ntoa(addr.sin_addr);
459
+ if (result) {
460
+ return result;
461
+ } else {
462
+ return "UNKNOWN";
463
+ }
464
+ }
465
+
466
+ std::pair<socket_handle, socket_handle> socket_createpair() {
467
+ #ifdef _MSC_VER
468
+ socket_handle acceptor = socket_createAcceptor(0, true);
469
+ const char *host = socket_hostname(acceptor);
470
+ short port = socket_hostport(acceptor);
471
+ socket_handle client = socket_createConnector();
472
+ socket_connect(client, "localhost", port);
473
+ socket_handle server = socket_accept(acceptor);
474
+ socket_close(acceptor);
475
+ return std::make_pair(client, server);
476
+ #else
477
+ socket_handle pair[2];
478
+ socketpair(AF_UNIX, SOCK_STREAM, 0, pair);
479
+ return std::make_pair(pair[0], pair[1]);
480
+ #endif
481
+ }
482
+
483
+ tm time_gmtime(const time_t *t) {
484
+ #ifdef _MSC_VER
485
+ #if (_MSC_VER >= 1400)
486
+ tm result;
487
+ gmtime_s(&result, t);
488
+ return result;
489
+ #else
490
+ return *gmtime(t);
491
+ #endif
492
+ #else
493
+ tm result;
494
+ return *gmtime_r(t, &result);
495
+ #endif
496
+ }
497
+
498
+ tm time_localtime(const time_t *t) {
499
+ #ifdef _MSC_VER
500
+ #if (_MSC_VER >= 1400)
501
+ tm result;
502
+ localtime_s(&result, t);
503
+ return result;
504
+ #else
505
+ return *localtime(t);
506
+ #endif
507
+ #else
508
+ tm result;
509
+ return *localtime_r(t, &result);
510
+ #endif
511
+ }
512
+
513
+ bool thread_spawn(THREAD_START_ROUTINE func, void *var, thread_id &thread) {
514
+ #ifdef _MSC_VER
515
+ thread_id result = 0;
516
+ unsigned int id = 0;
517
+ result = reinterpret_cast<thread_id>(_beginthreadex(NULL, 0, func, var, 0, &id));
518
+ if (result == 0) {
519
+ return false;
520
+ }
521
+ #else
522
+ thread_id result = 0;
523
+ if (pthread_create(&result, 0, func, var) != 0) {
524
+ return false;
525
+ }
526
+ #endif
527
+ thread = result;
528
+ return true;
529
+ }
530
+
531
+ bool thread_spawn(THREAD_START_ROUTINE func, void *var) {
532
+ thread_id thread = 0;
533
+ return thread_spawn(func, var, thread);
534
+ }
535
+
536
+ void thread_join(thread_id thread) {
537
+ #ifdef _MSC_VER
538
+ WaitForSingleObject((void *)thread, INFINITE);
539
+ CloseHandle(thread);
540
+ #else
541
+ pthread_join((pthread_t)thread, 0);
542
+ #endif
543
+ }
544
+
545
+ void thread_detach(thread_id thread) {
546
+ #ifdef _MSC_VER
547
+ CloseHandle(thread);
548
+ #else
549
+ pthread_t t = thread;
550
+ pthread_detach(t);
551
+ #endif
552
+ }
553
+
554
+ thread_id thread_self() {
555
+ #ifdef _MSC_VER
556
+ return GetCurrentThread();
557
+ #else
558
+ return pthread_self();
559
+ #endif
560
+ }
561
+
562
+ void process_sleep(double s) {
563
+ #ifdef _MSC_VER
564
+ Sleep((long)(s * 1000));
565
+ #else
566
+ timespec time, remainder;
567
+ double intpart;
568
+ time.tv_nsec = (long)(modf(s, &intpart) * 1e9);
569
+ time.tv_sec = (int)intpart;
570
+ while (nanosleep(&time, &remainder) == -1) {
571
+ time = remainder;
572
+ }
573
+ #endif
574
+ }
575
+
576
+ std::string file_separator() {
577
+ #ifdef _MSC_VER
578
+ return "\\";
579
+ #else
580
+ return "/";
581
+ #endif
582
+ }
583
+
584
+ void file_mkdir(const char *path) {
585
+ int length = (int)strlen(path);
586
+ std::string createPath = "";
587
+
588
+ for (const char *pos = path; (pos - path) <= length; ++pos) {
589
+ createPath += *pos;
590
+ if (*pos == '/' || *pos == '\\' || (pos - path) == length) {
591
+ #ifdef _MSC_VER
592
+ _mkdir(createPath.c_str());
593
+ #else
594
+ // use umask to override rwx for all
595
+ mkdir(createPath.c_str(), 0777);
596
+ #endif
597
+ }
598
+ }
599
+ }
600
+
601
+ FILE *file_fopen(const char *path, const char *mode) {
602
+ #ifdef _MSC_VER
603
+ return _fsopen(path, mode, _SH_DENYWR);
604
+ #else
605
+ return fopen(path, mode);
606
+ #endif
607
+ }
608
+
609
+ void file_fclose(FILE *file) { fclose(file); }
610
+
611
+ bool file_exists(const char *path) {
612
+ std::ifstream stream;
613
+ stream.open(path, std::ios_base::in);
614
+ if (stream.is_open()) {
615
+ stream.close();
616
+ return true;
617
+ }
618
+ return false;
619
+ }
620
+
621
+ void file_unlink(const char *path) {
622
+ #ifdef _MSC_VER
623
+ _unlink(path);
624
+ #else
625
+ unlink(path);
626
+ #endif
627
+ }
628
+
629
+ int file_rename(const char *oldpath, const char *newpath) { return rename(oldpath, newpath); }
630
+
631
+ std::string file_appendpath(const std::string &path, const std::string &file) {
632
+ const char last = path[path.size() - 1];
633
+ if (last == '/' || last == '\\') {
634
+ return std::string(path) + file;
635
+ } else {
636
+ return std::string(path) + file_separator() + file;
637
+ }
638
+ }
639
+ } // namespace FIX