diff --git a/src/legacy/switch-file.cpp b/src/legacy/switch-file.cpp index 9beef18f7..ddd2c64cc 100644 --- a/src/legacy/switch-file.cpp +++ b/src/legacy/switch-file.cpp @@ -177,17 +177,17 @@ static std::string getRemoteData(std::string &url) { std::string readBuffer; - switcher->curl.SetOpt(CURLOPT_URL, url.c_str()); - switcher->curl.SetOpt(CURLOPT_WRITEFUNCTION, WriteCallback); - switcher->curl.SetOpt(CURLOPT_WRITEDATA, &readBuffer); + CurlHelper::SetOpt(CURLOPT_URL, url.c_str()); + CurlHelper::SetOpt(CURLOPT_WRITEFUNCTION, WriteCallback); + CurlHelper::SetOpt(CURLOPT_WRITEDATA, &readBuffer); // Set timeout to at least one second int timeout = switcher->interval / 1000; if (timeout == 0) { timeout = 1; } - switcher->curl.SetOpt(CURLOPT_TIMEOUT, 1); - switcher->curl.Perform(); + CurlHelper::SetOpt(CURLOPT_TIMEOUT, 1); + CurlHelper::Perform(); return readBuffer; } @@ -422,7 +422,7 @@ void AdvSceneSwitcher::SetupFileTab() obs_module_text("AdvSceneSwitcher.fileTab.remoteFileWarning2")); ui->remoteFileWarningLabel->hide(); - if (switcher->curl.Initialized()) { + if (CurlHelper::Initialized()) { ui->libcurlWarning->setVisible(false); } diff --git a/src/macro-core/macro-action-clipboard.cpp b/src/macro-core/macro-action-clipboard.cpp index b58d8ef7e..f5720f96c 100644 --- a/src/macro-core/macro-action-clipboard.cpp +++ b/src/macro-core/macro-action-clipboard.cpp @@ -1,6 +1,5 @@ #include "macro-action-clipboard.hpp" #include "curl-helper.hpp" -#include "switcher-data.hpp" #include #include @@ -34,17 +33,17 @@ static std::optional getImageFromUrl(const char *url) { QByteArray response; - switcher->curl.SetOpt(CURLOPT_URL, url); - switcher->curl.SetOpt(CURLOPT_HTTPGET, 1L); - switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, 30000); - switcher->curl.SetOpt(CURLOPT_WRITEFUNCTION, writeCallback); - switcher->curl.SetOpt(CURLOPT_WRITEDATA, &response); - auto code = switcher->curl.Perform(); + CurlHelper::SetOpt(CURLOPT_URL, url); + CurlHelper::SetOpt(CURLOPT_HTTPGET, 1L); + CurlHelper::SetOpt(CURLOPT_TIMEOUT_MS, 30000); + CurlHelper::SetOpt(CURLOPT_WRITEFUNCTION, writeCallback); + CurlHelper::SetOpt(CURLOPT_WRITEDATA, &response); + auto code = CurlHelper::Perform(); if (code != CURLE_OK) { blog(LOG_WARNING, "Retrieving image failed in %s with error: %s", __func__, - switcher->curl.GetError(code)); + CurlHelper::GetError(code)); return {}; } diff --git a/src/macro-core/macro-action-http.cpp b/src/macro-core/macro-action-http.cpp index 45fc394db..4556ea968 100644 --- a/src/macro-core/macro-action-http.cpp +++ b/src/macro-core/macro-action-http.cpp @@ -1,5 +1,4 @@ #include "macro-action-http.hpp" -#include "switcher-data.hpp" #include "utility.hpp" #include "curl-helper.hpp" @@ -36,44 +35,44 @@ void MacroActionHttp::SetupHeaders() } struct curl_slist *headers = nullptr; for (auto &header : _headers) { - headers = switcher->curl.SlistAppend(headers, header.c_str()); + headers = CurlHelper::SlistAppend(headers, header.c_str()); } if (!_headers.empty()) { - switcher->curl.SetOpt(CURLOPT_HTTPHEADER, headers); + CurlHelper::SetOpt(CURLOPT_HTTPHEADER, headers); } } void MacroActionHttp::Get() { - switcher->curl.SetOpt(CURLOPT_URL, _url.c_str()); - switcher->curl.SetOpt(CURLOPT_HTTPGET, 1L); - switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.Milliseconds()); + CurlHelper::SetOpt(CURLOPT_URL, _url.c_str()); + CurlHelper::SetOpt(CURLOPT_HTTPGET, 1L); + CurlHelper::SetOpt(CURLOPT_TIMEOUT_MS, _timeout.Milliseconds()); SetupHeaders(); std::string response; if (IsReferencedInVars()) { - switcher->curl.SetOpt(CURLOPT_WRITEFUNCTION, WriteCB); + CurlHelper::SetOpt(CURLOPT_WRITEFUNCTION, WriteCB); } else { - switcher->curl.SetOpt(CURLOPT_WRITEFUNCTION, DropCB); + CurlHelper::SetOpt(CURLOPT_WRITEFUNCTION, DropCB); } - switcher->curl.SetOpt(CURLOPT_WRITEDATA, &response); - switcher->curl.Perform(); + CurlHelper::SetOpt(CURLOPT_WRITEDATA, &response); + CurlHelper::Perform(); SetVariableValue(response); } void MacroActionHttp::Post() { - switcher->curl.SetOpt(CURLOPT_URL, _url.c_str()); - switcher->curl.SetOpt(CURLOPT_POSTFIELDS, _data.c_str()); - switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.Milliseconds()); + CurlHelper::SetOpt(CURLOPT_URL, _url.c_str()); + CurlHelper::SetOpt(CURLOPT_POSTFIELDS, _data.c_str()); + CurlHelper::SetOpt(CURLOPT_TIMEOUT_MS, _timeout.Milliseconds()); SetupHeaders(); - switcher->curl.Perform(); + CurlHelper::Perform(); } bool MacroActionHttp::PerformAction() { - if (!switcher->curl.Initialized()) { + if (!CurlHelper::Initialized()) { blog(LOG_WARNING, "cannot perform http action (curl not found)"); return true; diff --git a/src/macro-core/macro-condition-file.cpp b/src/macro-core/macro-condition-file.cpp index 13bf44bdb..80af066ae 100644 --- a/src/macro-core/macro-condition-file.cpp +++ b/src/macro-core/macro-condition-file.cpp @@ -1,7 +1,7 @@ #include "macro-condition-file.hpp" #include "utility.hpp" -#include "switcher-data.hpp" #include "curl-helper.hpp" +#include "plugin-state-helpers.hpp" #include #include @@ -28,16 +28,16 @@ static size_t WriteCallback(void *contents, size_t size, size_t nmemb, static std::string getRemoteData(std::string &url) { std::string readBuffer; - switcher->curl.SetOpt(CURLOPT_URL, url.c_str()); - switcher->curl.SetOpt(CURLOPT_WRITEFUNCTION, WriteCallback); - switcher->curl.SetOpt(CURLOPT_WRITEDATA, &readBuffer); + CurlHelper::SetOpt(CURLOPT_URL, url.c_str()); + CurlHelper::SetOpt(CURLOPT_WRITEFUNCTION, WriteCallback); + CurlHelper::SetOpt(CURLOPT_WRITEDATA, &readBuffer); // Set timeout to at least one second - int timeout = switcher->interval / 1000; + int timeout = GetIntervalValue() / 1000; if (timeout == 0) { timeout = 1; } - switcher->curl.SetOpt(CURLOPT_TIMEOUT, 1); - switcher->curl.Perform(); + CurlHelper::SetOpt(CURLOPT_TIMEOUT, 1); + CurlHelper::Perform(); return readBuffer; } diff --git a/src/switcher-data.hpp b/src/switcher-data.hpp index 81650485b..76138a7fe 100644 --- a/src/switcher-data.hpp +++ b/src/switcher-data.hpp @@ -18,7 +18,6 @@ #include "macro-properties.hpp" #include "duration-control.hpp" -#include "curl-helper.hpp" #include "priority-helper.hpp" #include "log-helper.hpp" #include "plugin-state-helpers.hpp" @@ -29,7 +28,6 @@ #include #include #include -#include #include namespace advss { @@ -160,7 +158,6 @@ class SwitcherData { AudioFadeInfo masterAudioFade; std::unordered_map activeAudioFades; - Curlhelper curl; std::deque> variables; std::string lastTitle; diff --git a/src/utils/curl-helper.cpp b/src/utils/curl-helper.cpp index 11122002e..726620f08 100644 --- a/src/utils/curl-helper.cpp +++ b/src/utils/curl-helper.cpp @@ -15,7 +15,7 @@ constexpr auto curl_library_name = "libcurl.4.dylib"; constexpr auto curl_library_name = "libcurl.so.4"; #endif -Curlhelper::Curlhelper() +CurlHelper::CurlHelper() { if (LoadLib()) { _curl = _init(); @@ -23,7 +23,7 @@ Curlhelper::Curlhelper() } } -Curlhelper::~Curlhelper() +CurlHelper::~CurlHelper() { if (_lib) { if (_cleanup) { @@ -34,32 +34,46 @@ Curlhelper::~Curlhelper() } } -curl_slist *Curlhelper::SlistAppend(curl_slist *list, const char *string) +CurlHelper &CurlHelper::getInstance() { - if (!_initialized) { + static CurlHelper curl; + return curl; +} + +bool CurlHelper::Initialized() +{ + return getInstance()._initialized; +} + +curl_slist *CurlHelper::SlistAppend(curl_slist *list, const char *string) +{ + auto &curl = getInstance(); + if (!curl._initialized) { return nullptr; } - return _slistAppend(list, string); + return curl._slistAppend(list, string); } -CURLcode Curlhelper::Perform() +CURLcode CurlHelper::Perform() { - if (!_initialized) { + auto &curl = getInstance(); + if (!curl._initialized) { return CURLE_FAILED_INIT; } - return _perform(_curl); + return curl._perform(curl._curl); } -char *Curlhelper::GetError(CURLcode code) +char *CurlHelper::GetError(CURLcode code) { - if (!_initialized) { + auto &curl = getInstance(); + if (!curl._initialized) { return (char *)"CURL initialization failed"; } - return _error(code); + return curl._error(code); } -bool Curlhelper::LoadLib() +bool CurlHelper::LoadLib() { _lib = new QLibrary(curl_library_name, nullptr); if (Resolve()) { @@ -103,7 +117,7 @@ bool Curlhelper::LoadLib() return false; } -bool Curlhelper::Resolve() +bool CurlHelper::Resolve() { _init = (initFunction)_lib->resolve("curl_easy_init"); _setopt = (setOptFunction)_lib->resolve("curl_easy_setopt"); diff --git a/src/utils/curl-helper.hpp b/src/utils/curl-helper.hpp index 560ab21ae..4142dbdd2 100644 --- a/src/utils/curl-helper.hpp +++ b/src/utils/curl-helper.hpp @@ -1,31 +1,45 @@ #pragma once #include #include +#include namespace advss { -typedef CURL *(*initFunction)(void); -typedef CURLcode (*setOptFunction)(CURL *, CURLoption, ...); -typedef struct curl_slist *(*slistAppendFunction)(struct curl_slist *list, - const char *string); -typedef CURLcode (*performFunction)(CURL *); -typedef void (*cleanupFunction)(CURL *); -typedef char *(*errorFunction)(CURLcode); - -class Curlhelper { +class CurlHelper { public: - Curlhelper(); - ~Curlhelper(); + static bool Initialized(); + template static CURLcode SetOpt(CURLoption, Args...); + static struct curl_slist *SlistAppend(struct curl_slist *list, + const char *string); + static CURLcode Perform(); + static char *GetError(CURLcode code); - bool Initialized() { return _initialized; } +private: + CurlHelper(); + CurlHelper(const CurlHelper &) = delete; + CurlHelper &operator=(const CurlHelper &) = delete; + ~CurlHelper(); - template CURLcode SetOpt(CURLoption, Args...); - struct curl_slist *SlistAppend(struct curl_slist *list, - const char *string); - CURLcode Perform(); - char *GetError(CURLcode code); + /* + using initFunction = std::function; + using setOptFunction = std::function; + using slistAppendFunction = std::function; + using performFunction = std::function; + using cleanupFunction = std::function; + using errorFunction = std::function; + */ + + typedef CURL *(*initFunction)(void); + typedef CURLcode (*setOptFunction)(CURL *, CURLoption, ...); + typedef struct curl_slist *(*slistAppendFunction)( + struct curl_slist *list, const char *string); + typedef CURLcode (*performFunction)(CURL *); + typedef void (*cleanupFunction)(CURL *); + typedef char *(*errorFunction)(CURLcode); + + static CurlHelper &getInstance(); -private: bool LoadLib(); bool Resolve(); @@ -37,16 +51,17 @@ class Curlhelper { errorFunction _error = nullptr; CURL *_curl = nullptr; QLibrary *_lib; - bool _initialized = false; + std::atomic_bool _initialized = {false}; }; template -inline CURLcode Curlhelper::SetOpt(CURLoption option, Args... args) +static inline CURLcode CurlHelper::SetOpt(CURLoption option, Args... args) { - if (!_initialized) { + auto &curl = getInstance(); + if (!curl._initialized) { return CURLE_FAILED_INIT; } - return _setopt(_curl, option, args...); + return curl._setopt(curl._curl, option, args...); } } // namespace advss