diff --git a/.clang-format b/.clang-format
index 51d2aa3..18f4351 100644
--- a/.clang-format
+++ b/.clang-format
@@ -18,7 +18,7 @@ BreakBeforeBraces: Linux
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 80
-CommentPragmas: '^ IWYU pragma:'
+CommentPragmas: "^ IWYU pragma:"
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
@@ -27,7 +27,7 @@ DerivePointerBinding: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: true
IndentFunctionDeclarationAfterType: true
-IndentWidth: 4
+IndentWidth: 2
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: true
@@ -50,5 +50,5 @@ SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
Standard: c++14
SortIncludes: true
-TabWidth: 4
+TabWidth: 2
UseTab: Never
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/.name b/.idea/.name
deleted file mode 100644
index 6abfb67..0000000
--- a/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-GermanAirlinesVA_GAConnector
\ No newline at end of file
diff --git a/.idea/GermanAirlinesVA-GAConnector.iml b/.idea/GermanAirlinesVA-GAConnector.iml
deleted file mode 100644
index f08604b..0000000
--- a/.idea/GermanAirlinesVA-GAConnector.iml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index a55e7a1..0000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 79b3c94..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index ff0f9b0..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
deleted file mode 100644
index 2378106..0000000
--- a/.vscode/c_cpp_properties.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "configurations": [
- {
- "name": "Linux",
- "includePath": [
- "${workspaceFolder}/**"
- ],
- "defines": [],
- "compilerPath": "/opt/llvm-mingw/bin/clang++",
- "cStandard": "c17",
- "intelliSenseMode": "windows-clang-x64"
- }
- ],
- "version": 4
-}
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 0999cd5..0000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "name": "clang++-10 - Build and debug active file",
- "type": "cppdbg",
- "request": "launch",
- "program": "",
- "args": [],
- "stopAtEntry": false,
- "cwd": "${fileDirname}",
- "environment": [],
- "externalConsole": false,
- "MIMode": "lldb",
- "setupCommands": [
- {
- "description": "Enable pretty-printing for gdb",
- "text": "-enable-pretty-printing",
- "ignoreFailures": true
- },
- {
- "description": "Set Disassembly Flavor to Intel",
- "text": "-gdb-set disassembly-flavor intel",
- "ignoreFailures": true
- }
- ],
- "preLaunchTask": "C/C++: clang++-10 build active file",
- "miDebuggerPath": "/usr/bin/lldb-mi-10"
- }
- ]
-}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index cd358a6..6ca437e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,67 +1,7 @@
{
- "files.associations": {
- "thread": "cpp",
- "algorithm": "cpp",
- "array": "cpp",
- "atomic": "cpp",
- "bit": "cpp",
- "*.tcc": "cpp",
- "bitset": "cpp",
- "cctype": "cpp",
- "chrono": "cpp",
- "clocale": "cpp",
- "cmath": "cpp",
- "codecvt": "cpp",
- "condition_variable": "cpp",
- "cstdarg": "cpp",
- "cstddef": "cpp",
- "cstdint": "cpp",
- "cstdio": "cpp",
- "cstdlib": "cpp",
- "cstring": "cpp",
- "ctime": "cpp",
- "cwchar": "cpp",
- "cwctype": "cpp",
- "deque": "cpp",
- "forward_list": "cpp",
- "list": "cpp",
- "map": "cpp",
- "set": "cpp",
- "unordered_map": "cpp",
- "vector": "cpp",
- "exception": "cpp",
- "functional": "cpp",
- "iterator": "cpp",
- "memory": "cpp",
- "memory_resource": "cpp",
- "numeric": "cpp",
- "optional": "cpp",
- "random": "cpp",
- "ratio": "cpp",
- "regex": "cpp",
- "string": "cpp",
- "string_view": "cpp",
- "system_error": "cpp",
- "tuple": "cpp",
- "type_traits": "cpp",
- "utility": "cpp",
- "fstream": "cpp",
- "future": "cpp",
- "initializer_list": "cpp",
- "iomanip": "cpp",
- "iosfwd": "cpp",
- "iostream": "cpp",
- "istream": "cpp",
- "limits": "cpp",
- "mutex": "cpp",
- "new": "cpp",
- "ostream": "cpp",
- "shared_mutex": "cpp",
- "sstream": "cpp",
- "stdexcept": "cpp",
- "streambuf": "cpp",
- "cinttypes": "cpp",
- "typeinfo": "cpp",
- "valarray": "cpp"
- }
+ "cmake.generator": "Unix Makefiles",
+ "cmake.configureArgs": [
+ "-DIBM=ON"
+ ],
+ "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
deleted file mode 100644
index 2fc6150..0000000
--- a/.vscode/tasks.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "tasks": [
- {
- "type": "cppbuild",
- "label": "C/C++: clang++-10 build active file",
- "command": "/usr/bin/clang++-10",
- "args": [
- "-fdiagnostics-color=always",
- "-g",
- "${file}",
- "-o",
- "${fileDirname}/${fileBasenameNoExtension}"
- ],
- "options": {
- "cwd": "${fileDirname}"
- },
- "problemMatcher": [
- "$gcc"
- ],
- "group": {
- "kind": "build",
- "isDefault": true
- },
- "detail": "Task generated by Debugger."
- }
- ],
- "version": "2.0.0"
-}
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6047254..8473c7e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,9 +12,6 @@ set(PLUGIN_NAME GAConnector)
option(DEBUG "Debug symbols" OFF)
-add_subdirectory(
- ixwebsocket
-)
add_subdirectory(
xplugin
)
diff --git a/file/config.hpp b/file/config.hpp
index cc87d6c..a8cd004 100644
--- a/file/config.hpp
+++ b/file/config.hpp
@@ -12,36 +12,36 @@
namespace config
{
- static inline std::map
- readConfig(const std::string &file)
- {
- std::ifstream config(file);
- std::map settings;
+ static inline std::map
+ readConfig(const std::string &file)
+ {
+ std::ifstream config(file);
+ std::map settings;
- std::string line;
- while (std::getline(config, line)) {
- std::vector fields = split(line, '=');
- if (fields.size() >= 2) {
- trim(fields[0]);
- trim(fields[1]);
- settings[fields[0]] = fields[1];
- }
- }
-
- config.close();
- return settings;
+ std::string line;
+ while (std::getline(config, line)) {
+ std::vector fields = split(line, '=');
+ if (fields.size() >= 2) {
+ trim(fields[0]);
+ trim(fields[1]);
+ settings[fields[0]] = fields[1];
+ }
}
+ config.close();
+ return settings;
+ }
- static inline void
- writeConfig(const std::map &config,
- const std::string &file)
- {
- std::ofstream cfg(file);
- for (const std::pair &entry : config) {
- cfg << entry.first << '=' << entry.second << '\n';
- }
- cfg.close();
+
+ static inline void
+ writeConfig(const std::map &config,
+ const std::string &file)
+ {
+ std::ofstream cfg(file);
+ for (const std::pair &entry : config) {
+ cfg << entry.first << '=' << entry.second << '\n';
}
+ cfg.close();
+ }
} // namespace config
#endif
diff --git a/file/gate.hpp b/file/gate.hpp
index 9182544..59fe6a4 100644
--- a/file/gate.hpp
+++ b/file/gate.hpp
@@ -21,36 +21,35 @@
*/
class Gate
{
-private:
- std::string designator;
- double latitude;
- double longitude;
- std::vector file;
+ private:
+ std::string designator;
+ double latitude;
+ double longitude;
+ std::vector file;
-public:
- Gate(const std::string &designator, double latitude, double longitude)
- {
+ public:
+ Gate(const std::string &designator, double latitude, double longitude)
+ {
- this->designator = designator;
- this->latitude = latitude;
- this->longitude = longitude;
+ this->designator = designator;
+ this->latitude = latitude;
+ this->longitude = longitude;
- file = std::vector(18 + this->designator.length(), 0);
- std::uint8_t *bufPtr = file.data();
- memset(bufPtr,
- static_cast(this->designator.length()),
- sizeof(std::uint8_t));
- bufPtr++; // Designator length
- memcpy(bufPtr, this->designator.c_str(), this->designator.length());
- bufPtr +=
- this->designator.length() + 1; // Designator plus null termination
- memcpy(bufPtr, &this->latitude, sizeof(this->latitude));
- bufPtr += 8; // Latitude
- memcpy(bufPtr, &this->longitude, sizeof(this->longitude));
- }
+ file = std::vector(18 + this->designator.length(), 0);
+ std::uint8_t *bufPtr = file.data();
+ memset(bufPtr,
+ static_cast(this->designator.length()),
+ sizeof(std::uint8_t));
+ bufPtr++; // Designator length
+ memcpy(bufPtr, this->designator.c_str(), this->designator.length());
+ bufPtr += this->designator.length() + 1; // Designator plus null termination
+ memcpy(bufPtr, &this->latitude, sizeof(this->latitude));
+ bufPtr += 8; // Latitude
+ memcpy(bufPtr, &this->longitude, sizeof(this->longitude));
+ }
- std::uint8_t *getBinaryData() { return file.data(); }
- std::size_t getBinaryLength() { return file.size(); }
+ std::uint8_t *getBinaryData() { return file.data(); }
+ std::size_t getBinaryLength() { return file.size(); }
};
#endif
\ No newline at end of file
diff --git a/file/pathSegment.hpp b/file/pathSegment.hpp
index 100db9e..75431cb 100644
--- a/file/pathSegment.hpp
+++ b/file/pathSegment.hpp
@@ -11,47 +11,46 @@
*/
class PathSegment
{
-private:
- std::uint16_t altitude = 0;
- std::uint16_t groundSpeed = 0;
- double latitude = 0;
- double longitude = 0;
- std::vector file;
+ private:
+ std::uint16_t altitude = 0;
+ std::uint16_t groundSpeed = 0;
+ double latitude = 0;
+ double longitude = 0;
+ std::vector file;
-public:
- PathSegment() = default;
- PathSegment(std::uint16_t altitude,
- std::uint16_t groundSpeed,
- double latitude,
- double longitude)
- {
- this->altitude = altitude;
- this->groundSpeed = groundSpeed;
- this->latitude = latitude;
- this->longitude = longitude;
+ public:
+ PathSegment() = default;
+ PathSegment(std::uint16_t altitude,
+ std::uint16_t groundSpeed,
+ double latitude,
+ double longitude)
+ {
+ this->altitude = altitude;
+ this->groundSpeed = groundSpeed;
+ this->latitude = latitude;
+ this->longitude = longitude;
- file = std::vector(20, 0);
- std::uint8_t *bufPtr = file.data();
- memcpy(bufPtr, &this->altitude, sizeof(this->altitude));
- bufPtr += sizeof(this->altitude);
- memcpy(bufPtr, &this->groundSpeed, sizeof(this->groundSpeed));
- bufPtr += sizeof(this->groundSpeed);
- memcpy(bufPtr, &this->latitude, sizeof(this->latitude));
- bufPtr += sizeof(this->latitude);
- memcpy(bufPtr, &this->longitude, sizeof(this->longitude));
- }
+ file = std::vector(20, 0);
+ std::uint8_t *bufPtr = file.data();
+ memcpy(bufPtr, &this->altitude, sizeof(this->altitude));
+ bufPtr += sizeof(this->altitude);
+ memcpy(bufPtr, &this->groundSpeed, sizeof(this->groundSpeed));
+ bufPtr += sizeof(this->groundSpeed);
+ memcpy(bufPtr, &this->latitude, sizeof(this->latitude));
+ bufPtr += sizeof(this->latitude);
+ memcpy(bufPtr, &this->longitude, sizeof(this->longitude));
+ }
- std::uint8_t *getBinaryData() { return file.data(); }
- std::size_t getBinaryLength() { return file.size(); }
+ std::uint8_t *getBinaryData() { return file.data(); }
+ std::size_t getBinaryLength() { return file.size(); }
- friend bool operator==(const PathSegment &lhs, const PathSegment &rhs)
- {
- return lhs.altitude == rhs.altitude &&
- lhs.groundSpeed == rhs.groundSpeed &&
- lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude;
- }
- friend bool operator!=(const PathSegment &lhs, const PathSegment &rhs)
- {
- return !(lhs == rhs);
- }
+ friend bool operator==(const PathSegment &lhs, const PathSegment &rhs)
+ {
+ return lhs.altitude == rhs.altitude && lhs.groundSpeed == rhs.groundSpeed &&
+ lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude;
+ }
+ friend bool operator!=(const PathSegment &lhs, const PathSegment &rhs)
+ {
+ return !(lhs == rhs);
+ }
};
diff --git a/file/recordingPath.hpp b/file/recordingPath.hpp
index 2e3d173..8740256 100644
--- a/file/recordingPath.hpp
+++ b/file/recordingPath.hpp
@@ -6,19 +6,19 @@
class Path
{
-private:
- std::uint64_t count = 0;
- std::vector file;
+ private:
+ std::uint64_t count = 0;
+ std::vector file;
-public:
- void addSegment(PathSegment segment)
- {
- file.resize(file.size() + segment.getBinaryLength());
- std::uint8_t *bufPtr = file.data() + count * segment.getBinaryLength();
- memcpy(bufPtr, segment.getBinaryData(), segment.getBinaryLength());
- count++;
- }
+ public:
+ void addSegment(PathSegment segment)
+ {
+ file.resize(file.size() + segment.getBinaryLength());
+ std::uint8_t *bufPtr = file.data() + count * segment.getBinaryLength();
+ memcpy(bufPtr, segment.getBinaryData(), segment.getBinaryLength());
+ count++;
+ }
- std::uint8_t *getBinaryData() { return file.data(); }
- std::size_t getBinaryLength() { return file.size(); }
+ std::uint8_t *getBinaryData() { return file.data(); }
+ std::size_t getBinaryLength() { return file.size(); }
};
\ No newline at end of file
diff --git a/file/runway.hpp b/file/runway.hpp
index ec34bb8..5d22117 100644
--- a/file/runway.hpp
+++ b/file/runway.hpp
@@ -23,92 +23,91 @@
*/
class Runway
{
-private:
- std::string designator;
- double latitudeStart;
- double longitudeStart;
- std::uint8_t width;
- std::uint16_t length;
- std::uint16_t trueHeading;
- std::vector file;
+ private:
+ std::string designator;
+ double latitudeStart;
+ double longitudeStart;
+ std::uint8_t width;
+ std::uint16_t length;
+ std::uint16_t trueHeading;
+ std::vector file;
-public:
- Runway(std::string designator,
- double latitudeStart,
- double longitudeStart,
- double latitudeEnd,
- double longitudeEnd,
- double width)
- {
- this->designator = std::move(designator);
- this->latitudeStart = latitudeStart;
- this->longitudeStart = longitudeStart;
- this->width = (std::uint8_t)std::round(util::to_feet(width));
- double dist = util::distanceEarth(latitudeStart,
- longitudeStart,
- latitudeEnd,
- longitudeEnd);
- this->length = (std::uint16_t)std::round(util::to_feet(dist));
- this->trueHeading =
- (std::uint16_t)std::round(util::bearing(latitudeStart,
- longitudeStart,
- latitudeEnd,
- longitudeEnd));
+ public:
+ Runway(std::string designator,
+ double latitudeStart,
+ double longitudeStart,
+ double latitudeEnd,
+ double longitudeEnd,
+ double width)
+ {
+ this->designator = std::move(designator);
+ this->latitudeStart = latitudeStart;
+ this->longitudeStart = longitudeStart;
+ this->width = (std::uint8_t)std::round(util::to_feet(width));
+ double dist = util::distanceEarth(latitudeStart,
+ longitudeStart,
+ latitudeEnd,
+ longitudeEnd);
+ this->length = (std::uint16_t)std::round(util::to_feet(dist));
+ this->trueHeading = (std::uint16_t)std::round(util::bearing(latitudeStart,
+ longitudeStart,
+ latitudeEnd,
+ longitudeEnd));
- file = std::vector(23 + this->designator.length(), 0);
- std::uint8_t *bufPtr = file.data();
- memset(bufPtr,
- static_cast(this->designator.length()),
- sizeof(std::uint8_t));
- bufPtr++;
- memcpy(bufPtr, this->designator.c_str(), this->designator.length());
- bufPtr += this->designator.length() + 1;
- memcpy(bufPtr, &this->latitudeStart, sizeof(this->latitudeStart));
- bufPtr += sizeof(this->latitudeStart);
- memcpy(bufPtr, &this->longitudeStart, sizeof(this->longitudeStart));
- bufPtr += sizeof(this->longitudeStart);
- memcpy(bufPtr, &this->width, sizeof(this->width));
- bufPtr += sizeof(this->width);
- memcpy(bufPtr, &this->length, sizeof(this->length));
- bufPtr += sizeof(this->length);
- memcpy(bufPtr, &this->trueHeading, sizeof(this->trueHeading));
- }
+ file = std::vector(23 + this->designator.length(), 0);
+ std::uint8_t *bufPtr = file.data();
+ memset(bufPtr,
+ static_cast(this->designator.length()),
+ sizeof(std::uint8_t));
+ bufPtr++;
+ memcpy(bufPtr, this->designator.c_str(), this->designator.length());
+ bufPtr += this->designator.length() + 1;
+ memcpy(bufPtr, &this->latitudeStart, sizeof(this->latitudeStart));
+ bufPtr += sizeof(this->latitudeStart);
+ memcpy(bufPtr, &this->longitudeStart, sizeof(this->longitudeStart));
+ bufPtr += sizeof(this->longitudeStart);
+ memcpy(bufPtr, &this->width, sizeof(this->width));
+ bufPtr += sizeof(this->width);
+ memcpy(bufPtr, &this->length, sizeof(this->length));
+ bufPtr += sizeof(this->length);
+ memcpy(bufPtr, &this->trueHeading, sizeof(this->trueHeading));
+ }
- Runway(std::string designator,
- double latitudeStart,
- double longitudeStart,
- std::uint8_t width,
- std::uint16_t length,
- std::uint16_t trueHeading)
- {
- this->designator = std::move(designator);
- this->latitudeStart = latitudeStart;
- this->longitudeStart = longitudeStart;
- this->width = width;
- this->length = length;
- this->trueHeading = trueHeading;
+ Runway(std::string designator,
+ double latitudeStart,
+ double longitudeStart,
+ std::uint8_t width,
+ std::uint16_t length,
+ std::uint16_t trueHeading)
+ {
+ this->designator = std::move(designator);
+ this->latitudeStart = latitudeStart;
+ this->longitudeStart = longitudeStart;
+ this->width = width;
+ this->length = length;
+ this->trueHeading = trueHeading;
- file = std::vector(23 + this->designator.length(), 0);
- std::uint8_t *bufPtr = file.data();
- memset(bufPtr,
- static_cast(this->designator.length()),
- sizeof(std::uint8_t));
- bufPtr++;
- memcpy(bufPtr, this->designator.c_str(), this->designator.length());
- bufPtr += this->designator.length() + 1;
- memcpy(bufPtr, &this->latitudeStart, sizeof(this->latitudeStart));
- bufPtr += sizeof(this->latitudeStart);
- memcpy(bufPtr, &this->longitudeStart, sizeof(this->longitudeStart));
- bufPtr += sizeof(this->longitudeStart);
- memcpy(bufPtr, &this->width, sizeof(this->width));
- bufPtr += sizeof(this->width);
- memcpy(bufPtr, &this->length, sizeof(this->length));
- bufPtr += sizeof(this->length);
- memcpy(bufPtr, &this->trueHeading, sizeof(this->trueHeading));
- }
+ file = std::vector(23 + this->designator.length(), 0);
+ std::uint8_t *bufPtr = file.data();
+ memset(bufPtr,
+ static_cast(this->designator.length()),
+ sizeof(std::uint8_t));
+ bufPtr++;
+ memcpy(bufPtr, this->designator.c_str(), this->designator.length());
+ bufPtr += this->designator.length() + 1;
+ memcpy(bufPtr, &this->latitudeStart, sizeof(this->latitudeStart));
+ bufPtr += sizeof(this->latitudeStart);
+ memcpy(bufPtr, &this->longitudeStart, sizeof(this->longitudeStart));
+ bufPtr += sizeof(this->longitudeStart);
+ memcpy(bufPtr, &this->width, sizeof(this->width));
+ bufPtr += sizeof(this->width);
+ memcpy(bufPtr, &this->length, sizeof(this->length));
+ bufPtr += sizeof(this->length);
+ memcpy(bufPtr, &this->trueHeading, sizeof(this->trueHeading));
+ }
- std::uint8_t *getBinaryData() { return file.data(); }
- std::size_t getBinaryLength() { return file.size(); }
+ std::uint8_t *getBinaryData() { return file.data(); }
+ std::size_t getBinaryLength() { return file.size(); }
};
#endif
\ No newline at end of file
diff --git a/file/simulatorDatabase.hpp b/file/simulatorDatabase.hpp
index e92a5bb..9a951fc 100644
--- a/file/simulatorDatabase.hpp
+++ b/file/simulatorDatabase.hpp
@@ -32,160 +32,152 @@
namespace simulatorDatabase
{
- static inline void toFile(
- std::map, std::vector>>
- &airports,
- const std::string &file)
- {
- std::uint8_t null = 0;
- std::ofstream out(file, std::fstream::binary);
+ static inline void toFile(
+ std::map, std::vector>>
+ &airports,
+ const std::string &file)
+ {
+ std::uint8_t null = 0;
+ std::ofstream out(file, std::fstream::binary);
- // File Header
- std::uint8_t header[] = {'V', 'G', 'A', 'S', 0, CURRENT_VERSION};
- out.write(reinterpret_cast(header), 6);
- // Num Airports
- std::uint16_t numAirports = airports.size();
- out.write(reinterpret_cast(&numAirports),
- sizeof(numAirports));
- // Airport
- for (const std::pair, std::vector>>
- &airport : airports) {
- std::string icao = airport.first;
- std::vector gates = airport.second.first;
- std::vector runways = airport.second.second;
- // ICAO
- std::uint8_t icaoLength = icao.length();
- out.write(reinterpret_cast(&icaoLength),
- sizeof(icaoLength));
- out.write(icao.c_str(), icaoLength);
- out.write(reinterpret_cast(&null), sizeof(null));
- // Gates
- std::uint16_t numGates = gates.size();
- out.write(reinterpret_cast(&numGates),
- sizeof(numGates));
- for (Gate &gate : gates) {
- out.write(reinterpret_cast(gate.getBinaryData()),
- (std::streamsize)gate.getBinaryLength());
- }
- // Runways
- std::uint8_t numRunways = runways.size();
- out.write(reinterpret_cast(&numRunways),
- sizeof(numRunways));
- for (Runway &runway : runways) {
- out.write(
- reinterpret_cast(runway.getBinaryData()),
- (std::streamsize)runway.getBinaryLength());
- }
- }
- out.close();
+ // File Header
+ std::uint8_t header[] = {'V', 'G', 'A', 'S', 0, CURRENT_VERSION};
+ out.write(reinterpret_cast(header), 6);
+ // Num Airports
+ std::uint16_t numAirports = airports.size();
+ out.write(reinterpret_cast(&numAirports),
+ sizeof(numAirports));
+ // Airport
+ for (const std::pair, std::vector>>
+ &airport : airports) {
+ std::string icao = airport.first;
+ std::vector gates = airport.second.first;
+ std::vector runways = airport.second.second;
+ // ICAO
+ std::uint8_t icaoLength = icao.length();
+ out.write(reinterpret_cast(&icaoLength),
+ sizeof(icaoLength));
+ out.write(icao.c_str(), icaoLength);
+ out.write(reinterpret_cast(&null), sizeof(null));
+ // Gates
+ std::uint16_t numGates = gates.size();
+ out.write(reinterpret_cast(&numGates), sizeof(numGates));
+ for (Gate &gate : gates) {
+ out.write(reinterpret_cast(gate.getBinaryData()),
+ (std::streamsize)gate.getBinaryLength());
+ }
+ // Runways
+ std::uint8_t numRunways = runways.size();
+ out.write(reinterpret_cast(&numRunways),
+ sizeof(numRunways));
+ for (Runway &runway : runways) {
+ out.write(reinterpret_cast(runway.getBinaryData()),
+ (std::streamsize)runway.getBinaryLength());
+ }
+ }
+ out.close();
+ }
+
+ static inline std::map, std::vector>>
+ readVersion1(std::ifstream &in)
+ {
+ std::map, std::vector>>
+ airports;
+
+ std::uint16_t numAirports;
+ in.read(reinterpret_cast(&numAirports), sizeof(numAirports));
+
+ for (int i = 0; i < numAirports; i++) {
+ // ICAO
+ std::uint8_t icaoLength;
+ in.read(reinterpret_cast(&icaoLength), sizeof(icaoLength));
+ char *icao = static_cast(calloc(icaoLength + 1, sizeof(char)));
+ in.read(icao, icaoLength + 1);
+ // Gates
+ std::uint16_t numGates;
+ in.read(reinterpret_cast(&numGates), sizeof(numGates));
+ for (int j = 0; j < numGates; j++) {
+ // ICAO
+ std::uint8_t designatorLength;
+ in.read(reinterpret_cast(&designatorLength),
+ sizeof(designatorLength));
+ char *designator =
+ static_cast(calloc(designatorLength + 1, sizeof(char)));
+ in.read(designator, designatorLength + 1);
+ // Latitude
+ double latitude;
+ in.read(reinterpret_cast(&latitude), sizeof(latitude));
+ // Latitude
+ double longitude;
+ in.read(reinterpret_cast(&longitude), sizeof(longitude));
+
+ airports[icao].first.emplace_back(designator, latitude, longitude);
+ }
+ // Runways
+ std::uint8_t numRunways;
+ in.read(reinterpret_cast(&numRunways), sizeof(numRunways));
+ for (int j = 0; j < numRunways; j++) {
+ // ICAO
+ std::uint8_t designatorLength;
+ in.read(reinterpret_cast(&designatorLength),
+ sizeof(designatorLength));
+ char *designator =
+ static_cast(calloc(designatorLength + 1, sizeof(char)));
+ in.read(designator, designatorLength + 1);
+ // Latitude
+ double latitude;
+ in.read(reinterpret_cast(&latitude), sizeof(latitude));
+ // Latitude
+ double longitude;
+ in.read(reinterpret_cast(&longitude), sizeof(longitude));
+ // Width
+ std::uint8_t width;
+ in.read(reinterpret_cast(&width), sizeof(width));
+ // Length
+ std::uint16_t length;
+ in.read(reinterpret_cast(&length), sizeof(length));
+ // True Heading
+ std::uint16_t trueHeading;
+ in.read(reinterpret_cast(&trueHeading), sizeof(trueHeading));
+
+ airports[icao].second.emplace_back(designator,
+ latitude,
+ longitude,
+ width,
+ length,
+ trueHeading);
+ }
}
- static inline std::map, std::vector>>
- readVersion1(std::ifstream &in)
- {
- std::map, std::vector>>
- airports;
+ in.close();
- std::uint16_t numAirports;
- in.read(reinterpret_cast(&numAirports), sizeof(numAirports));
+ return airports;
+ }
- for (int i = 0; i < numAirports; i++) {
- // ICAO
- std::uint8_t icaoLength;
- in.read(reinterpret_cast(&icaoLength), sizeof(icaoLength));
- char *icao =
- static_cast(calloc(icaoLength + 1, sizeof(char)));
- in.read(icao, icaoLength + 1);
- // Gates
- std::uint16_t numGates;
- in.read(reinterpret_cast(&numGates), sizeof(numGates));
- for (int j = 0; j < numGates; j++) {
- // ICAO
- std::uint8_t designatorLength;
- in.read(reinterpret_cast(&designatorLength),
- sizeof(designatorLength));
- char *designator = static_cast(
- calloc(designatorLength + 1, sizeof(char)));
- in.read(designator, designatorLength + 1);
- // Latitude
- double latitude;
- in.read(reinterpret_cast(&latitude), sizeof(latitude));
- // Latitude
- double longitude;
- in.read(reinterpret_cast(&longitude),
- sizeof(longitude));
+ static inline std::map, std::vector>>
+ fromFile(const std::string &file)
+ {
+ std::map, std::vector>>
+ airports;
+ std::ifstream in(file);
- airports[icao].first.emplace_back(designator,
- latitude,
- longitude);
- }
- // Runways
- std::uint8_t numRunways;
- in.read(reinterpret_cast(&numRunways), sizeof(numRunways));
- for (int j = 0; j < numRunways; j++) {
- // ICAO
- std::uint8_t designatorLength;
- in.read(reinterpret_cast(&designatorLength),
- sizeof(designatorLength));
- char *designator = static_cast(
- calloc(designatorLength + 1, sizeof(char)));
- in.read(designator, designatorLength + 1);
- // Latitude
- double latitude;
- in.read(reinterpret_cast(&latitude), sizeof(latitude));
- // Latitude
- double longitude;
- in.read(reinterpret_cast(&longitude),
- sizeof(longitude));
- // Width
- std::uint8_t width;
- in.read(reinterpret_cast(&width), sizeof(width));
- // Length
- std::uint16_t length;
- in.read(reinterpret_cast(&length), sizeof(length));
- // True Heading
- std::uint16_t trueHeading;
- in.read(reinterpret_cast(&trueHeading),
- sizeof(trueHeading));
-
- airports[icao].second.emplace_back(designator,
- latitude,
- longitude,
- width,
- length,
- trueHeading);
- }
- }
-
- in.close();
-
- return airports;
+ // File Header
+ char ident[5];
+ in.read(ident, 5);
+ if (strcmp(ident, "VGAS") != 0) {
+ throw std::invalid_argument("Wrong file");
}
+ std::uint8_t version;
+ in.read(reinterpret_cast(&version), 1);
- static inline std::map, std::vector>>
- fromFile(const std::string &file)
- {
- std::map, std::vector>>
- airports;
- std::ifstream in(file);
-
- // File Header
- char ident[5];
- in.read(ident, 5);
- if (strcmp(ident, "VGAS") != 0) {
- throw std::invalid_argument("Wrong file");
- }
- std::uint8_t version;
- in.read(reinterpret_cast(&version), 1);
-
- if (version == 1) {
- return readVersion1(in);
- }
- return airports;
+ if (version == 1) {
+ return readVersion1(in);
}
+ return airports;
+ }
} // namespace simulatorDatabase
#endif
diff --git a/file/stringExtensions.hpp b/file/stringExtensions.hpp
index 73cd052..ceea395 100644
--- a/file/stringExtensions.hpp
+++ b/file/stringExtensions.hpp
@@ -9,45 +9,45 @@
// trim from start (in place)
static inline void ltrim(std::string &s)
{
- s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
- return !std::isspace(ch);
- }));
+ s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
+ return !std::isspace(ch);
+ }));
}
// trim from end (in place)
static inline void rtrim(std::string &s)
{
- s.erase(std::find_if(s.rbegin(),
- s.rend(),
- [](unsigned char ch) { return !std::isspace(ch); })
- .base(),
- s.end());
+ s.erase(std::find_if(s.rbegin(),
+ s.rend(),
+ [](unsigned char ch) { return !std::isspace(ch); })
+ .base(),
+ s.end());
}
static inline std::string rtrim_copy(std::string s)
{
- rtrim(s);
- return s;
+ rtrim(s);
+ return s;
}
// trim from both ends (in place)
static inline void trim(std::string &s)
{
- ltrim(s);
- rtrim(s);
+ ltrim(s);
+ rtrim(s);
}
static inline std::vector split(const std::string &s, char delim)
{
- std::vector result;
- std::stringstream ss(s);
- std::string item;
+ std::vector result;
+ std::stringstream ss(s);
+ std::string item;
- while (getline(ss, item, delim)) {
- result.push_back(item);
- }
+ while (getline(ss, item, delim)) {
+ result.push_back(item);
+ }
- return result;
+ return result;
}
#endif
\ No newline at end of file
diff --git a/file/util.hpp b/file/util.hpp
index c3add92..592cec0 100644
--- a/file/util.hpp
+++ b/file/util.hpp
@@ -39,264 +39,258 @@
namespace util
{
- static inline double to_feet(double value) { return value * 3.280839895; }
+ static inline double to_feet(double value) { return value * 3.280839895; }
- static inline double to_degrees(double value) { return value * 180 / M_PI; }
+ static inline double to_degrees(double value) { return value * 180 / M_PI; }
- static inline double to_radians(double value) { return value * M_PI / 180; }
+ static inline double to_radians(double value) { return value * M_PI / 180; }
- static inline double normalize(double value)
- {
- return fmod(value + 360, 360);
- }
+ static inline double normalize(double value)
+ {
+ return fmod(value + 360, 360);
+ }
- static inline double bearing(double fromLatitude,
- double fromLongitude,
- double toLatitude,
- double toLongitude)
- {
- double y = sin(to_radians(toLongitude) - to_radians(fromLongitude)) *
- cos(to_radians(toLatitude));
- double x = cos(to_radians(fromLatitude)) * sin(to_radians(toLatitude)) -
- sin(to_radians(fromLatitude)) * cos(to_radians(toLatitude)) *
- cos(to_radians(toLongitude) - to_radians(fromLongitude));
+ static inline double bearing(double fromLatitude,
+ double fromLongitude,
+ double toLatitude,
+ double toLongitude)
+ {
+ double y = sin(to_radians(toLongitude) - to_radians(fromLongitude)) *
+ cos(to_radians(toLatitude));
+ double x = cos(to_radians(fromLatitude)) * sin(to_radians(toLatitude)) -
+ sin(to_radians(fromLatitude)) * cos(to_radians(toLatitude)) *
+ cos(to_radians(toLongitude) - to_radians(fromLongitude));
- return normalize(to_degrees(atan2(y, x)));
- }
+ return normalize(to_degrees(atan2(y, x)));
+ }
- static inline double distanceEarth(double fromLatitude,
- double fromLongitude,
- double toLatitude,
- double toLongitude)
- {
- double lat1r, lon1r, lat2r, lon2r, u, v;
- lat1r = to_radians(fromLatitude);
- lon1r = to_radians(fromLongitude);
- lat2r = to_radians(toLatitude);
- lon2r = to_radians(toLongitude);
- u = sin((lat2r - lat1r) / 2);
- v = sin((lon2r - lon1r) / 2);
- return 2.0 * EARTH_M *
- asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
- }
+ static inline double distanceEarth(double fromLatitude,
+ double fromLongitude,
+ double toLatitude,
+ double toLongitude)
+ {
+ double lat1r, lon1r, lat2r, lon2r, u, v;
+ lat1r = to_radians(fromLatitude);
+ lon1r = to_radians(fromLongitude);
+ lat2r = to_radians(toLatitude);
+ lon2r = to_radians(toLongitude);
+ u = sin((lat2r - lat1r) / 2);
+ v = sin((lon2r - lon1r) / 2);
+ return 2.0 * EARTH_M * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
+ }
- template
- static inline std::vector
- select_T(const std::vector &inVec,
- std::function predicate)
- {
- std::vector result;
- copy_if(inVec.begin(), inVec.end(), back_inserter(result), predicate);
- return result;
- }
+ template
+ static inline std::vector
+ select_T(const std::vector &inVec,
+ std::function predicate)
+ {
+ std::vector result;
+ copy_if(inVec.begin(), inVec.end(), back_inserter(result), predicate);
+ return result;
+ }
#if defined APL || defined LIN
- static unsigned long get_size_by_fd(int fd)
- {
- struct stat buf {
- };
- if (fstat(fd, &buf) < 0)
- return 0;
- return buf.st_size;
- }
+ static unsigned long get_size_by_fd(int fd)
+ {
+ struct stat buf {
+ };
+ if (fstat(fd, &buf) < 0)
+ return 0;
+ return buf.st_size;
+ }
#endif
- static void to_hex(const char *hash, char *buffer)
- {
- for (int i = 0; i < MD5LEN; i++) {
- if (buffer != nullptr) {
- sprintf(&buffer[2 * i], "%02x", hash[i] & 0xff);
- }
- }
+ static void to_hex(const char *hash, char *buffer)
+ {
+ for (int i = 0; i < MD5LEN; i++) {
+ if (buffer != nullptr) {
+ sprintf(&buffer[2 * i], "%02x", hash[i] & 0xff);
+ }
}
+ }
#ifdef IBM
- static inline int
- generateMD5(const char *filepath,
- char *lastHash,
- const std::function toLog)
- {
- BOOL bResult = FALSE;
- HCRYPTPROV hProv = 0;
- HCRYPTHASH hHash = 0;
- HANDLE hFile;
- BYTE rgbFile[BUFSIZE] = {0};
- DWORD cbRead = 0;
- BYTE rgbHash[MD5LEN] = {0};
- DWORD cbHash = 0;
+ static inline int
+ generateMD5(const char *filepath,
+ char *lastHash,
+ const std::function toLog)
+ {
+ BOOL bResult = FALSE;
+ HCRYPTPROV hProv = 0;
+ HCRYPTHASH hHash = 0;
+ HANDLE hFile;
+ BYTE rgbFile[BUFSIZE] = {0};
+ DWORD cbRead = 0;
+ BYTE rgbHash[MD5LEN] = {0};
+ DWORD cbHash = 0;
- // Logic to check usage goes here.
- hFile = CreateFile(filepath,
- GENERIC_READ,
- FILE_SHARE_READ,
- nullptr,
- OPEN_EXISTING,
- FILE_FLAG_SEQUENTIAL_SCAN,
- nullptr);
+ // Logic to check usage goes here.
+ hFile = CreateFile(filepath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ nullptr,
+ OPEN_EXISTING,
+ FILE_FLAG_SEQUENTIAL_SCAN,
+ nullptr);
- // Get handle to the crypto provider
- if (!CryptAcquireContext(&hProv,
- nullptr,
- nullptr,
- PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT)) {
- std::stringstream debug_msg;
- debug_msg << "CryptAcquireContext returned with error "
- << GetLastError();
- toLog(debug_msg.str());
+ // Get handle to the crypto provider
+ if (!CryptAcquireContext(&hProv,
+ nullptr,
+ nullptr,
+ PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ std::stringstream debug_msg;
+ debug_msg << "CryptAcquireContext returned with error " << GetLastError();
+ toLog(debug_msg.str());
- CloseHandle(hFile);
- return 1;
- }
+ CloseHandle(hFile);
+ return 1;
+ }
- if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
- std::stringstream debug_msg;
- debug_msg << "CryptCreateHash returned with error "
- << GetLastError();
- toLog(debug_msg.str());
+ if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
+ std::stringstream debug_msg;
+ debug_msg << "CryptCreateHash returned with error " << GetLastError();
+ toLog(debug_msg.str());
- CloseHandle(hFile);
- CryptReleaseContext(hProv, 0);
- return 1;
- }
+ CloseHandle(hFile);
+ CryptReleaseContext(hProv, 0);
+ return 1;
+ }
- while (
- (bResult = ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, nullptr))) {
- if (0 == cbRead) {
- break;
- }
+ while ((bResult = ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, nullptr))) {
+ if (0 == cbRead) {
+ break;
+ }
- if (!CryptHashData(hHash, rgbFile, cbRead, 0)) {
- std::stringstream debug_msg;
- debug_msg << "CryptHashData returned with error "
- << GetLastError();
- toLog(debug_msg.str());
+ if (!CryptHashData(hHash, rgbFile, cbRead, 0)) {
+ std::stringstream debug_msg;
+ debug_msg << "CryptHashData returned with error " << GetLastError();
+ toLog(debug_msg.str());
- CryptReleaseContext(hProv, 0);
- CryptDestroyHash(hHash);
- CloseHandle(hFile);
- return 1;
- }
- }
-
- if (!bResult) {
- std::stringstream debug_msg;
- debug_msg << "ReadFile returned with error " << GetLastError();
- toLog(debug_msg.str());
-
- CryptReleaseContext(hProv, 0);
- CryptDestroyHash(hHash);
- CloseHandle(hFile);
- return 1;
- }
-
- cbHash = MD5LEN;
- if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) {
- to_hex((char *)rgbHash, lastHash);
- } else {
- std::stringstream debug_msg;
- debug_msg << "CryptGetHashParam returned with error "
- << GetLastError();
- toLog(debug_msg.str());
- }
-
- CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
+ CryptDestroyHash(hHash);
CloseHandle(hFile);
-
- return 0;
+ return 1;
+ }
}
+
+ if (!bResult) {
+ std::stringstream debug_msg;
+ debug_msg << "ReadFile returned with error " << GetLastError();
+ toLog(debug_msg.str());
+
+ CryptReleaseContext(hProv, 0);
+ CryptDestroyHash(hHash);
+ CloseHandle(hFile);
+ return 1;
+ }
+
+ cbHash = MD5LEN;
+ if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) {
+ to_hex((char *)rgbHash, lastHash);
+ } else {
+ std::stringstream debug_msg;
+ debug_msg << "CryptGetHashParam returned with error " << GetLastError();
+ toLog(debug_msg.str());
+ }
+
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+ CloseHandle(hFile);
+
+ return 0;
+ }
#endif
#ifdef APL
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
- static inline int
- generateMD5(const char *filepath,
- char *lastHash,
- const std::function &toLog)
- {
- int file_descript;
- unsigned long file_size;
- char *file_buffer;
- unsigned char result[MD5LEN];
+ static inline int
+ generateMD5(const char *filepath,
+ char *lastHash,
+ const std::function &toLog)
+ {
+ int file_descript;
+ unsigned long file_size;
+ char *file_buffer;
+ unsigned char result[MD5LEN];
- file_descript = open(filepath, O_RDONLY);
- if (file_descript < 0)
- return 1;
+ file_descript = open(filepath, O_RDONLY);
+ if (file_descript < 0)
+ return 1;
- file_size = get_size_by_fd(file_descript);
+ file_size = get_size_by_fd(file_descript);
- file_buffer =
- (char *)mmap(0, file_size, PROT_READ, MAP_SHARED, file_descript, 0);
+ file_buffer =
+ (char *)mmap(0, file_size, PROT_READ, MAP_SHARED, file_descript, 0);
- CC_MD5_CTX context;
- CC_MD5_Init(&context);
- CC_MD5_Update(&context, file_buffer, (CC_LONG)file_size);
- CC_MD5_Final(result, &context);
+ CC_MD5_CTX context;
+ CC_MD5_Init(&context);
+ CC_MD5_Update(&context, file_buffer, (CC_LONG)file_size);
+ CC_MD5_Final(result, &context);
- munmap(file_buffer, file_size);
- close(file_descript);
+ munmap(file_buffer, file_size);
+ close(file_descript);
- to_hex((char *)result, lastHash);
- return 0;
- }
+ to_hex((char *)result, lastHash);
+ return 0;
+ }
#pragma clang diagnostic pop
#endif
#ifdef LIN
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
- static inline int
- generateMD5(const char *filepath,
- char *buffer,
- const std::function &toLog)
- {
- int file_descriptor;
- unsigned long file_size;
- char *file_buffer;
- unsigned char result[MD5LEN];
+ static inline int
+ generateMD5(const char *filepath,
+ char *buffer,
+ const std::function &toLog)
+ {
+ int file_descriptor;
+ unsigned long file_size;
+ char *file_buffer;
+ unsigned char result[MD5LEN];
- file_descriptor = open(filepath, O_RDONLY);
- if (file_descriptor < 0)
- return 1;
+ file_descriptor = open(filepath, O_RDONLY);
+ if (file_descriptor < 0)
+ return 1;
- file_size = get_size_by_fd(file_descriptor);
- if (file_size == 0)
- return 1;
+ file_size = get_size_by_fd(file_descriptor);
+ if (file_size == 0)
+ return 1;
- file_buffer = (char *)
- mmap(nullptr, file_size, PROT_READ, MAP_SHARED, file_descriptor, 0);
+ file_buffer = (char *)
+ mmap(nullptr, file_size, PROT_READ, MAP_SHARED, file_descriptor, 0);
- MD5((unsigned char *)file_buffer, file_size, result);
+ MD5((unsigned char *)file_buffer, file_size, result);
- munmap(file_buffer, file_size);
- close(file_descriptor);
+ munmap(file_buffer, file_size);
+ close(file_descriptor);
- to_hex((char *)result, buffer);
- return 0;
- }
+ to_hex((char *)result, buffer);
+ return 0;
+ }
#pragma clang diagnostic pop
#endif
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
- static inline void setThreadName(const std::string &name)
- {
+ static inline void setThreadName(const std::string &name)
+ {
#ifdef APL
- //
- // Apple reserves 16 bytes for its thread names
- // Notice that the Apple version of pthread_setname_np
- // does not take a pthread_t argument
- //
- pthread_setname_np(name.substr(0, 63).c_str());
+ //
+ // Apple reserves 16 bytes for its thread names
+ // Notice that the Apple version of pthread_setname_np
+ // does not take a pthread_t argument
+ //
+ pthread_setname_np(name.substr(0, 63).c_str());
#endif
#ifdef LIN
- //
- // Linux only reserves 16 bytes for its thread names
- // See prctl and PR_SET_NAME property in
- // http://man7.org/linux/man-pages/man2/prctl.2.html
- //
- pthread_setname_np(pthread_self(), name.substr(0, 15).c_str());
+ //
+ // Linux only reserves 16 bytes for its thread names
+ // See prctl and PR_SET_NAME property in
+ // http://man7.org/linux/man-pages/man2/prctl.2.html
+ //
+ pthread_setname_np(pthread_self(), name.substr(0, 15).c_str());
#endif
- }
+ }
#pragma clang diagnostic pop
} // namespace util
diff --git a/format.sh b/format.sh
index 59aa6ed..3add914 100755
--- a/format.sh
+++ b/format.sh
@@ -2,7 +2,7 @@
shopt -s globstar
-GLOBIGNORE='**/XPLM/**:XPLM/**:**/XPLM:**/ixwebsocket/**:ixwebsocket/**:**/ixwebsocket:**/nlohmann/**:nlohmann/**:**/nlohmann:**/XPSDK/**:XPSDK/**:**/XPSDK:**/build*/**:build*/**:**/build*'
+GLOBIGNORE='**/XPLM/**:XPLM/**:**/XPLM:**/nlohmann/**:nlohmann/**:**/nlohmann:**/XPSDK/**:XPSDK/**:**/XPSDK:**/build*/**:build*/**:**/build*'
clang-format -verbose -i **/*.cpp
clang-format -verbose -i **/*.h
diff --git a/ixwebsocket/CMakeLists.txt b/ixwebsocket/CMakeLists.txt
deleted file mode 100644
index fd5bfb4..0000000
--- a/ixwebsocket/CMakeLists.txt
+++ /dev/null
@@ -1,99 +0,0 @@
-
-file(GLOB ixwebsocket CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/ixwebsocket/*.cpp)
-
-add_library(ixwebsocket SHARED
- ${ixwebsocket}
-)
-
-target_include_directories(ixwebsocket PRIVATE
- ${CMAKE_SOURCE_DIR}/ixwebsocket/include
-)
-
-set_target_properties(ixwebsocket PROPERTIES
- PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/ixwebsocket/include
-)
-target_compile_options(ixwebsocket PRIVATE
- -Wall
- -Wextra
- -pedantic
- #-fvisibility=hidden
-)
-if(DEBUG)
- target_compile_options(ixwebsocket PRIVATE
- -g
- )
- target_link_options(ixwebsocket PRIVATE
- -g
- )
-else()
- target_compile_options(ixwebsocket PRIVATE
- -O2
- )
-endif()
-
-if(APPLE)
- message("Building ixwebsocket for MacOSX Universal into ${PROJECT_BINARY_DIR}/${PLUGIN_NAME}/${BIT}")
-
- set_target_properties(ixwebsocket PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}
- BUILD_WITH_INSTALL_NAME_DIR TRUE
- )
-
- target_compile_options(ixwebsocket PRIVATE
- #"SHELL:-arch i386"
- "SHELL:-arch x86_64"
- )
- target_link_options(ixwebsocket PRIVATE
- #"SHELL:-arch i386"
- "SHELL:-arch x86_64"
- )
- target_link_libraries(ixwebsocket PRIVATE
- "-framework Security"
- )
-elseif(UNIX)
- message("Building ixwebsocket for Linux ${BIT} into ${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}/${BIT}")
-
- set_target_properties(ixwebsocket PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}/${BIT}
- )
-
- target_compile_options(ixwebsocket PRIVATE
- -nodefaultlibs
- )
- if(BIT STREQUAL "32")
- target_compile_options(ixwebsocket PRIVATE
- -m32
- )
- target_link_options(ixwebsocket PRIVATE
- -m32
- )
- endif()
- target_link_libraries(ixwebsocket PRIVATE
- crypto
- pthread
- )
-elseif(WIN32)
- message("Building ixwebsocket for Windows ${BIT} into ${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}/${BIT}")
-
- set_target_properties(ixwebsocket PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Plugin/${PLUGIN_NAME}/${BIT}
- )
-
- if(DEBUG)
- target_compile_options(ixwebsocket PRIVATE
- -gcodeview
- )
- target_link_options(ixwebsocket PRIVATE
- -Wl,-pdb=
- )
- endif()
- target_link_options(ixwebsocket PRIVATE
- -static-libgcc
- -static-libstdc++
- )
- target_link_libraries(ixwebsocket PRIVATE
- ws2_32.lib
- )
-endif()
-
-add_library(ixwebsocket::ixwebsocket ALIAS ixwebsocket)
diff --git a/ixwebsocket/IXBench.cpp b/ixwebsocket/IXBench.cpp
deleted file mode 100644
index 665f3fe..0000000
--- a/ixwebsocket/IXBench.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * IXBench.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2017-2020 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXBench.h"
-
-#include
-
-namespace ix
-{
-Bench::Bench(const std::string &description) : _description(description)
-{
- reset();
-}
-
-Bench::~Bench()
-{
- if (!_reported) {
- report();
- }
-}
-
-void Bench::reset()
-{
- _start = std::chrono::high_resolution_clock::now();
- _reported = false;
-}
-
-void Bench::report()
-{
- auto now = std::chrono::high_resolution_clock::now();
- auto microseconds =
- std::chrono::duration_cast(now - _start);
-
- _duration = microseconds.count();
- std::cerr << _description << " completed in " << _duration << " us"
- << std::endl;
-
- setReported();
-}
-
-void Bench::record()
-{
- auto now = std::chrono::high_resolution_clock::now();
- auto microseconds =
- std::chrono::duration_cast(now - _start);
-
- _duration = microseconds.count();
-}
-
-void Bench::setReported() { _reported = true; }
-
-uint64_t Bench::getDuration() const { return _duration; }
-} // namespace ix
diff --git a/ixwebsocket/IXCancellationRequest.cpp b/ixwebsocket/IXCancellationRequest.cpp
deleted file mode 100644
index ddc58e5..0000000
--- a/ixwebsocket/IXCancellationRequest.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * IXCancellationRequest.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXCancellationRequest.h"
-
-#include
-#include
-
-namespace ix
-{
-CancellationRequest makeCancellationRequestWithTimeout(
- int secs,
- std::atomic &requestInitCancellation)
-{
- assert(secs > 0);
-
- auto start = std::chrono::system_clock::now();
- auto timeout = std::chrono::seconds(secs);
-
- auto isCancellationRequested =
- [&requestInitCancellation, start, timeout]() -> bool {
- // Was an explicit cancellation requested ?
- if (requestInitCancellation)
- return true;
-
- auto now = std::chrono::system_clock::now();
- if ((now - start) > timeout)
- return true;
-
- // No cancellation request
- return false;
- };
-
- return isCancellationRequested;
-}
-} // namespace ix
diff --git a/ixwebsocket/IXConnectionState.cpp b/ixwebsocket/IXConnectionState.cpp
deleted file mode 100644
index 43eb9e1..0000000
--- a/ixwebsocket/IXConnectionState.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * IXConnectionState.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXConnectionState.h"
-
-namespace ix
-{
-std::atomic ConnectionState::_globalId(0);
-
-ConnectionState::ConnectionState() : _terminated(false) { computeId(); }
-
-void ConnectionState::computeId() { _id = std::to_string(_globalId++); }
-
-const std::string &ConnectionState::getId() const { return _id; }
-
-std::shared_ptr ConnectionState::createConnectionState()
-{
- return std::make_shared();
-}
-
-void ConnectionState::setOnSetTerminatedCallback(
- const OnSetTerminatedCallback &callback)
-{
- _onSetTerminatedCallback = callback;
-}
-
-bool ConnectionState::isTerminated() const { return _terminated; }
-
-void ConnectionState::setTerminated()
-{
- _terminated = true;
-
- if (_onSetTerminatedCallback) {
- _onSetTerminatedCallback();
- }
-}
-
-const std::string &ConnectionState::getRemoteIp() { return _remoteIp; }
-
-int ConnectionState::getRemotePort() { return _remotePort; }
-
-void ConnectionState::setRemoteIp(const std::string &remoteIp)
-{
- _remoteIp = remoteIp;
-}
-
-void ConnectionState::setRemotePort(int remotePort)
-{
- _remotePort = remotePort;
-}
-} // namespace ix
diff --git a/ixwebsocket/IXDNSLookup.cpp b/ixwebsocket/IXDNSLookup.cpp
deleted file mode 100644
index db0b8d1..0000000
--- a/ixwebsocket/IXDNSLookup.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * IXDNSLookup.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
- */
-
-//
-// On Windows Universal Platform (uwp), gai_strerror defaults behavior is to
-// returns wchar_t which is different from all other platforms. We want the non
-// unicode version. See https://github.com/microsoft/vcpkg/pull/11030 We could
-// do this in IXNetSystem.cpp but so far we are only using gai_strerror in here.
-//
-#ifdef _UNICODE
-#undef _UNICODE
-#endif
-#ifdef UNICODE
-#undef UNICODE
-#endif
-
-#include "IXDNSLookup.h"
-
-#include "IXNetSystem.h"
-#include
-#include
-#include
-
-// mingw build quirks
-#if defined(_WIN32) && defined(__GNUC__)
-#define AI_NUMERICSERV NI_NUMERICSERV
-#define AI_ADDRCONFIG LUP_ADDRCONFIG
-#endif
-
-namespace ix
-{
-const int64_t DNSLookup::kDefaultWait = 1; // ms
-
-DNSLookup::DNSLookup(const std::string &hostname, int port, int64_t wait)
- : _hostname(hostname), _port(port), _wait(wait), _res(nullptr), _done(false)
-{
- ;
-}
-
-struct addrinfo *DNSLookup::getAddrInfo(const std::string &hostname,
- int port,
- std::string &errMsg)
-{
- struct addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- std::string sport = std::to_string(port);
-
- struct addrinfo *res;
- int getaddrinfo_result =
- getaddrinfo(hostname.c_str(), sport.c_str(), &hints, &res);
- if (getaddrinfo_result) {
- errMsg = gai_strerror(getaddrinfo_result);
- res = nullptr;
- }
- return res;
-}
-
-struct addrinfo *
- DNSLookup::resolve(std::string &errMsg,
- const CancellationRequest &isCancellationRequested,
- bool cancellable)
-{
- return cancellable ? resolveCancellable(errMsg, isCancellationRequested)
- : resolveUnCancellable(errMsg, isCancellationRequested);
-}
-
-void DNSLookup::release(struct addrinfo *addr) { freeaddrinfo(addr); }
-
-struct addrinfo *DNSLookup::resolveUnCancellable(
- std::string &errMsg,
- const CancellationRequest &isCancellationRequested)
-{
- errMsg = "no error";
-
- // Maybe a cancellation request got in before the background thread
- // terminated ?
- if (isCancellationRequested()) {
- errMsg = "cancellation requested";
- return nullptr;
- }
-
- return getAddrInfo(_hostname, _port, errMsg);
-}
-
-struct addrinfo *DNSLookup::resolveCancellable(
- std::string &errMsg,
- const CancellationRequest &isCancellationRequested)
-{
- errMsg = "no error";
-
- // Can only be called once, otherwise we would have to manage a pool
- // of background thread which is overkill for our usage.
- if (_done) {
- return nullptr; // programming error, create a second DNSLookup instance
- // if you need a second lookup.
- }
-
- //
- // Good resource on thread forced termination
- // https://www.bo-yang.net/2017/11/19/cpp-kill-detached-thread
- //
- auto ptr = shared_from_this();
- std::weak_ptr self(ptr);
-
- int port = _port;
- std::string hostname(_hostname);
-
- // We make the background thread doing the work a shared pointer
- // instead of a member variable, because it can keep running when
- // this object goes out of scope, in case of cancellation
- auto t = std::make_shared(&DNSLookup::run,
- this,
- self,
- hostname,
- port);
- t->detach();
-
- while (!_done) {
- // Wait for 1 milliseconds, to see if the bg thread has terminated.
- // We do not use a condition variable to wait, as destroying this one
- // if the bg thread is alive can cause undefined behavior.
- std::this_thread::sleep_for(std::chrono::milliseconds(_wait));
-
- // Were we cancelled ?
- if (isCancellationRequested()) {
- errMsg = "cancellation requested";
- return nullptr;
- }
- }
-
- // Maybe a cancellation request got in before the bg terminated ?
- if (isCancellationRequested()) {
- errMsg = "cancellation requested";
- return nullptr;
- }
-
- errMsg = getErrMsg();
- return getRes();
-}
-
-void DNSLookup::run(std::weak_ptr self,
- std::string hostname,
- int port) // thread runner
-{
- // We don't want to read or write into members variables of an object that
- // could be gone, so we use temporary variables (res) or we pass in by copy
- // everything that getAddrInfo needs to work.
- std::string errMsg;
- struct addrinfo *res = getAddrInfo(hostname, port, errMsg);
-
- if (auto lock = self.lock()) {
- // Copy result into the member variables
- setRes(res);
- setErrMsg(errMsg);
-
- _done = true;
- }
-}
-
-void DNSLookup::setErrMsg(const std::string &errMsg)
-{
- std::lock_guard lock(_errMsgMutex);
- _errMsg = errMsg;
-}
-
-const std::string &DNSLookup::getErrMsg()
-{
- std::lock_guard lock(_errMsgMutex);
- return _errMsg;
-}
-
-void DNSLookup::setRes(struct addrinfo *addr)
-{
- std::lock_guard lock(_resMutex);
- _res = addr;
-}
-
-struct addrinfo *DNSLookup::getRes()
-{
- std::lock_guard lock(_resMutex);
- return _res;
-}
-} // namespace ix
diff --git a/ixwebsocket/IXExponentialBackoff.cpp b/ixwebsocket/IXExponentialBackoff.cpp
deleted file mode 100644
index 9a40999..0000000
--- a/ixwebsocket/IXExponentialBackoff.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * IXExponentialBackoff.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2017-2019 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXExponentialBackoff.h"
-
-#include
-
-namespace ix
-{
-uint32_t
- calculateRetryWaitMilliseconds(uint32_t retryCount,
- uint32_t maxWaitBetweenReconnectionRetries,
- uint32_t minWaitBetweenReconnectionRetries)
-{
- uint32_t waitTime = (retryCount < 26) ? (std::pow(2, retryCount) * 100) : 0;
-
- if (waitTime < minWaitBetweenReconnectionRetries) {
- waitTime = minWaitBetweenReconnectionRetries;
- }
-
- if (waitTime > maxWaitBetweenReconnectionRetries || waitTime == 0) {
- waitTime = maxWaitBetweenReconnectionRetries;
- }
-
- return waitTime;
-}
-} // namespace ix
diff --git a/ixwebsocket/IXGetFreePort.cpp b/ixwebsocket/IXGetFreePort.cpp
deleted file mode 100644
index d5ac863..0000000
--- a/ixwebsocket/IXGetFreePort.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * IXGetFreePort.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2019 Machine Zone. All rights reserved.
- */
-
-// Using inet_addr will trigger an error on uwp without this
-// FIXME: use a different api
-#ifdef _WIN32
-#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
-#define _WINSOCK_DEPRECATED_NO_WARNINGS
-#endif
-#endif
-
-#include "IXGetFreePort.h"
-
-#include "IXNetSystem.h"
-#include "IXSocket.h"
-#include
-#include
-
-namespace ix
-{
-int getAnyFreePortRandom()
-{
- std::random_device rd;
- std::uniform_int_distribution dist(1024 + 1, 65535);
-
- return dist(rd);
-}
-
-int getAnyFreePort()
-{
- socket_t sockfd;
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- return getAnyFreePortRandom();
- }
-
- int enable = 1;
- if (setsockopt(sockfd,
- SOL_SOCKET,
- SO_REUSEADDR,
- (char *)&enable,
- sizeof(enable)) < 0) {
- return getAnyFreePortRandom();
- }
-
- // Bind to port 0. This is the standard way to get a free port.
- struct sockaddr_in server; // server address information
- server.sin_family = AF_INET;
- server.sin_port = htons(0);
- server.sin_addr.s_addr = inet_addr("127.0.0.1");
-
- if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) {
- Socket::closeSocket(sockfd);
- return getAnyFreePortRandom();
- }
-
- struct sockaddr_in sa; // server address information
- socklen_t len = sizeof(sa);
- if (getsockname(sockfd, (struct sockaddr *)&sa, &len) < 0) {
- Socket::closeSocket(sockfd);
- return getAnyFreePortRandom();
- }
-
- int port = ntohs(sa.sin_port);
- Socket::closeSocket(sockfd);
-
- return port;
-}
-
-int getFreePort()
-{
- while (true) {
-#if defined(__has_feature)
-#if __has_feature(address_sanitizer)
- int port = getAnyFreePortRandom();
-#else
- int port = getAnyFreePort();
-#endif
-#else
- int port = getAnyFreePort();
-#endif
- //
- // Only port above 1024 can be used by non root users, but for some
- // reason I got port 7 returned with macOS when binding on port 0...
- //
- if (port > 1024) {
- return port;
- }
- }
-
- return -1;
-}
-} // namespace ix
diff --git a/ixwebsocket/IXGzipCodec.cpp b/ixwebsocket/IXGzipCodec.cpp
deleted file mode 100644
index 82251f5..0000000
--- a/ixwebsocket/IXGzipCodec.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * IXGzipCodec.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2020 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXGzipCodec.h"
-
-#include "IXBench.h"
-#include
-#include
-
-#ifdef IXWEBSOCKET_USE_ZLIB
-#include
-#endif
-
-#ifdef IXWEBSOCKET_USE_DEFLATE
-#include
-#endif
-
-namespace ix
-{
-std::string gzipCompress(const std::string &str)
-{
-#ifndef IXWEBSOCKET_USE_ZLIB
- return std::string();
-#else
-#ifdef IXWEBSOCKET_USE_DEFLATE
- int compressionLevel = 6;
- struct libdeflate_compressor *compressor;
-
- compressor = libdeflate_alloc_compressor(compressionLevel);
-
- const void *uncompressed_data = str.data();
- size_t uncompressed_size = str.size();
- void *compressed_data;
- size_t actual_compressed_size;
- size_t max_compressed_size;
-
- max_compressed_size =
- libdeflate_gzip_compress_bound(compressor, uncompressed_size);
- compressed_data = malloc(max_compressed_size);
-
- if (compressed_data == NULL) {
- return std::string();
- }
-
- actual_compressed_size = libdeflate_gzip_compress(compressor,
- uncompressed_data,
- uncompressed_size,
- compressed_data,
- max_compressed_size);
-
- libdeflate_free_compressor(compressor);
-
- if (actual_compressed_size == 0) {
- free(compressed_data);
- return std::string();
- }
-
- std::string out;
- out.assign(reinterpret_cast(compressed_data),
- actual_compressed_size);
- free(compressed_data);
-
- return out;
-#else
- z_stream zs; // z_stream is zlib's control structure
- memset(&zs, 0, sizeof(zs));
-
- // deflateInit2 configure the file format: request gzip instead of deflate
- const int windowBits = 15;
- const int GZIP_ENCODING = 16;
-
- deflateInit2(&zs,
- Z_DEFAULT_COMPRESSION,
- Z_DEFLATED,
- windowBits | GZIP_ENCODING,
- 8,
- Z_DEFAULT_STRATEGY);
-
- zs.next_in = (Bytef *)str.data();
- zs.avail_in = (uInt)str.size(); // set the z_stream's input
-
- int ret;
- char outbuffer[32768];
- std::string outstring;
-
- // retrieve the compressed bytes blockwise
- do {
- zs.next_out = reinterpret_cast(outbuffer);
- zs.avail_out = sizeof(outbuffer);
-
- ret = deflate(&zs, Z_FINISH);
-
- if (outstring.size() < zs.total_out) {
- // append the block to the output string
- outstring.append(outbuffer, zs.total_out - outstring.size());
- }
- } while (ret == Z_OK);
-
- deflateEnd(&zs);
-
- return outstring;
-#endif // IXWEBSOCKET_USE_DEFLATE
-#endif // IXWEBSOCKET_USE_ZLIB
-}
-
-#ifdef IXWEBSOCKET_USE_DEFLATE
-static uint32_t loadDecompressedGzipSize(const uint8_t *p)
-{
- return ((uint32_t)p[0] << 0) | ((uint32_t)p[1] << 8) |
- ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
-}
-#endif
-
-bool gzipDecompress(const std::string &in, std::string &out)
-{
-#ifndef IXWEBSOCKET_USE_ZLIB
- return false;
-#else
-#ifdef IXWEBSOCKET_USE_DEFLATE
- struct libdeflate_decompressor *decompressor;
- decompressor = libdeflate_alloc_decompressor();
-
- const void *compressed_data = in.data();
- size_t compressed_size = in.size();
-
- // Retrieve uncompressed size from the trailer of the gziped data
- const uint8_t *ptr = reinterpret_cast(&in.front());
- auto uncompressed_size =
- loadDecompressedGzipSize(&ptr[compressed_size - 4]);
-
- // Use it to redimension our output buffer
- out.resize(uncompressed_size);
-
- libdeflate_result result = libdeflate_gzip_decompress(decompressor,
- compressed_data,
- compressed_size,
- &out.front(),
- uncompressed_size,
- NULL);
-
- libdeflate_free_decompressor(decompressor);
- return result == LIBDEFLATE_SUCCESS;
-#else
- z_stream inflateState;
- memset(&inflateState, 0, sizeof(inflateState));
-
- inflateState.zalloc = Z_NULL;
- inflateState.zfree = Z_NULL;
- inflateState.opaque = Z_NULL;
- inflateState.avail_in = 0;
- inflateState.next_in = Z_NULL;
-
- if (inflateInit2(&inflateState, 16 + MAX_WBITS) != Z_OK) {
- return false;
- }
-
- inflateState.avail_in = (uInt)in.size();
- inflateState.next_in = (unsigned char *)(const_cast(in.data()));
-
- const int kBufferSize = 1 << 14;
- std::array compressBuffer;
-
- do {
- inflateState.avail_out = (uInt)kBufferSize;
- inflateState.next_out = &compressBuffer.front();
-
- int ret = inflate(&inflateState, Z_SYNC_FLUSH);
-
- if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) {
- inflateEnd(&inflateState);
- return false;
- }
-
- out.append(reinterpret_cast(&compressBuffer.front()),
- kBufferSize - inflateState.avail_out);
- } while (inflateState.avail_out == 0);
-
- inflateEnd(&inflateState);
- return true;
-#endif // IXWEBSOCKET_USE_DEFLATE
-#endif // IXWEBSOCKET_USE_ZLIB
-}
-} // namespace ix
diff --git a/ixwebsocket/IXHttp.cpp b/ixwebsocket/IXHttp.cpp
deleted file mode 100644
index ac87598..0000000
--- a/ixwebsocket/IXHttp.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * IXHttp.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXHttp.h"
-
-#include "IXCancellationRequest.h"
-#include "IXGzipCodec.h"
-#include "IXSocket.h"
-#include
-#include
-
-namespace ix
-{
-std::string Http::trim(const std::string &str)
-{
- std::string out;
- for (auto c : str) {
- if (c != ' ' && c != '\n' && c != '\r') {
- out += c;
- }
- }
-
- return out;
-}
-
-std::pair Http::parseStatusLine(const std::string &line)
-{
- // Request-Line = Method SP Request-URI SP HTTP-Version CRLF
- std::string token;
- std::stringstream tokenStream(line);
- std::vector tokens;
-
- // Split by ' '
- while (std::getline(tokenStream, token, ' ')) {
- tokens.push_back(token);
- }
-
- std::string httpVersion;
- if (tokens.size() >= 1) {
- httpVersion = trim(tokens[0]);
- }
-
- int statusCode = -1;
- if (tokens.size() >= 2) {
- std::stringstream ss;
- ss << trim(tokens[1]);
- ss >> statusCode;
- }
-
- return std::make_pair(httpVersion, statusCode);
-}
-
-std::tuple
- Http::parseRequestLine(const std::string &line)
-{
- // Request-Line = Method SP Request-URI SP HTTP-Version CRLF
- std::string token;
- std::stringstream tokenStream(line);
- std::vector tokens;
-
- // Split by ' '
- while (std::getline(tokenStream, token, ' ')) {
- tokens.push_back(token);
- }
-
- std::string method;
- if (tokens.size() >= 1) {
- method = trim(tokens[0]);
- }
-
- std::string requestUri;
- if (tokens.size() >= 2) {
- requestUri = trim(tokens[1]);
- }
-
- std::string httpVersion;
- if (tokens.size() >= 3) {
- httpVersion = trim(tokens[2]);
- }
-
- return std::make_tuple(method, requestUri, httpVersion);
-}
-
-std::tuple
- Http::parseRequest(std::unique_ptr &socket, int timeoutSecs)
-{
- HttpRequestPtr httpRequest;
-
- std::atomic requestInitCancellation(false);
-
- auto isCancellationRequested =
- makeCancellationRequestWithTimeout(timeoutSecs,
- requestInitCancellation);
-
- // Read first line
- auto lineResult = socket->readLine(isCancellationRequested);
- auto lineValid = lineResult.first;
- auto line = lineResult.second;
-
- if (!lineValid) {
- return std::make_tuple(false,
- "Error reading HTTP request line",
- httpRequest);
- }
-
- // Parse request line (GET /foo HTTP/1.1\r\n)
- auto requestLine = Http::parseRequestLine(line);
- auto method = std::get<0>(requestLine);
- auto uri = std::get<1>(requestLine);
- auto httpVersion = std::get<2>(requestLine);
-
- // Retrieve and validate HTTP headers
- auto result = parseHttpHeaders(socket, isCancellationRequested);
- auto headersValid = result.first;
- auto headers = result.second;
-
- if (!headersValid) {
- return std::make_tuple(false,
- "Error parsing HTTP headers",
- httpRequest);
- }
-
- std::string body;
- if (headers.find("Content-Length") != headers.end()) {
- int contentLength = 0;
- try {
- contentLength = std::stoi(headers["Content-Length"]);
- } catch (const std::exception &) {
- return std::make_tuple(false,
- "Error parsing HTTP Header 'Content-Length'",
- httpRequest);
- }
-
- if (contentLength < 0) {
- return std::make_tuple(
- false,
- "Error: 'Content-Length' should be a positive integer",
- httpRequest);
- }
-
- auto res =
- socket->readBytes(contentLength, nullptr, isCancellationRequested);
- if (!res.first) {
- return std::make_tuple(false,
- std::string("Error reading request: ") +
- res.second,
- httpRequest);
- }
- body = res.second;
- }
-
- // If the content was compressed with gzip, decode it
- if (headers["Content-Encoding"] == "gzip") {
-#ifdef IXWEBSOCKET_USE_ZLIB
- std::string decompressedPayload;
- if (!gzipDecompress(body, decompressedPayload)) {
- return std::make_tuple(
- false,
- std::string("Error during gzip decompression of the body"),
- httpRequest);
- }
- body = decompressedPayload;
-#else
- std::string errorMsg(
- "ixwebsocket was not compiled with gzip support on");
- return std::make_tuple(false, errorMsg, httpRequest);
-#endif
- }
-
- httpRequest =
- std::make_shared(uri, method, httpVersion, body, headers);
- return std::make_tuple(true, "", httpRequest);
-}
-
-bool Http::sendResponse(HttpResponsePtr response,
- std::unique_ptr &socket)
-{
- // Write the response to the socket
- std::stringstream ss;
- ss << "HTTP/1.1 ";
- ss << response->statusCode;
- ss << " ";
- ss << response->description;
- ss << "\r\n";
-
- if (!socket->writeBytes(ss.str(), nullptr)) {
- return false;
- }
-
- // Write headers
- ss.str("");
- ss << "Content-Length: " << response->body.size() << "\r\n";
- for (auto &&it : response->headers) {
- ss << it.first << ": " << it.second << "\r\n";
- }
- ss << "\r\n";
-
- if (!socket->writeBytes(ss.str(), nullptr)) {
- return false;
- }
-
- return response->body.empty() ? true
- : socket->writeBytes(response->body, nullptr);
-}
-} // namespace ix
diff --git a/ixwebsocket/IXHttpClient.cpp b/ixwebsocket/IXHttpClient.cpp
deleted file mode 100644
index 7deb3d7..0000000
--- a/ixwebsocket/IXHttpClient.cpp
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * IXHttpClient.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXHttpClient.h"
-
-#include "IXGzipCodec.h"
-#include "IXSocketFactory.h"
-#include "IXUrlParser.h"
-#include "IXUserAgent.h"
-#include "IXWebSocketHttpHeaders.h"
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace ix
-{
-// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
-const std::string HttpClient::kPost = "POST";
-const std::string HttpClient::kGet = "GET";
-const std::string HttpClient::kHead = "HEAD";
-const std::string HttpClient::kDelete = "DELETE";
-const std::string HttpClient::kPut = "PUT";
-const std::string HttpClient::kPatch = "PATCH";
-
-HttpClient::HttpClient(bool async)
- : _async(async), _stop(false), _forceBody(false)
-{
- if (!_async)
- return;
-
- _thread = std::thread(&HttpClient::run, this);
-}
-
-HttpClient::~HttpClient()
-{
- if (!_thread.joinable())
- return;
-
- _stop = true;
- _condition.notify_one();
- _thread.join();
-}
-
-void HttpClient::setTLSOptions(const SocketTLSOptions &tlsOptions)
-{
- _tlsOptions = tlsOptions;
-}
-
-void HttpClient::setForceBody(bool value) { _forceBody = value; }
-
-HttpRequestArgsPtr HttpClient::createRequest(const std::string &url,
- const std::string &verb)
-{
- auto request = std::make_shared();
- request->url = url;
- request->verb = verb;
- return request;
-}
-
-bool HttpClient::performRequest(HttpRequestArgsPtr args,
- const OnResponseCallback &onResponseCallback)
-{
- assert(_async && "HttpClient needs its async parameter set to true "
- "in order to call performRequest");
- if (!_async)
- return false;
-
- // Enqueue the task
- {
- // acquire lock
- std::unique_lock lock(_queueMutex);
-
- // add the task
- _queue.push(std::make_pair(args, onResponseCallback));
- } // release lock
-
- // wake up one thread
- _condition.notify_one();
-
- return true;
-}
-
-void HttpClient::run()
-{
- while (true) {
- HttpRequestArgsPtr args;
- OnResponseCallback onResponseCallback;
-
- {
- std::unique_lock lock(_queueMutex);
-
- while (!_stop && _queue.empty()) {
- _condition.wait(lock);
- }
-
- if (_stop)
- return;
-
- auto p = _queue.front();
- _queue.pop();
-
- args = p.first;
- onResponseCallback = p.second;
- }
-
- if (_stop)
- return;
-
- HttpResponsePtr response =
- request(args->url, args->verb, args->body, args);
- onResponseCallback(response);
-
- if (_stop)
- return;
- }
-}
-
-HttpResponsePtr HttpClient::request(const std::string &url,
- const std::string &verb,
- const std::string &body,
- HttpRequestArgsPtr args,
- int redirects)
-{
- // We only have one socket connection, so we cannot
- // make multiple requests concurrently.
- std::lock_guard lock(_mutex);
-
- uint64_t uploadSize = 0;
- uint64_t downloadSize = 0;
- int code = 0;
- WebSocketHttpHeaders headers;
- std::string payload;
- std::string description;
-
- std::string protocol, host, path, query;
- int port;
-
- if (!UrlParser::parse(url, protocol, host, path, query, port)) {
- std::stringstream ss;
- ss << "Cannot parse url: " << url;
- return std::make_shared(code,
- description,
- HttpErrorCode::UrlMalformed,
- headers,
- payload,
- ss.str(),
- uploadSize,
- downloadSize);
- }
-
- bool tls = protocol == "https";
- std::string errorMsg;
- _socket = createSocket(tls, -1, errorMsg, _tlsOptions);
-
- if (!_socket) {
- return std::make_shared(code,
- description,
- HttpErrorCode::CannotCreateSocket,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
-
- // Build request string
- std::stringstream ss;
- ss << verb << " " << path << " HTTP/1.1\r\n";
- ss << "Host: " << host << "\r\n";
-
-#ifdef IXWEBSOCKET_USE_ZLIB
- if (args->compress) {
- ss << "Accept-Encoding: gzip"
- << "\r\n";
- }
-#endif
-
- // Append extra headers
- for (auto &&it : args->extraHeaders) {
- ss << it.first << ": " << it.second << "\r\n";
- }
-
- // Set a default Accept header if none is present
- if (args->extraHeaders.find("Accept") == args->extraHeaders.end()) {
- ss << "Accept: */*"
- << "\r\n";
- }
-
- // Set a default User agent if none is present
- if (args->extraHeaders.find("User-Agent") == args->extraHeaders.end()) {
- ss << "User-Agent: " << userAgent() << "\r\n";
- }
-
- if (verb == kPost || verb == kPut || verb == kPatch || _forceBody) {
- // Set request compression header
-#ifdef IXWEBSOCKET_USE_ZLIB
- if (args->compressRequest) {
- ss << "Content-Encoding: gzip"
- << "\r\n";
- }
-#endif
-
- ss << "Content-Length: " << body.size() << "\r\n";
-
- // Set default Content-Type if unspecified
- if (args->extraHeaders.find("Content-Type") ==
- args->extraHeaders.end()) {
- if (args->multipartBoundary.empty()) {
- ss << "Content-Type: application/x-www-form-urlencoded"
- << "\r\n";
- } else {
- ss << "Content-Type: multipart/form-data; boundary="
- << args->multipartBoundary << "\r\n";
- }
- }
- ss << "\r\n";
- ss << body;
- } else {
- ss << "\r\n";
- }
-
- std::string req(ss.str());
- std::string errMsg;
-
- // Make a cancellation object dealing with connection timeout
- auto isCancellationRequested =
- makeCancellationRequestWithTimeout(args->connectTimeout, _stop);
-
- bool success =
- _socket->connect(host, port, errMsg, isCancellationRequested);
- if (!success) {
- std::stringstream ss;
- ss << "Cannot connect to url: " << url << " / error : " << errMsg;
- return std::make_shared(code,
- description,
- HttpErrorCode::CannotConnect,
- headers,
- payload,
- ss.str(),
- uploadSize,
- downloadSize);
- }
-
- // Make a new cancellation object dealing with transfer timeout
- isCancellationRequested =
- makeCancellationRequestWithTimeout(args->transferTimeout, _stop);
-
- if (args->verbose) {
- std::stringstream ss;
- ss << "Sending " << verb << " request "
- << "to " << host << ":" << port << std::endl
- << "request size: " << req.size() << " bytes" << std::endl
- << "=============" << std::endl
- << req << "=============" << std::endl
- << std::endl;
-
- log(ss.str(), args);
- }
-
- if (!_socket->writeBytes(req, isCancellationRequested)) {
- std::string errorMsg("Cannot send request");
- return std::make_shared(code,
- description,
- HttpErrorCode::SendError,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
-
- uploadSize = req.size();
-
- auto lineResult = _socket->readLine(isCancellationRequested);
- auto lineValid = lineResult.first;
- auto line = lineResult.second;
-
- if (!lineValid) {
- std::string errorMsg("Cannot retrieve status line");
- return std::make_shared(
- code,
- description,
- HttpErrorCode::CannotReadStatusLine,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
-
- if (args->verbose) {
- std::stringstream ss;
- ss << "Status line " << line;
- log(ss.str(), args);
- }
-
- if (sscanf(line.c_str(), "HTTP/1.1 %d", &code) != 1) {
- std::string errorMsg("Cannot parse response code from status line");
- return std::make_shared(code,
- description,
- HttpErrorCode::MissingStatus,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
-
- auto result = parseHttpHeaders(_socket, isCancellationRequested);
- auto headersValid = result.first;
- headers = result.second;
-
- if (!headersValid) {
- std::string errorMsg("Cannot parse http headers");
- return std::make_shared(code,
- description,
- HttpErrorCode::HeaderParsingError,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
-
- // Redirect ?
- if ((code >= 301 && code <= 308) && args->followRedirects) {
- if (headers.find("Location") == headers.end()) {
- std::string errorMsg("Missing location header for redirect");
- return std::make_shared(
- code,
- description,
- HttpErrorCode::MissingLocation,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
-
- if (redirects >= args->maxRedirects) {
- std::stringstream ss;
- ss << "Too many redirects: " << redirects;
- return std::make_shared(
- code,
- description,
- HttpErrorCode::TooManyRedirects,
- headers,
- payload,
- ss.str(),
- uploadSize,
- downloadSize);
- }
-
- // Recurse
- std::string location = headers["Location"];
- return request(location, verb, body, args, redirects + 1);
- }
-
- if (verb == "HEAD") {
- return std::make_shared(code,
- description,
- HttpErrorCode::Ok,
- headers,
- payload,
- std::string(),
- uploadSize,
- downloadSize);
- }
-
- // Parse response:
- if (headers.find("Content-Length") != headers.end()) {
- ssize_t contentLength = -1;
- ss.str("");
- ss << headers["Content-Length"];
- ss >> contentLength;
-
- payload.reserve(contentLength);
-
- auto chunkResult = _socket->readBytes(contentLength,
- args->onProgressCallback,
- isCancellationRequested);
- if (!chunkResult.first) {
- errorMsg = "Cannot read chunk";
- return std::make_shared(code,
- description,
- HttpErrorCode::ChunkReadError,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
- payload += chunkResult.second;
- } else if (headers.find("Transfer-Encoding") != headers.end() &&
- headers["Transfer-Encoding"] == "chunked") {
- std::stringstream ss;
-
- while (true) {
- lineResult = _socket->readLine(isCancellationRequested);
- line = lineResult.second;
-
- if (!lineResult.first) {
- return std::make_shared(
- code,
- description,
- HttpErrorCode::ChunkReadError,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
-
- uint64_t chunkSize;
- ss.str("");
- ss << std::hex << line;
- ss >> chunkSize;
-
- if (args->verbose) {
- std::stringstream oss;
- oss << "Reading " << chunkSize << " bytes" << std::endl;
- log(oss.str(), args);
- }
-
- payload.reserve(payload.size() + (size_t)chunkSize);
-
- // Read a chunk
- auto chunkResult = _socket->readBytes((size_t)chunkSize,
- args->onProgressCallback,
- isCancellationRequested);
- if (!chunkResult.first) {
- errorMsg = "Cannot read chunk";
- return std::make_shared(
- code,
- description,
- HttpErrorCode::ChunkReadError,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
- payload += chunkResult.second;
-
- // Read the line that terminates the chunk (\r\n)
- lineResult = _socket->readLine(isCancellationRequested);
-
- if (!lineResult.first) {
- return std::make_shared(
- code,
- description,
- HttpErrorCode::ChunkReadError,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
-
- if (chunkSize == 0)
- break;
- }
- } else if (code == 204) {
- ; // 204 is NoContent response code
- } else {
- std::string errorMsg("Cannot read http body");
- return std::make_shared(code,
- description,
- HttpErrorCode::CannotReadBody,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
-
- downloadSize = payload.size();
-
- // If the content was compressed with gzip, decode it
- if (headers["Content-Encoding"] == "gzip") {
-#ifdef IXWEBSOCKET_USE_ZLIB
- std::string decompressedPayload;
- if (!gzipDecompress(payload, decompressedPayload)) {
- std::string errorMsg("Error decompressing payload");
- return std::make_shared(code,
- description,
- HttpErrorCode::Gzip,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
- }
- payload = decompressedPayload;
-#else
- std::string errorMsg(
- "ixwebsocket was not compiled with gzip support on");
- return std::make_shared(code,
- description,
- HttpErrorCode::Gzip,
- headers,
- payload,
- errorMsg,
- uploadSize,
- downloadSize);
-#endif
- }
-
- return std::make_shared(code,
- description,
- HttpErrorCode::Ok,
- headers,
- payload,
- std::string(),
- uploadSize,
- downloadSize);
-}
-
-HttpResponsePtr HttpClient::get(const std::string &url, HttpRequestArgsPtr args)
-{
- return request(url, kGet, std::string(), args);
-}
-
-HttpResponsePtr HttpClient::head(const std::string &url,
- HttpRequestArgsPtr args)
-{
- return request(url, kHead, std::string(), args);
-}
-
-HttpResponsePtr HttpClient::Delete(const std::string &url,
- HttpRequestArgsPtr args)
-{
- return request(url, kDelete, std::string(), args);
-}
-
-HttpResponsePtr
- HttpClient::request(const std::string &url,
- const std::string &verb,
- const HttpParameters &httpParameters,
- const HttpFormDataParameters &httpFormDataParameters,
- HttpRequestArgsPtr args)
-{
- std::string body;
-
- if (httpFormDataParameters.empty()) {
- body = serializeHttpParameters(httpParameters);
- } else {
- std::string multipartBoundary = generateMultipartBoundary();
- args->multipartBoundary = multipartBoundary;
- body = serializeHttpFormDataParameters(multipartBoundary,
- httpFormDataParameters,
- httpParameters);
- }
-
-#ifdef IXWEBSOCKET_USE_ZLIB
- if (args->compressRequest) {
- body = gzipCompress(body);
- }
-#endif
-
- return request(url, verb, body, args);
-}
-
-HttpResponsePtr
- HttpClient::post(const std::string &url,
- const HttpParameters &httpParameters,
- const HttpFormDataParameters &httpFormDataParameters,
- HttpRequestArgsPtr args)
-{
- return request(url, kPost, httpParameters, httpFormDataParameters, args);
-}
-
-HttpResponsePtr HttpClient::post(const std::string &url,
- const std::string &body,
- HttpRequestArgsPtr args)
-{
- return request(url, kPost, body, args);
-}
-
-HttpResponsePtr
- HttpClient::put(const std::string &url,
- const HttpParameters &httpParameters,
- const HttpFormDataParameters &httpFormDataParameters,
- HttpRequestArgsPtr args)
-{
- return request(url, kPut, httpParameters, httpFormDataParameters, args);
-}
-
-HttpResponsePtr HttpClient::put(const std::string &url,
- const std::string &body,
- const HttpRequestArgsPtr args)
-{
- return request(url, kPut, body, args);
-}
-
-HttpResponsePtr
- HttpClient::patch(const std::string &url,
- const HttpParameters &httpParameters,
- const HttpFormDataParameters &httpFormDataParameters,
- HttpRequestArgsPtr args)
-{
- return request(url, kPatch, httpParameters, httpFormDataParameters, args);
-}
-
-HttpResponsePtr HttpClient::patch(const std::string &url,
- const std::string &body,
- const HttpRequestArgsPtr args)
-{
- return request(url, kPatch, body, args);
-}
-
-std::string HttpClient::urlEncode(const std::string &value)
-{
- std::ostringstream escaped;
- escaped.fill('0');
- escaped << std::hex;
-
- for (std::string::const_iterator i = value.begin(), n = value.end(); i != n;
- ++i) {
- std::string::value_type c = (*i);
-
- // Keep alphanumeric and other accepted characters intact
- if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
- escaped << c;
- continue;
- }
-
- // Any other characters are percent-encoded
- escaped << std::uppercase;
- escaped << '%' << std::setw(2) << int((unsigned char)c);
- escaped << std::nouppercase;
- }
-
- return escaped.str();
-}
-
-std::string
- HttpClient::serializeHttpParameters(const HttpParameters &httpParameters)
-{
- std::stringstream ss;
- size_t count = httpParameters.size();
- size_t i = 0;
-
- for (auto &&it : httpParameters) {
- ss << urlEncode(it.first) << "=" << urlEncode(it.second);
-
- if (i++ < (count - 1)) {
- ss << "&";
- }
- }
- return ss.str();
-}
-
-std::string HttpClient::serializeHttpFormDataParameters(
- const std::string &multipartBoundary,
- const HttpFormDataParameters &httpFormDataParameters,
- const HttpParameters &httpParameters)
-{
- //
- // --AaB03x
- // Content-Disposition: form-data; name="submit-name"
-
- // Larry
- // --AaB03x
- // Content-Disposition: form-data; name="foo.txt"; filename="file1.txt"
- // Content-Type: text/plain
-
- // ... contents of file1.txt ...
- // --AaB03x--
- //
- std::stringstream ss;
-
- for (auto &&it : httpFormDataParameters) {
- ss << "--" << multipartBoundary << "\r\n"
- << "Content-Disposition:"
- << " form-data; name=\"" << it.first << "\";"
- << " filename=\"" << it.first << "\""
- << "\r\n"
- << "Content-Type: application/octet-stream"
- << "\r\n"
- << "\r\n"
- << it.second << "\r\n";
- }
-
- for (auto &&it : httpParameters) {
- ss << "--" << multipartBoundary << "\r\n"
- << "Content-Disposition:"
- << " form-data; name=\"" << it.first << "\";"
- << "\r\n"
- << "\r\n"
- << it.second << "\r\n";
- }
-
- ss << "--" << multipartBoundary << "--\r\n";
-
- return ss.str();
-}
-
-void HttpClient::log(const std::string &msg, HttpRequestArgsPtr args)
-{
- if (args->logger) {
- args->logger(msg);
- }
-}
-
-std::string HttpClient::generateMultipartBoundary()
-{
- std::string str(
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
-
- static std::random_device rd;
- static std::mt19937 generator(rd());
-
- std::shuffle(str.begin(), str.end(), generator);
-
- return str;
-}
-} // namespace ix
diff --git a/ixwebsocket/IXHttpServer.cpp b/ixwebsocket/IXHttpServer.cpp
deleted file mode 100644
index 743394c..0000000
--- a/ixwebsocket/IXHttpServer.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * IXHttpServer.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXHttpServer.h"
-
-#include "IXGzipCodec.h"
-#include "IXNetSystem.h"
-#include "IXSocketConnect.h"
-#include "IXUserAgent.h"
-#include
-#include
-#include
-#include
-
-namespace
-{
-std::pair> load(const std::string &path)
-{
- std::vector memblock;
-
- std::ifstream file(path);
- if (!file.is_open())
- return std::make_pair(false, memblock);
-
- file.seekg(0, file.end);
- std::streamoff size = file.tellg();
- file.seekg(0, file.beg);
-
- memblock.resize((size_t)size);
- file.read((char *)&memblock.front(), static_cast(size));
-
- return std::make_pair(true, memblock);
-}
-
-std::pair readAsString(const std::string &path)
-{
- auto res = load(path);
- auto vec = res.second;
- return std::make_pair(res.first, std::string(vec.begin(), vec.end()));
-}
-} // namespace
-
-namespace ix
-{
-const int HttpServer::kDefaultTimeoutSecs(30);
-
-HttpServer::HttpServer(int port,
- const std::string &host,
- int backlog,
- size_t maxConnections,
- int addressFamily,
- int timeoutSecs)
- : SocketServer(port, host, backlog, maxConnections, addressFamily),
- _connectedClientsCount(0), _timeoutSecs(timeoutSecs)
-{
- setDefaultConnectionCallback();
-}
-
-HttpServer::~HttpServer() { stop(); }
-
-void HttpServer::stop()
-{
- stopAcceptingConnections();
-
- // FIXME: cancelling / closing active clients ...
-
- SocketServer::stop();
-}
-
-void HttpServer::setOnConnectionCallback(const OnConnectionCallback &callback)
-{
- _onConnectionCallback = callback;
-}
-
-void HttpServer::handleConnection(
- std::unique_ptr socket,
- std::shared_ptr connectionState)
-{
- _connectedClientsCount++;
-
- auto ret = Http::parseRequest(socket, _timeoutSecs);
- // FIXME: handle errors in parseRequest
-
- if (std::get<0>(ret)) {
- auto response =
- _onConnectionCallback(std::get<2>(ret), connectionState);
- if (!Http::sendResponse(response, socket)) {
- logError("Cannot send response");
- }
- }
- connectionState->setTerminated();
-
- _connectedClientsCount--;
-}
-
-size_t HttpServer::getConnectedClientsCount() { return _connectedClientsCount; }
-
-void HttpServer::setDefaultConnectionCallback()
-{
- setOnConnectionCallback(
- [this](HttpRequestPtr request,
- std::shared_ptr connectionState)
- -> HttpResponsePtr {
- std::string uri(request->uri);
- if (uri.empty() || uri == "/") {
- uri = "/index.html";
- }
-
- WebSocketHttpHeaders headers;
- headers["Server"] = userAgent();
-
- std::string path("." + uri);
- auto res = readAsString(path);
- bool found = res.first;
- if (!found) {
- return std::make_shared(404,
- "Not Found",
- HttpErrorCode::Ok,
- WebSocketHttpHeaders(),
- std::string());
- }
-
- std::string content = res.second;
-
-#ifdef IXWEBSOCKET_USE_ZLIB
- std::string acceptEncoding = request->headers["Accept-encoding"];
- if (acceptEncoding == "*" ||
- acceptEncoding.find("gzip") != std::string::npos) {
- content = gzipCompress(content);
- headers["Content-Encoding"] = "gzip";
- }
-#endif
-
- // Log request
- std::stringstream ss;
- ss << connectionState->getRemoteIp() << ":"
- << connectionState->getRemotePort() << " " << request->method
- << " " << request->headers["User-Agent"] << " " << request->uri
- << " " << content.size();
- logInfo(ss.str());
-
- // FIXME: check extensions to set the content type
- // headers["Content-Type"] = "application/octet-stream";
- headers["Accept-Ranges"] = "none";
-
- for (auto &&it : request->headers) {
- headers[it.first] = it.second;
- }
-
- return std::make_shared(200,
- "OK",
- HttpErrorCode::Ok,
- headers,
- content);
- });
-}
-
-void HttpServer::makeRedirectServer(const std::string &redirectUrl)
-{
- //
- // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections
- //
- setOnConnectionCallback(
- [this, redirectUrl](HttpRequestPtr request,
- std::shared_ptr connectionState)
- -> HttpResponsePtr {
- WebSocketHttpHeaders headers;
- headers["Server"] = userAgent();
-
- // Log request
- std::stringstream ss;
- ss << connectionState->getRemoteIp() << ":"
- << connectionState->getRemotePort() << " " << request->method
- << " " << request->headers["User-Agent"] << " " << request->uri;
- logInfo(ss.str());
-
- if (request->method == "POST") {
- return std::make_shared(200,
- "OK",
- HttpErrorCode::Ok,
- headers,
- std::string());
- }
-
- headers["Location"] = redirectUrl;
-
- return std::make_shared(301,
- "OK",
- HttpErrorCode::Ok,
- headers,
- std::string());
- });
-}
-
-//
-// Display the client parameter and body on the console
-//
-void HttpServer::makeDebugServer()
-{
- setOnConnectionCallback(
- [this](HttpRequestPtr request,
- std::shared_ptr connectionState)
- -> HttpResponsePtr {
- WebSocketHttpHeaders headers;
- headers["Server"] = userAgent();
-
- // Log request
- std::stringstream ss;
- ss << connectionState->getRemoteIp() << ":"
- << connectionState->getRemotePort() << " " << request->method
- << " " << request->headers["User-Agent"] << " " << request->uri;
- logInfo(ss.str());
-
- logInfo("== Headers == ");
- for (auto &&it : request->headers) {
- std::ostringstream oss;
- oss << it.first << ": " << it.second;
- logInfo(oss.str());
- }
- logInfo("");
-
- logInfo("== Body == ");
- logInfo(request->body);
- logInfo("");
-
- return std::make_shared(200,
- "OK",
- HttpErrorCode::Ok,
- headers,
- std::string("OK"));
- });
-}
-
-int HttpServer::getTimeoutSecs() { return _timeoutSecs; }
-
-} // namespace ix
diff --git a/ixwebsocket/IXNetSystem.cpp b/ixwebsocket/IXNetSystem.cpp
deleted file mode 100644
index ea5b105..0000000
--- a/ixwebsocket/IXNetSystem.cpp
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * IXNetSystem.cpp
- * Author: Korchynskyi Dmytro
- * Copyright (c) 2019 Machine Zone. All rights reserved.
- */
-
-#include "IXNetSystem.h"
-#include
-#include
-
-namespace ix
-{
-bool initNetSystem()
-{
-#ifdef _WIN32
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- // Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h
- wVersionRequested = MAKEWORD(2, 2);
- err = WSAStartup(wVersionRequested, &wsaData);
-
- return err == 0;
-#else
- return true;
-#endif
-}
-
-bool uninitNetSystem()
-{
-#ifdef _WIN32
- int err = WSACleanup();
- return err == 0;
-#else
- return true;
-#endif
-}
-
-//
-// That function could 'return WSAPoll(pfd, nfds, timeout);'
-// but WSAPoll is said to have weird behaviors on the internet
-// (the curl folks have had problems with it).
-//
-// So we make it a select wrapper
-//
-int poll(struct pollfd *fds, nfds_t nfds, int timeout)
-{
-#ifdef _WIN32
- socket_t maxfd = 0;
- fd_set readfds, writefds, errorfds;
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_ZERO(&errorfds);
-
- for (nfds_t i = 0; i < nfds; ++i) {
- struct pollfd *fd = &fds[i];
-
- if (fd->fd > maxfd) {
- maxfd = fd->fd;
- }
- if ((fd->events & POLLIN)) {
- FD_SET(fd->fd, &readfds);
- }
- if ((fd->events & POLLOUT)) {
- FD_SET(fd->fd, &writefds);
- }
- if ((fd->events & POLLERR)) {
- FD_SET(fd->fd, &errorfds);
- }
- }
-
- struct timeval tv;
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
-
- int ret = select(maxfd + 1,
- &readfds,
- &writefds,
- &errorfds,
- timeout != -1 ? &tv : NULL);
-
- if (ret < 0) {
- return ret;
- }
-
- for (nfds_t i = 0; i < nfds; ++i) {
- struct pollfd *fd = &fds[i];
- fd->revents = 0;
-
- if (FD_ISSET(fd->fd, &readfds)) {
- fd->revents |= POLLIN;
- }
- if (FD_ISSET(fd->fd, &writefds)) {
- fd->revents |= POLLOUT;
- }
- if (FD_ISSET(fd->fd, &errorfds)) {
- fd->revents |= POLLERR;
- }
- }
-
- return ret;
-#else
- //
- // It was reported that on Android poll can fail and return -1 with
- // errno == EINTR, which should be a temp error and should typically
- // be handled by retrying in a loop.
- // Maybe we need to put all syscall / C functions in
- // a new IXSysCalls.cpp and wrap them all.
- //
- // The style from libuv is as such.
- //
- int ret = -1;
- do {
- ret = ::poll(fds, nfds, timeout);
- } while (ret == -1 && errno == EINTR);
-
- return ret;
-#endif
-}
-
-//
-// mingw does not have inet_ntop, which were taken as is from the musl C
-// library.
-//
-const char *inet_ntop(int af, const void *a0, char *s, socklen_t l)
-{
-#if defined(_WIN32) && defined(__GNUC__)
- const unsigned char *a = (const unsigned char *)a0;
- int i, j, max, best;
- char buf[100];
-
- switch (af) {
- case AF_INET:
- if (snprintf(s, l, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]) < l)
- return s;
- break;
- case AF_INET6:
- if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\377\377", 12))
- snprintf(buf,
- sizeof buf,
- "%x:%x:%x:%x:%x:%x:%x:%x",
- 256 * a[0] + a[1],
- 256 * a[2] + a[3],
- 256 * a[4] + a[5],
- 256 * a[6] + a[7],
- 256 * a[8] + a[9],
- 256 * a[10] + a[11],
- 256 * a[12] + a[13],
- 256 * a[14] + a[15]);
- else
- snprintf(buf,
- sizeof buf,
- "%x:%x:%x:%x:%x:%x:%d.%d.%d.%d",
- 256 * a[0] + a[1],
- 256 * a[2] + a[3],
- 256 * a[4] + a[5],
- 256 * a[6] + a[7],
- 256 * a[8] + a[9],
- 256 * a[10] + a[11],
- a[12],
- a[13],
- a[14],
- a[15]);
- /* Replace longest /(^0|:)[:0]{2,}/ with "::" */
- for (i = best = 0, max = 2; buf[i]; i++) {
- if (i && buf[i] != ':')
- continue;
- j = strspn(buf + i, ":0");
- if (j > max)
- best = i, max = j;
- }
- if (max > 3) {
- buf[best] = buf[best + 1] = ':';
- memmove(buf + best + 2, buf + best + max, i - best - max + 1);
- }
- if (strlen(buf) < l) {
- strcpy(s, buf);
- return s;
- }
- break;
- default:
- errno = EAFNOSUPPORT;
- return 0;
- }
- errno = ENOSPC;
- return 0;
-#else
- return ::inet_ntop(af, a0, s, l);
-#endif
-}
-
-#if defined(_WIN32) && defined(__GNUC__)
-static int hexval(unsigned c)
-{
- if (c - '0' < 10)
- return c - '0';
- c |= 32;
- if (c - 'a' < 6)
- return c - 'a' + 10;
- return -1;
-}
-#endif
-
-//
-// mingw does not have inet_pton, which were taken as is from the musl C
-// library.
-//
-int inet_pton(int af, const char *s, void *a0)
-{
-#if defined(_WIN32) && defined(__GNUC__)
- uint16_t ip[8];
- unsigned char *a = (unsigned char *)a0;
- int i, j, v, d, brk = -1, need_v4 = 0;
-
- if (af == AF_INET) {
- for (i = 0; i < 4; i++) {
- for (v = j = 0; j < 3 && isdigit(s[j]); j++)
- v = 10 * v + s[j] - '0';
- if (j == 0 || (j > 1 && s[0] == '0') || v > 255)
- return 0;
- a[i] = v;
- if (s[j] == 0 && i == 3)
- return 1;
- if (s[j] != '.')
- return 0;
- s += j + 1;
- }
- return 0;
- } else if (af != AF_INET6) {
- errno = EAFNOSUPPORT;
- return -1;
- }
-
- if (*s == ':' && *++s != ':')
- return 0;
-
- for (i = 0;; i++) {
- if (s[0] == ':' && brk < 0) {
- brk = i;
- ip[i & 7] = 0;
- if (!*++s)
- break;
- if (i == 7)
- return 0;
- continue;
- }
- for (v = j = 0; j < 4 && (d = hexval(s[j])) >= 0; j++)
- v = 16 * v + d;
- if (j == 0)
- return 0;
- ip[i & 7] = v;
- if (!s[j] && (brk >= 0 || i == 7))
- break;
- if (i == 7)
- return 0;
- if (s[j] != ':') {
- if (s[j] != '.' || (i < 6 && brk < 0))
- return 0;
- need_v4 = 1;
- i++;
- break;
- }
- s += j + 1;
- }
- if (brk >= 0) {
- memmove(ip + brk + 7 - i, ip + brk, 2 * (i + 1 - brk));
- for (j = 0; j < 7 - i; j++)
- ip[brk + j] = 0;
- }
- for (j = 0; j < 8; j++) {
- *a++ = ip[j] >> 8;
- *a++ = ip[j];
- }
- if (need_v4 && inet_pton(AF_INET, (const char *)s, a - 4) <= 0)
- return 0;
- return 1;
-#else
- return ::inet_pton(af, s, a0);
-#endif
-}
-
-// Convert network bytes to host bytes. Copied from the ASIO library
-unsigned short network_to_host_short(unsigned short value)
-{
-#if defined(_WIN32)
- unsigned char *value_p = reinterpret_cast(&value);
- unsigned short result = (static_cast(value_p[0]) << 8) |
- static_cast(value_p[1]);
- return result;
-#else // defined(_WIN32)
- return ntohs(value);
-#endif // defined(_WIN32)
-}
-
-} // namespace ix
diff --git a/ixwebsocket/IXSelectInterrupt.cpp b/ixwebsocket/IXSelectInterrupt.cpp
deleted file mode 100644
index f29a837..0000000
--- a/ixwebsocket/IXSelectInterrupt.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * IXSelectInterrupt.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXSelectInterrupt.h"
-
-namespace ix
-{
-const uint64_t SelectInterrupt::kSendRequest = 1;
-const uint64_t SelectInterrupt::kCloseRequest = 2;
-
-SelectInterrupt::SelectInterrupt() { ; }
-
-SelectInterrupt::~SelectInterrupt() { ; }
-
-bool SelectInterrupt::init(std::string & /*errorMsg*/) { return true; }
-
-bool SelectInterrupt::notify(uint64_t /*value*/) { return true; }
-
-uint64_t SelectInterrupt::read() { return 0; }
-
-bool SelectInterrupt::clear() { return true; }
-
-int SelectInterrupt::getFd() const { return -1; }
-} // namespace ix
diff --git a/ixwebsocket/IXSelectInterruptFactory.cpp b/ixwebsocket/IXSelectInterruptFactory.cpp
deleted file mode 100644
index 9ab6347..0000000
--- a/ixwebsocket/IXSelectInterruptFactory.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * IXSelectInterruptFactory.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXSelectInterruptFactory.h"
-
-#include "IXUniquePtr.h"
-#if defined(__linux__) || defined(__APPLE__)
-#include "IXSelectInterruptPipe.h"
-#else
-#include "IXSelectInterrupt.h"
-#endif
-
-namespace ix
-{
-SelectInterruptPtr createSelectInterrupt()
-{
-#if defined(__linux__) || defined(__APPLE__)
- return ix::make_unique();
-#else
- return ix::make_unique();
-#endif
-}
-} // namespace ix
diff --git a/ixwebsocket/IXSelectInterruptPipe.cpp b/ixwebsocket/IXSelectInterruptPipe.cpp
deleted file mode 100644
index def317f..0000000
--- a/ixwebsocket/IXSelectInterruptPipe.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * IXSelectInterruptPipe.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2018-2019 Machine Zone, Inc. All rights reserved.
- */
-
-//
-// On UNIX we use pipes to wake up select. There is no way to do that
-// on Windows so this file is compiled out on Windows.
-//
-#ifndef _WIN32
-
-#include "IXSelectInterruptPipe.h"
-
-#include
-#include
-#include
-#include
-#include // for strerror
-#include // for write
-
-namespace ix
-{
-// File descriptor at index 0 in _fildes is the read end of the pipe
-// File descriptor at index 1 in _fildes is the write end of the pipe
-const int SelectInterruptPipe::kPipeReadIndex = 0;
-const int SelectInterruptPipe::kPipeWriteIndex = 1;
-
-SelectInterruptPipe::SelectInterruptPipe()
-{
- _fildes[kPipeReadIndex] = -1;
- _fildes[kPipeWriteIndex] = -1;
-}
-
-SelectInterruptPipe::~SelectInterruptPipe()
-{
- ::close(_fildes[kPipeReadIndex]);
- ::close(_fildes[kPipeWriteIndex]);
- _fildes[kPipeReadIndex] = -1;
- _fildes[kPipeWriteIndex] = -1;
-}
-
-bool SelectInterruptPipe::init(std::string &errorMsg)
-{
- std::lock_guard lock(_fildesMutex);
-
- // calling init twice is a programming error
- assert(_fildes[kPipeReadIndex] == -1);
- assert(_fildes[kPipeWriteIndex] == -1);
-
- if (pipe(_fildes) < 0) {
- std::stringstream ss;
- ss << "SelectInterruptPipe::init() failed in pipe() call"
- << " : " << strerror(errno);
- errorMsg = ss.str();
- return false;
- }
-
- if (fcntl(_fildes[kPipeReadIndex], F_SETFL, O_NONBLOCK) == -1) {
- std::stringstream ss;
- ss << "SelectInterruptPipe::init() failed in fcntl(..., O_NONBLOCK) "
- "call"
- << " : " << strerror(errno);
- errorMsg = ss.str();
-
- _fildes[kPipeReadIndex] = -1;
- _fildes[kPipeWriteIndex] = -1;
- return false;
- }
-
- if (fcntl(_fildes[kPipeWriteIndex], F_SETFL, O_NONBLOCK) == -1) {
- std::stringstream ss;
- ss << "SelectInterruptPipe::init() failed in fcntl(..., O_NONBLOCK) "
- "call"
- << " : " << strerror(errno);
- errorMsg = ss.str();
-
- _fildes[kPipeReadIndex] = -1;
- _fildes[kPipeWriteIndex] = -1;
- return false;
- }
-
-#ifdef F_SETNOSIGPIPE
- if (fcntl(_fildes[kPipeWriteIndex], F_SETNOSIGPIPE, 1) == -1) {
- std::stringstream ss;
- ss << "SelectInterruptPipe::init() failed in fcntl(.... "
- "F_SETNOSIGPIPE) call"
- << " : " << strerror(errno);
- errorMsg = ss.str();
-
- _fildes[kPipeReadIndex] = -1;
- _fildes[kPipeWriteIndex] = -1;
- return false;
- }
-
- if (fcntl(_fildes[kPipeWriteIndex], F_SETNOSIGPIPE, 1) == -1) {
- std::stringstream ss;
- ss << "SelectInterruptPipe::init() failed in fcntl(..., "
- "F_SETNOSIGPIPE) call"
- << " : " << strerror(errno);
- errorMsg = ss.str();
-
- _fildes[kPipeReadIndex] = -1;
- _fildes[kPipeWriteIndex] = -1;
- return false;
- }
-#endif
-
- return true;
-}
-
-bool SelectInterruptPipe::notify(uint64_t value)
-{
- std::lock_guard lock(_fildesMutex);
-
- int fd = _fildes[kPipeWriteIndex];
- if (fd == -1)
- return false;
-
- ssize_t ret = -1;
- do {
- ret = ::write(fd, &value, sizeof(value));
- } while (ret == -1 && errno == EINTR);
-
- // we should write 8 bytes for an uint64_t
- return ret == 8;
-}
-
-// TODO: return max uint64_t for errors ?
-uint64_t SelectInterruptPipe::read()
-{
- std::lock_guard lock(_fildesMutex);
-
- int fd = _fildes[kPipeReadIndex];
-
- uint64_t value = 0;
-
- ssize_t ret = -1;
- do {
- ret = ::read(fd, &value, sizeof(value));
- } while (ret == -1 && errno == EINTR);
-
- return value;
-}
-
-bool SelectInterruptPipe::clear() { return true; }
-
-int SelectInterruptPipe::getFd() const
-{
- std::lock_guard lock(_fildesMutex);
-
- return _fildes[kPipeReadIndex];
-}
-} // namespace ix
-
-#endif // !_WIN32
diff --git a/ixwebsocket/IXSetThreadName.cpp b/ixwebsocket/IXSetThreadName.cpp
deleted file mode 100644
index f4f83f8..0000000
--- a/ixwebsocket/IXSetThreadName.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * IXSetThreadName.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2018 2020 Machine Zone, Inc. All rights reserved.
- */
-#include "IXSetThreadName.h"
-
-// unix systems
-#if defined(__APPLE__) || defined(__linux__) || defined(BSD)
-#include
-#endif
-
-// freebsd needs this header as well
-#if defined(BSD)
-#include
-#endif
-
-// Windows
-#ifdef _WIN32
-#include
-#endif
-
-namespace ix
-{
-#ifdef _WIN32
-const DWORD MS_VC_EXCEPTION = 0x406D1388;
-
-#pragma pack(push, 8)
-typedef struct tagTHREADNAME_INFO {
- DWORD dwType; // Must be 0x1000.
- LPCSTR szName; // Pointer to name (in user addr space).
- DWORD dwThreadID; // Thread ID (-1=caller thread).
- DWORD dwFlags; // Reserved for future use, must be zero.
-} THREADNAME_INFO;
-#pragma pack(pop)
-
-void SetThreadName(DWORD dwThreadID, const char *threadName)
-{
-#ifndef __GNUC__
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = threadName;
- info.dwThreadID = dwThreadID;
- info.dwFlags = 0;
-
- __try {
- RaiseException(MS_VC_EXCEPTION,
- 0,
- sizeof(info) / sizeof(ULONG_PTR),
- (ULONG_PTR *)&info);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- }
-#endif
-}
-#endif
-
-void setThreadName(const std::string &name)
-{
-#if defined(__APPLE__)
- //
- // Apple reserves 16 bytes for its thread names
- // Notice that the Apple version of pthread_setname_np
- // does not take a pthread_t argument
- //
- pthread_setname_np(name.substr(0, 63).c_str());
-#elif defined(__linux__)
- //
- // Linux only reserves 16 bytes for its thread names
- // See prctl and PR_SET_NAME property in
- // http://man7.org/linux/man-pages/man2/prctl.2.html
- //
- pthread_setname_np(pthread_self(), name.substr(0, 15).c_str());
-#elif defined(_WIN32)
- SetThreadName(-1, name.c_str());
-#elif defined(BSD)
- pthread_set_name_np(pthread_self(), name.substr(0, 15).c_str());
-#else
- // ... assert here ?
-#endif
-}
-} // namespace ix
diff --git a/ixwebsocket/IXSocket.cpp b/ixwebsocket/IXSocket.cpp
deleted file mode 100644
index 1f00d96..0000000
--- a/ixwebsocket/IXSocket.cpp
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * IXSocket.cpp
- * Author: Benjamin Sergeant
- * Copyright (c) 2017-2018 Machine Zone, Inc. All rights reserved.
- */
-
-#include "IXSocket.h"
-
-#include "IXNetSystem.h"
-#include "IXSelectInterrupt.h"
-#include "IXSelectInterruptFactory.h"
-#include "IXSocketConnect.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifdef min
-#undef min
-#endif
-
-namespace ix
-{
-const int Socket::kDefaultPollNoTimeout = -1; // No poll timeout by default
-const int Socket::kDefaultPollTimeout = kDefaultPollNoTimeout;
-
-Socket::Socket(int fd) : _sockfd(fd), _selectInterrupt(createSelectInterrupt())
-{
- ;
-}
-
-Socket::~Socket() { close(); }
-
-PollResultType Socket::poll(bool readyToRead,
- int timeoutMs,
- int sockfd,
- const SelectInterruptPtr &selectInterrupt)
-{
- //
- // We used to use ::select to poll but on Android 9 we get large fds out of
- // ::connect which crash in FD_SET as they are larger than FD_SETSIZE.
- // Switching to ::poll does fix that.
- //
- // However poll isn't as portable as select and has bugs on Windows, so we
- // have a shim to fallback to select on those platforms. See
- // https://github.com/mpv-player/mpv/pull/5203/files for such a select
- // wrapper.
- //
- nfds_t nfds = 1;
- struct pollfd fds[2];
- memset(fds, 0, sizeof(fds));
-
- fds[0].fd = sockfd;
- fds[0].events = (readyToRead) ? POLLIN : POLLOUT;
-
- // this is ignored by poll, but our select based poll wrapper on Windows
- // needs it
- fds[0].events |= POLLERR;
-
- // File descriptor used to interrupt select when needed
- int interruptFd = -1;
- if (selectInterrupt) {
- interruptFd = selectInterrupt->getFd();
-
- if (interruptFd != -1) {
- nfds = 2;
- fds[1].fd = interruptFd;
- fds[1].events = POLLIN;
- }
- }
-
- int ret = ix::poll(fds, nfds, timeoutMs);
-
- PollResultType pollResult = PollResultType::ReadyForRead;
- if (ret < 0) {
- pollResult = PollResultType::Error;
- } else if (ret == 0) {
- pollResult = PollResultType::Timeout;
- } else if (interruptFd != -1 && fds[1].revents & POLLIN) {
- uint64_t value = selectInterrupt->read();
-
- if (value == SelectInterrupt::kSendRequest) {
- pollResult = PollResultType::SendRequest;
- } else if (value == SelectInterrupt::kCloseRequest) {
- pollResult = PollResultType::CloseRequest;
- }
- } else if (sockfd != -1 && readyToRead && fds[0].revents & POLLIN) {
- pollResult = PollResultType::ReadyForRead;
- } else if (sockfd != -1 && !readyToRead && fds[0].revents & POLLOUT) {
- pollResult = PollResultType::ReadyForWrite;
-
-#ifdef _WIN32
- // On connect error, in async mode, windows will write to the exceptions
- // fds
- if (fds[0].revents & POLLERR) {
- pollResult = PollResultType::Error;
- }
-#else
- int optval = -1;
- socklen_t optlen = sizeof(optval);
-
- // getsockopt() puts the errno value for connect into optval so 0
- // means no-error.
- if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1 ||
- optval != 0) {
- pollResult = PollResultType::Error;
-
- // set errno to optval so that external callers can have an
- // appropriate error description when calling strerror
- errno = optval;
- }
-#endif
- } else if (sockfd != -1 &&
- (fds[0].revents & POLLERR || fds[0].revents & POLLHUP ||
- fds[0].revents & POLLNVAL)) {
- pollResult = PollResultType::Error;
- }
-
- return pollResult;
-}
-
-PollResultType Socket::isReadyToRead(int timeoutMs)
-{
- if (_sockfd == -1) {
- return PollResultType::Error;
- }
-
- bool readyToRead = true;
- return poll(readyToRead, timeoutMs, _sockfd, _selectInterrupt);
-}
-
-PollResultType Socket::isReadyToWrite(int timeoutMs)
-{
- if (_sockfd == -1) {
- return PollResultType::Error;
- }
-
- bool readyToRead = false;
- return poll(readyToRead, timeoutMs, _sockfd, _selectInterrupt);
-}
-
-// Wake up from poll/select by writing to the pipe which is watched by select
-bool Socket::wakeUpFromPoll(uint64_t wakeUpCode)
-{
- return _selectInterrupt->notify(wakeUpCode);
-}
-
-bool Socket::accept(std::string &errMsg)
-{
- if (_sockfd == -1) {
- errMsg = "Socket is uninitialized";
- return false;
- }
- return true;
-}
-
-bool Socket::connect(const std::string &host,
- int port,
- std::string &errMsg,
- const CancellationRequest &isCancellationRequested)
-{
- std::lock_guard lock(_socketMutex);
-
- if (!_selectInterrupt->clear())
- return false;
-
- _sockfd =
- SocketConnect::connect(host, port, errMsg, isCancellationRequested);
- return _sockfd != -1;
-}
-
-void Socket::close()
-{
- std::lock_guard lock(_socketMutex);
-
- if (_sockfd == -1)
- return;
-
- closeSocket(_sockfd);
- _sockfd = -1;
-}
-
-ssize_t Socket::send(char *buffer, size_t length)
-{
- int flags = 0;
-#ifdef MSG_NOSIGNAL
- flags = MSG_NOSIGNAL;
-#endif
-
- return ::send(_sockfd, buffer, length, flags);
-}
-
-ssize_t Socket::send(const std::string &buffer)
-{
- return send((char *)&buffer[0], buffer.size());
-}
-
-ssize_t Socket::recv(void *buffer, size_t length)
-{
- int flags = 0;
-#ifdef MSG_NOSIGNAL
- flags = MSG_NOSIGNAL;
-#endif
-
- return ::recv(_sockfd, (char *)buffer, length, flags);
-}
-
-int Socket::getErrno()
-{
- int err;
-
-#ifdef _WIN32
- err = WSAGetLastError();
-#else
- err = errno;
-#endif
-
- return err;
-}
-
-bool Socket::isWaitNeeded()
-{
- int err = getErrno();
-
- if (err == EWOULDBLOCK || err == EAGAIN || err == EINPROGRESS) {
- return true;
- }
-
- return false;
-}
-
-void Socket::closeSocket(int fd)
-{
-#ifdef _WIN32
- closesocket(fd);
-#else
- ::close(fd);
-#endif
-}
-
-bool Socket::init(std::string &errorMsg)
-{
- return _selectInterrupt->init(errorMsg);
-}
-
-bool Socket::writeBytes(const std::string &str,
- const CancellationRequest &isCancellationRequested)
-{
- int offset = 0;
- int len = (int)str.size();
-
- while (true) {
- if (isCancellationRequested && isCancellationRequested())
- return false;
-
- ssize_t ret = send((char *)&str[offset], len);
-
- // We wrote some bytes, as needed, all good.
- if (ret > 0) {
- if (ret == len) {
- return true;
- } else {
- offset += ret;
- len -= ret;
- continue;
- }
- }
- // There is possibly something to be writen, try again
- else if (ret < 0 && Socket::isWaitNeeded()) {
- continue;
- }
- // There was an error during the write, abort
- else {
- return false;
- }
- }
-}
-
-bool Socket::readByte(void *buffer,
- const CancellationRequest &isCancellationRequested)
-{
- while (true) {
- if (isCancellationRequested && isCancellationRequested())
- return false;
-
- ssize_t ret;
- ret = recv(buffer, 1);
-
- // We read one byte, as needed, all good.
- if (ret == 1) {
- return true;
- }
- // There is possibly something to be read, try again
- else if (ret < 0 && Socket::isWaitNeeded()) {
- // Wait with a 1ms timeout until the socket is ready to read.
- // This way we are not busy looping
- if (isReadyToRead(1) == PollResultType::Error) {
- return false;
- }
- }
- // There was an error during the read, abort
- else {
- return false;
- }
- }
-}
-
-std::pair
- Socket::readLine(const CancellationRequest &isCancellationRequested)
-{
- char c;
- std::string line;
- line.reserve(64);
-
- for (int i = 0; i < 2 || (line[i - 2] != '\r' && line[i - 1] != '\n');
- ++i) {
- if (!readByte(&c, isCancellationRequested)) {
- // Return what we were able to read
- return std::make_pair(false, line);
- }
-
- line += c;
- }
-
- return std::make_pair(true, line);
-}
-
-std::pair
- Socket::readBytes(size_t length,
- const OnProgressCallback &onProgressCallback,
- const CancellationRequest &isCancellationRequested)
-{
- std::array readBuffer;
-
- std::vector