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.
- 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,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
|