Auto reformatted the base, ref #470

This commit is contained in:
emeric
2024-05-24 23:31:52 +02:00
parent 83b868673c
commit 39941d90a3
460 changed files with 8583 additions and 8514 deletions
+3 -4
View File
@@ -17,9 +17,9 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include <benchmark/benchmark.h>
#include <iostream>
#include <thread>
#include <benchmark/benchmark.h>
#include "core/ILogger.hpp"
@@ -59,8 +59,7 @@ namespace lms::core
static void BM_TraceLogger_Detailed_withArg(benchmark::State& state)
{
auto someExpensiveArgComputation{ []() -> std::string
{
auto someExpensiveArgComputation{ []() -> std::string {
std::this_thread::sleep_for(std::chrono::microseconds{ 1 });
return "foo";
} };
@@ -77,6 +76,6 @@ namespace lms::core
BENCHMARK(BM_TraceLogger_Detailed)->Threads(1)->Threads(std::thread::hardware_concurrency());
BENCHMARK(BM_TraceLogger_Detailed_withArg)->Threads(1)->Threads(std::thread::hardware_concurrency());
}
} // namespace lms::core
BENCHMARK_MAIN();
+15 -15
View File
@@ -23,6 +23,7 @@
#include <cassert>
#include <cstring> // strerror
#include <fstream>
#include <archive.h>
#include <archive_entry.h>
@@ -39,12 +40,14 @@ namespace lms::zip
{
public:
FileException(const std::filesystem::path& p, std::string_view message)
: Exception{ "File '" + p.string() + "': " + std::string {message} }
{}
: Exception{ "File '" + p.string() + "': " + std::string{ message } }
{
}
FileException(const std::filesystem::path& p, std::string_view message, int err)
: Exception{ "File '" + p.string() + "': " + std::string {message} + ": " + ::strerror(err) }
{}
: Exception{ "File '" + p.string() + "': " + std::string{ message } + ": " + ::strerror(err) }
{
}
};
class ArchiveException : public Exception
@@ -52,7 +55,8 @@ namespace lms::zip
public:
ArchiveException(struct ::archive* arch)
: Exception{ getError(arch) }
{}
{
}
static std::string_view getError(struct ::archive* arch)
{
@@ -88,19 +92,16 @@ namespace lms::zip
if (!_archive)
throw Exception{ "Cannot create archive control struct" };
auto archiveOpen{ [](struct ::archive*, void*)
{
auto archiveOpen{ [](struct ::archive*, void*) {
return ARCHIVE_OK;
} };
auto archiveWrite{ [](struct ::archive*, void* clientData, const void* buff, ::size_t n) -> la_ssize_t
{
ArchiveZipper* zipper {static_cast<ArchiveZipper*>(clientData)};
auto archiveWrite{ [](struct ::archive*, void* clientData, const void* buff, ::size_t n) -> la_ssize_t {
ArchiveZipper* zipper{ static_cast<ArchiveZipper*>(clientData) };
return zipper->onWriteCallback(static_cast<const std::byte*>(buff), n);
} };
auto archiveClose{ [](struct ::archive*, void*)
{
auto archiveClose{ [](struct ::archive*, void*) {
return ARCHIVE_OK;
} };
@@ -183,8 +184,7 @@ namespace lms::zip
using std::filesystem::perms;
::mode_t mode{};
auto testPerm{ [](perms p, perms permToTest)
{
auto testPerm{ [](perms p, perms permToTest) {
return (p & permToTest) == permToTest;
} };
@@ -295,4 +295,4 @@ namespace lms::zip
return bufferSize;
}
}
} // namespace lms::zip
+2 -1
View File
@@ -21,6 +21,7 @@
#include <cstddef>
#include <memory>
#include "core/IZipper.hpp"
extern "C"
@@ -77,4 +78,4 @@ namespace lms::zip
std::uint64_t _bytesWrittenInCurrentOutputStream{};
};
}
} // namespace lms::zip
+10 -9
View File
@@ -19,21 +19,21 @@
#include "ChildProcess.hpp"
#include <cstring>
#include <cerrno>
#include <cstring>
#include <fcntl.h>
#include <signal.h>
#include <stdexcept>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <algorithm>
#include <iostream>
#include <mutex>
#include <boost/asio/read.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/read.hpp>
#include "core/Exception.hpp"
#include "core/ILogger.hpp"
@@ -47,13 +47,15 @@ namespace lms::core
public:
SystemException(int err, const std::string& errMsg)
: ChildProcessException{ errMsg + ": " + ::strerror(err) }
{}
{
}
SystemException(boost::system::error_code ec, const std::string& errMsg)
: ChildProcessException{ errMsg + ": " + ec.message() }
{}
{
}
};
}
} // namespace
ChildProcess::ChildProcess(boost::asio::io_context& ioContext, const std::filesystem::path& path, const Args& args)
: _ioContext{ ioContext }
@@ -170,8 +172,7 @@ namespace lms::core
LMS_LOG(CHILDPROCESS, DEBUG, "Async read, bufferSize = " << bufferSize);
boost::asio::async_read(_childStdout, boost::asio::buffer(data, bufferSize),
[this, callback{ std::move(callback) }](const boost::system::error_code& error, std::size_t bytesTransferred)
{
[this, callback{ std::move(callback) }](const boost::system::error_code& error, std::size_t bytesTransferred) {
LMS_LOG(CHILDPROCESS, DEBUG, "Async read cb - ec = '" << error.message() << "' (" << error.value() << "), bytesTransferred = " << bytesTransferred);
ReadResult readResult{ ReadResult::Success };
@@ -206,4 +207,4 @@ namespace lms::core
{
return _finished;
}
}
} // namespace lms::core
+11 -11
View File
@@ -40,20 +40,20 @@ namespace lms::core
ChildProcess(boost::asio::io_context& ioContext, const std::filesystem::path& path, const Args& args);
private:
void asyncRead(std::byte* data, std::size_t bufferSize, ReadCallback callback) override;
std::size_t readSome(std::byte* data, std::size_t bufferSize) override;
bool finished() const override;
void asyncRead(std::byte* data, std::size_t bufferSize, ReadCallback callback) override;
std::size_t readSome(std::byte* data, std::size_t bufferSize) override;
bool finished() const override;
void kill();
bool wait(bool block); // return true if waited
void kill();
bool wait(bool block); // return true if waited
using FileDescriptor = boost::asio::posix::stream_descriptor;
boost::asio::io_context& _ioContext;
FileDescriptor _childStdout;
::pid_t _childPID{};
bool _waited{};
bool _finished{};
std::optional<int> _exitCode;
FileDescriptor _childStdout;
::pid_t _childPID{};
bool _waited{};
bool _finished{};
std::optional<int> _exitCode;
};
}
} // namespace lms::core
+1 -1
View File
@@ -39,4 +39,4 @@ namespace lms::core
{
return std::make_unique<ChildProcess>(_ioContext, path, args);
}
}
} // namespace lms::core
+1 -1
View File
@@ -44,4 +44,4 @@ namespace lms::core
boost::asio::io_context& _ioContext;
};
}
} // namespace lms::core
+3 -3
View File
@@ -65,7 +65,7 @@ namespace lms::core
{
try
{
const libconfig::Setting& values{ _config.lookup(std::string {setting}) };
const libconfig::Setting& values{ _config.lookup(std::string{ setting }) };
for (int i{}; i < values.getLength(); ++i)
_func(static_cast<const char*>(values[i]));
}
@@ -83,7 +83,7 @@ namespace lms::core
{
try
{
const char* res{ _config.lookup(std::string {setting}) };
const char* res{ _config.lookup(std::string{ setting }) };
return std::filesystem::path{ std::string(res) };
}
catch (libconfig::ConfigException&)
@@ -127,4 +127,4 @@ namespace lms::core
return def;
}
}
}
} // namespace lms::core
+7 -8
View File
@@ -37,15 +37,14 @@ namespace lms::core
Config& operator=(Config&&) = delete;
// Default values are returned in case of setting not found
std::string_view getString(std::string_view setting, std::string_view def = "") override;
void visitStrings(std::string_view setting, std::function<void(std::string_view)> _func, std::initializer_list<std::string_view> defs) override;
std::filesystem::path getPath(std::string_view setting, const std::filesystem::path& def = std::filesystem::path()) override;
unsigned long getULong(std::string_view setting, unsigned long def = 0) override;
long getLong(std::string_view setting, long def = 0) override;
bool getBool(std::string_view setting, bool def = false) override;
std::string_view getString(std::string_view setting, std::string_view def = "") override;
void visitStrings(std::string_view setting, std::function<void(std::string_view)> _func, std::initializer_list<std::string_view> defs) override;
std::filesystem::path getPath(std::string_view setting, const std::filesystem::path& def = std::filesystem::path()) override;
unsigned long getULong(std::string_view setting, unsigned long def = 0) override;
long getLong(std::string_view setting, long def = 0) override;
bool getBool(std::string_view setting, bool def = false) override;
private:
libconfig::Config _config;
};
}
} // namespace lms::core
+2 -2
View File
@@ -80,7 +80,7 @@ namespace lms
std::ostringstream contentRange;
contentRange << "bytes " << startByte << "-"
<< _beyondLastByte - 1 << "/" << fileSize;
<< _beyondLastByte - 1 << "/" << fileSize;
response.addHeader("Content-Range", contentRange.str());
response.setContentLength(_beyondLastByte - startByte);
@@ -134,4 +134,4 @@ namespace lms
LMS_LOG(UTILS, DEBUG, "Job complete!");
return nullptr;
}
}
} // namespace lms
+7 -6
View File
@@ -22,6 +22,7 @@
#include <filesystem>
#include <string>
#include <string_view>
#include "core/IResourceHandler.hpp"
namespace lms
@@ -33,13 +34,13 @@ namespace lms
private:
Wt::Http::ResponseContinuation* processRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;
void abort() override {};
void abort() override{};
static constexpr std::size_t _chunkSize{ 262'144 };
std::filesystem::path _path;
std::string _mimeType;
::uint64_t _beyondLastByte{};
::uint64_t _offset{};
std::filesystem::path _path;
std::string _mimeType;
::uint64_t _beyondLastByte{};
::uint64_t _offset{};
};
}
} // namespace lms
+16 -17
View File
@@ -41,24 +41,23 @@ namespace lms::core
threadName += std::to_string(i);
}
_threads.emplace_back([this, threadName]
_threads.emplace_back([this, threadName] {
if (!threadName.empty())
{
if (!threadName.empty())
{
if (auto * traceLogger{ Service<tracing::ITraceLogger>::get() })
traceLogger->setThreadName(std::this_thread::get_id(), threadName);
}
if (auto* traceLogger{ Service<tracing::ITraceLogger>::get() })
traceLogger->setThreadName(std::this_thread::get_id(), threadName);
}
try
{
_ioService.run();
}
catch (const std::exception& e)
{
LMS_LOG(UTILS, FATAL, "Exception caught in IO context: " << e.what());
std::abort();
}
});
try
{
_ioService.run();
}
catch (const std::exception& e)
{
LMS_LOG(UTILS, FATAL, "Exception caught in IO context: " << e.what());
std::abort();
}
});
}
}
@@ -82,4 +81,4 @@ namespace lms::core
for (std::thread& t : _threads)
t.join();
}
}
} // namespace lms::core
+51 -26
View File
@@ -25,25 +25,44 @@ namespace lms::core::logging
{
switch (mod)
{
case Module::API_SUBSONIC: return "API_SUBSONIC";
case Module::AUTH: return "AUTH";
case Module::AV: return "AV";
case Module::CHILDPROCESS: return "CHILDPROC";
case Module::COVER: return "COVER";
case Module::DB: return "DB";
case Module::DBUPDATER: return "DB UPDATER";
case Module::FEATURE: return "FEATURE";
case Module::FEEDBACK: return "FEEDBACK";
case Module::HTTP: return "HTTP";
case Module::MAIN: return "MAIN";
case Module::METADATA: return "METADATA";
case Module::REMOTE: return "REMOTE";
case Module::SCROBBLING: return "SCROBBLING";
case Module::SERVICE: return "SERVICE";
case Module::RECOMMENDATION: return "RECOMMENDATION";
case Module::TRANSCODING: return "TRANSCODING";
case Module::UI: return "UI";
case Module::UTILS: return "UTILS";
case Module::API_SUBSONIC:
return "API_SUBSONIC";
case Module::AUTH:
return "AUTH";
case Module::AV:
return "AV";
case Module::CHILDPROCESS:
return "CHILDPROC";
case Module::COVER:
return "COVER";
case Module::DB:
return "DB";
case Module::DBUPDATER:
return "DB UPDATER";
case Module::FEATURE:
return "FEATURE";
case Module::FEEDBACK:
return "FEEDBACK";
case Module::HTTP:
return "HTTP";
case Module::MAIN:
return "MAIN";
case Module::METADATA:
return "METADATA";
case Module::REMOTE:
return "REMOTE";
case Module::SCROBBLING:
return "SCROBBLING";
case Module::SERVICE:
return "SERVICE";
case Module::RECOMMENDATION:
return "RECOMMENDATION";
case Module::TRANSCODING:
return "TRANSCODING";
case Module::UI:
return "UI";
case Module::UTILS:
return "UTILS";
}
return "";
}
@@ -52,11 +71,16 @@ namespace lms::core::logging
{
switch (sev)
{
case Severity::FATAL: return "fatal";
case Severity::ERROR: return "error";
case Severity::WARNING: return "warning";
case Severity::INFO: return "info";
case Severity::DEBUG: return "debug";
case Severity::FATAL:
return "fatal";
case Severity::ERROR:
return "error";
case Severity::WARNING:
return "warning";
case Severity::INFO:
return "info";
case Severity::DEBUG:
return "debug";
}
return "";
}
@@ -66,7 +90,8 @@ namespace lms::core::logging
, _module{ module }
, _severity{ severity }
{}
{
}
Log::~Log()
{
@@ -78,4 +103,4 @@ namespace lms::core::logging
{
return _oss.str();
}
}
} // namespace lms::core::logging
+15 -15
View File
@@ -23,24 +23,24 @@
namespace std
{
std::size_t hash<boost::asio::ip::address>::operator()(const boost::asio::ip::address& ipAddr) const
{
if (ipAddr.is_v4())
return ipAddr.to_v4().to_ulong();
std::size_t hash<boost::asio::ip::address>::operator()(const boost::asio::ip::address& ipAddr) const
{
if (ipAddr.is_v4())
return ipAddr.to_v4().to_ulong();
if (ipAddr.is_v6())
{
const auto& range {ipAddr.to_v6().to_bytes()};
std::size_t res {};
if (ipAddr.is_v6())
{
const auto& range{ ipAddr.to_v6().to_bytes() };
std::size_t res{};
for (auto b : range)
res ^= std::hash<char>{}(static_cast<char>(b));
for (auto b : range)
res ^= std::hash<char>{}(static_cast<char>(b));
return res;
}
return res;
}
return std::hash<std::string>{}(ipAddr.to_string());
}
}
return std::hash<std::string>{}(ipAddr.to_string());
}
} // namespace std
#endif // BOOST_ASIO_HAS_STD_HASH
+8 -7
View File
@@ -19,12 +19,11 @@
#include "core/Path.hpp"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <array>
#include <fstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <boost/tokenizer.hpp>
@@ -44,7 +43,7 @@ namespace lms::core::pathUtils
{
do
{
std::array<char, 1024> buffer;
std::array<char, 1024> buffer;
ifs.read(buffer.data(), buffer.size());
crc32.processBytes(reinterpret_cast<const std::byte*>(buffer.data()), ifs.gcount());
@@ -69,7 +68,9 @@ namespace lms::core::pathUtils
Wt::WDateTime getLastWriteTime(const std::filesystem::path& file)
{
struct stat sb {};
struct stat sb
{
};
if (stat(file.string().c_str(), &sb) == -1)
throw LmsException("Failed to get stats on file '" + file.string() + "'");
@@ -183,4 +184,4 @@ namespace lms::core::pathUtils
return longestCommonPath;
}
}
} // namespace lms::core::pathUtils
+1 -1
View File
@@ -35,4 +35,4 @@ namespace lms::core::random
return RandGenerator{ seed };
}
}
} // namespace lms::core::random
+1 -1
View File
@@ -131,4 +131,4 @@ namespace lms::core
return _sharedCounts[thisThreadId] > 0;
}
#endif
}
} // namespace lms::core
+1 -1
View File
@@ -35,4 +35,4 @@ namespace lms::core::logging
assert(isSeverityActive(log.getSeverity()));
_os << std::this_thread::get_id() << " [" << getSeverityName(log.getSeverity()) << "] [" << getModuleName(log.getModule()) << "] " << log.getMessage() << std::endl;
}
}
} // namespace lms::core::logging
+16 -17
View File
@@ -23,15 +23,14 @@
#include <iomanip>
#include <utility>
#include <Wt/WDateTime.h>
#include <Wt/WDate.h>
#include <Wt/WDateTime.h>
namespace lms::core::stringUtils
{
namespace details
{
constexpr std::pair<char, std::string_view> jsEscapeChars[]
{
constexpr std::pair<char, std::string_view> jsEscapeChars[]{
{ '\\', "\\\\" },
{ '\n', "\\n" },
{ '\r', "\\r" },
@@ -40,8 +39,7 @@ namespace lms::core::stringUtils
{ '\'', "\\\'" },
};
constexpr std::pair<char, std::string_view> jsonEscapeChars[]
{
constexpr std::pair<char, std::string_view> jsonEscapeChars[]{
{ '\\', "\\\\" },
{ '\n', "\\n" },
{ '\r', "\\r" },
@@ -49,8 +47,8 @@ namespace lms::core::stringUtils
{ '"', "\\\"" },
};
template <std::size_t N>
std::string escape(std::string_view str, const std::pair<char, std::string_view>(&charsToEscape)[N])
template<std::size_t N>
std::string escape(std::string_view str, const std::pair<char, std::string_view> (&charsToEscape)[N])
{
std::string escaped;
escaped.reserve(str.length());
@@ -70,12 +68,12 @@ namespace lms::core::stringUtils
return escaped;
}
template <std::size_t N>
void writeEscapedString(std::ostream& os, std::string_view str, const std::pair<char, std::string_view>(&charsToEscape)[N])
template<std::size_t N>
void writeEscapedString(std::ostream& os, std::string_view str, const std::pair<char, std::string_view> (&charsToEscape)[N])
{
for (const char c : str)
{
auto itEntry{ std::find_if(std::cbegin(charsToEscape), std::cend(charsToEscape), [=](const auto& entry) { return entry.first == c;}) };
auto itEntry{ std::find_if(std::cbegin(charsToEscape), std::cend(charsToEscape), [=](const auto& entry) { return entry.first == c; }) };
if (itEntry != std::cend(charsToEscape))
os << itEntry->second;
else
@@ -83,7 +81,7 @@ namespace lms::core::stringUtils
}
}
template <typename StringType>
template<typename StringType>
std::string joinStrings(std::span<const StringType> strings, std::string_view delimiter)
{
std::string res;
@@ -99,7 +97,7 @@ namespace lms::core::stringUtils
return res;
}
}
} // namespace details
template<>
std::optional<std::string> readAs(std::string_view str)
@@ -198,7 +196,8 @@ namespace lms::core::stringUtils
for (char c : str)
{
if (escaped) {
if (escaped)
{
current.push_back(c);
escaped = false;
}
@@ -248,14 +247,14 @@ namespace lms::core::stringUtils
std::string res;
res.reserve(str.size());
std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](unsigned char c) { return std::tolower(c);});
std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](unsigned char c) { return std::tolower(c); });
return res;
}
void stringToLower(std::string& str)
{
std::transform(std::cbegin(str), std::cend(str), std::begin(str), [](unsigned char c) { return std::tolower(c);});
std::transform(std::cbegin(str), std::cend(str), std::begin(str), [](unsigned char c) { return std::tolower(c); });
}
std::string stringToUpper(const std::string& str)
@@ -263,7 +262,7 @@ namespace lms::core::stringUtils
std::string res;
res.reserve(str.size());
std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](char c) { return std::toupper(c);});
std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](char c) { return std::toupper(c); });
return res;
}
@@ -436,4 +435,4 @@ namespace lms::core::stringUtils
// assume UTC
return date.toString("yyyy-MM-dd").toUTF8();
}
}
} // namespace lms::core::stringUtils
+10 -7
View File
@@ -22,6 +22,7 @@
#include <iomanip>
#include <memory>
#include <string>
#include "core/Exception.hpp"
#include "core/ILogger.hpp"
@@ -32,7 +33,8 @@ namespace lms::core::tracing
class CurrentThreadUnregisterer
{
public:
CurrentThreadUnregisterer(TraceLogger* logger) : _logger{ logger } {}
CurrentThreadUnregisterer(TraceLogger* logger)
: _logger{ logger } {}
~CurrentThreadUnregisterer()
{
if (_logger)
@@ -45,7 +47,7 @@ namespace lms::core::tracing
TraceLogger* _logger;
};
}
} // namespace
thread_local TraceLogger::Buffer* TraceLogger::_currentBuffer{};
@@ -71,11 +73,11 @@ namespace lms::core::tracing
LMS_LOG(UTILS, INFO, "TraceLogger: using " << _buffers.size() << " buffers. Buffer size = " << std::to_string(BufferSize) << ", entry size = " << sizeof(CompleteEventEntry) << ", entry count per buffer = " << Buffer::CompleteEventCount);
setMetadata("cpu_count", std::to_string(std::thread::hardware_concurrency()));
setMetadata("build_type",
setMetadata("build_type",
#ifndef NDEBUG
"debug"
"debug"
#else
"release"
"release"
#endif
);
}
@@ -182,7 +184,8 @@ namespace lms::core::tracing
if (first)
first = false;
else
os << ", " << std::endl;;
os << ", " << std::endl;
;
os << "\t\t{ ";
os << "\"name\" : \"" << event.name << "\", ";
@@ -297,4 +300,4 @@ namespace lms::core::tracing
return static_cast<std::uint32_t>(id);
}
}
} // namespace lms::core::tracing
+1 -1
View File
@@ -103,4 +103,4 @@ namespace lms::core::tracing
static thread_local Buffer* _currentBuffer;
};
}
} // namespace lms::core::tracing
+7 -8
View File
@@ -31,13 +31,13 @@ namespace lms::core
{
namespace stringUtils
{
template <>
template<>
std::optional<UUID>
readAs(std::string_view str)
readAs(std::string_view str)
{
return UUID::fromString(str);
}
}
} // namespace stringUtils
namespace
{
bool stringIsUUID(std::string_view str)
@@ -46,7 +46,7 @@ namespace lms::core
return std::regex_match(std::cbegin(str), std::cend(str), re);
}
}
} // namespace
UUID::UUID(std::string_view str)
: _value{ stringUtils::stringToLower(str) }
@@ -68,9 +68,8 @@ namespace lms::core
std::ostringstream oss;
auto concatRandomBytes{ [](std::ostream& os, std::size_t byteCount)
{
for (std::size_t i {}; i < byteCount; ++i)
auto concatRandomBytes{ [](std::ostream& os, std::size_t byteCount) {
for (std::size_t i{}; i < byteCount; ++i)
os << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(random::getRandom<std::uint8_t>(0, 255));
} };
@@ -88,4 +87,4 @@ namespace lms::core
assert(uuid);
return uuid.value();
}
}
} // namespace lms::core
+15 -9
View File
@@ -19,10 +19,11 @@
#include "core/WtLogger.hpp"
#include <thread>
#include <sstream>
#include <Wt/WServer.h>
#include <thread>
#include <Wt/WLogger.h>
#include <Wt/WServer.h>
#include "core/Exception.hpp"
@@ -36,7 +37,7 @@ namespace lms::core::logging
oss << id;
return oss.str();
}
}
} // namespace
WtLogger::WtLogger(Severity minSeverity)
: _minSeverity{ minSeverity }
@@ -47,11 +48,16 @@ namespace lms::core::logging
{
switch (minSeverity)
{
case Severity::DEBUG: return "*";
case Severity::INFO: return "* -debug";
case Severity::WARNING: return "* -debug -info";
case Severity::ERROR: return "* -debug -info -warning";
case Severity::FATAL: return "* -debug -info -warning -error";
case Severity::DEBUG:
return "*";
case Severity::INFO:
return "* -debug";
case Severity::WARNING:
return "* -debug -info";
case Severity::ERROR:
return "* -debug -info -warning";
case Severity::FATAL:
return "* -debug -info -warning -error";
}
throw LmsException{ "Unhandled severity" };
@@ -66,4 +72,4 @@ namespace lms::core::logging
{
Wt::log(getSeverityName(log.getSeverity())) << Wt::WLogger::sep << to_string(std::this_thread::get_id()) << Wt::WLogger::sep << "[" << getModuleName(log.getModule()) << "]" << Wt::WLogger::sep << log.getMessage();
}
}
} // namespace lms::core::logging
+1 -1
View File
@@ -36,4 +36,4 @@ namespace lms::core::http
{
_sendQueue.sendRequest(std::make_unique<ClientRequest>(std::move(POSTParams)));
}
}
} // namespace lms::core::http
+6 -4
View File
@@ -19,11 +19,12 @@
#pragma once
#include <unordered_map>
#include <string>
#include <shared_mutex>
#include <string>
#include <unordered_map>
#include "core/http/IClient.hpp"
#include "SendQueue.hpp"
namespace lms::core::http
@@ -33,7 +34,8 @@ namespace lms::core::http
public:
Client(boost::asio::io_context& ioContext, std::string_view baseUrl)
: _sendQueue{ ioContext, baseUrl }
{}
{
}
private:
void sendGETRequest(ClientGETRequestParameters&& request) override;
@@ -41,4 +43,4 @@ namespace lms::core::http
SendQueue _sendQueue;
};
}
} // namespace lms::core::http
+10 -7
View File
@@ -21,6 +21,7 @@
#include <memory>
#include <variant>
#include "core/http/ClientRequestParameters.hpp"
namespace lms::core::http
@@ -28,8 +29,10 @@ namespace lms::core::http
class ClientRequest
{
public:
ClientRequest(ClientGETRequestParameters&& GETParams) : _parameters{ std::move(GETParams) } {}
ClientRequest(ClientPOSTRequestParameters&& POSTParams) : _parameters{ std::move(POSTParams) } {}
ClientRequest(ClientGETRequestParameters&& GETParams)
: _parameters{ std::move(GETParams) } {}
ClientRequest(ClientPOSTRequestParameters&& POSTParams)
: _parameters{ std::move(POSTParams) } {}
std::size_t retryCount{};
@@ -37,10 +40,10 @@ namespace lms::core::http
{
const ClientRequestParameters* res;
std::visit([&](const auto& parameters)
{
res = &static_cast<const ClientRequestParameters&>(parameters);
}, _parameters);
std::visit([&](const auto& parameters) {
res = &static_cast<const ClientRequestParameters&>(parameters);
},
_parameters);
return *res;
}
@@ -71,4 +74,4 @@ namespace lms::core::http
private:
std::variant<ClientGETRequestParameters, ClientPOSTRequestParameters> _parameters;
};
}
} // namespace lms::core::http
+28 -32
View File
@@ -19,15 +19,15 @@
#include "SendQueue.hpp"
#include <boost/asio/dispatch.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/dispatch.hpp>
#include "core/Exception.hpp"
#include "core/ILogger.hpp"
#include "core/ITraceLogger.hpp"
#include "core/String.hpp"
#define LOG(sev, message) LMS_LOG(SCROBBLING, sev, "[Http SendQueue] - " << message)
#define LOG(sev, message) LMS_LOG(SCROBBLING, sev, "[Http SendQueue] - " << message)
namespace lms::core::stringUtils
{
@@ -41,35 +41,33 @@ namespace lms::core::stringUtils
return res;
}
}
} // namespace lms::core::stringUtils
namespace lms::core::http
{
namespace
{
template <typename T>
template<typename T>
std::optional<T> headerReadAs(const Wt::Http::Message& msg, std::string_view headerName)
{
std::optional<T> res;
if (const std::string * headerValue{ msg.getHeader(std::string {headerName}) })
if (const std::string * headerValue{ msg.getHeader(std::string{ headerName }) })
res = stringUtils::readAs<T>(*headerValue);
return res;
}
}
} // namespace
SendQueue::SendQueue(boost::asio::io_context& ioContext, std::string_view baseUrl)
: _ioContext{ ioContext }
, _baseUrl{ baseUrl }
{
_client.done().connect([this](Wt::AsioWrapper::error_code ec, const Wt::Http::Message& msg)
{
_strand.dispatch([this, ec, msg = std::move(msg)]
{
onClientDone(ec, msg);
});
_client.done().connect([this](Wt::AsioWrapper::error_code ec, const Wt::Http::Message& msg) {
_strand.dispatch([this, ec, msg = std::move(msg)] {
onClientDone(ec, msg);
});
});
}
SendQueue::~SendQueue()
@@ -79,13 +77,12 @@ namespace lms::core::http
void SendQueue::sendRequest(std::unique_ptr<ClientRequest> request)
{
boost::asio::dispatch(_strand, [this, request = std::move(request)]() mutable
{
_sendQueue[request->getParameters().priority].emplace_back(std::move(request));
boost::asio::dispatch(_strand, [this, request = std::move(request)]() mutable {
_sendQueue[request->getParameters().priority].emplace_back(std::move(request));
if (_state == State::Idle)
sendNextQueuedRequest();
});
if (_state == State::Idle)
sendNextQueuedRequest();
});
}
void SendQueue::sendNextQueuedRequest()
@@ -220,21 +217,20 @@ namespace lms::core::http
LOG(DEBUG, "Throttling for " << duration.count() << " seconds");
_throttleTimer.expires_after(duration);
_throttleTimer.async_wait([this](const boost::system::error_code& ec)
_throttleTimer.async_wait([this](const boost::system::error_code& ec) {
if (ec == boost::asio::error::operation_aborted)
{
if (ec == boost::asio::error::operation_aborted)
{
LOG(DEBUG, "Throttle aborted");
return;
}
else if (ec)
{
throw LmsException{ "Throttle timer failure: " + std::string {ec.message()} };
}
LOG(DEBUG, "Throttle aborted");
return;
}
else if (ec)
{
throw LmsException{ "Throttle timer failure: " + std::string{ ec.message() } };
}
_state = State::Idle;
sendNextQueuedRequest();
});
_state = State::Idle;
sendNextQueuedRequest();
});
_state = State::Throttled;
}
}
} // namespace lms::core::http
+13 -13
View File
@@ -20,14 +20,14 @@
#pragma once
#include <deque>
#include <vector>
#include <string_view>
#include <vector>
#include <Wt/Http/Client.h>
#include <boost/asio/io_context.hpp>
#include <boost/asio/io_context_strand.hpp>
#include <boost/asio/steady_timer.hpp>
#include <Wt/Http/Client.h>
#include "ClientRequest.hpp"
namespace lms::core::http
@@ -53,15 +53,15 @@ namespace lms::core::http
void onClientDoneSuccess(std::unique_ptr<ClientRequest> request, const Wt::Http::Message& msg);
void throttle(std::chrono::seconds duration);
const std::size_t _maxRetryCount{ 2 };
const std::chrono::seconds _defaultRetryWaitDuration{ 30 };
const std::chrono::seconds _minRetryWaitDuration{ 1 };
const std::chrono::seconds _maxRetryWaitDuration{ 300 };
const std::size_t _maxRetryCount{ 2 };
const std::chrono::seconds _defaultRetryWaitDuration{ 30 };
const std::chrono::seconds _minRetryWaitDuration{ 1 };
const std::chrono::seconds _maxRetryWaitDuration{ 300 };
boost::asio::io_context& _ioContext;
boost::asio::io_context::strand _strand{ _ioContext };
boost::asio::steady_timer _throttleTimer{ _ioContext };
std::string _baseUrl;
boost::asio::io_context::strand _strand{ _ioContext };
boost::asio::steady_timer _throttleTimer{ _ioContext };
std::string _baseUrl;
enum class State
{
@@ -69,10 +69,10 @@ namespace lms::core::http
Throttled,
Sending,
};
State _state{ State::Idle };
Wt::Http::Client _client{ _ioContext };
State _state{ State::Idle };
Wt::Http::Client _client{ _ioContext };
std::map<ClientRequestParameters::Priority, std::deque<std::unique_ptr<ClientRequest>>> _sendQueue;
std::unique_ptr<ClientRequest> _currentRequest;
std::unique_ptr<ClientRequest> _currentRequest;
};
}
} // namespace lms::core::http
@@ -19,7 +19,7 @@
#pragma once
#include <boost/crc.hpp> // for boost::crc_32_type
#include <boost/crc.hpp> // for boost::crc_32_type
namespace lms::core
{
@@ -40,4 +40,4 @@ namespace lms::core
using Crc32Type = boost::crc_32_type;
Crc32Type _result;
};
}
} // namespace lms::core
+8 -5
View File
@@ -27,7 +27,7 @@
namespace lms::core
{
template <typename T, typename underlying_type = std::uint32_t>
template<typename T, typename underlying_type = std::uint32_t>
class EnumSet
{
static_assert(std::is_enum<T>::value);
@@ -45,13 +45,13 @@ namespace lms::core
insert(value);
}
template <typename It>
template<typename It>
constexpr EnumSet(It begin, It end)
{
assign(begin, end);
}
template <typename It>
template<typename It>
constexpr void assign(It begin, It end)
{
clear();
@@ -158,7 +158,10 @@ namespace lms::core
private:
static_assert(std::numeric_limits<IndexType>::max() >= sizeof(underlying_type) * 8);
enum : IndexType { npos = sizeof(underlying_type) * 8 };
enum : IndexType
{
npos = sizeof(underlying_type) * 8
};
constexpr IndexType getFirstBitSetIndex(IndexType start = {}) const
{
@@ -190,4 +193,4 @@ namespace lms::core
underlying_type _bitfield{};
};
}
} // namespace lms::core
+3 -2
View File
@@ -29,6 +29,7 @@ namespace lms::core
class LmsException : public std::runtime_error
{
public:
LmsException(std::string_view error = "") : std::runtime_error{ std::string{ error } } {}
LmsException(std::string_view error = "")
: std::runtime_error{ std::string{ error } } {}
};
}
} // namespace lms::core
+4 -4
View File
@@ -48,9 +48,9 @@ namespace lms::core
};
using ReadCallback = std::function<void(ReadResult, std::size_t)>;
virtual void asyncRead(std::byte* data, std::size_t bufferSize, ReadCallback callback) = 0;
virtual void asyncRead(std::byte* data, std::size_t bufferSize, ReadCallback callback) = 0;
virtual std::size_t readSome(std::byte* data, std::size_t bufferSize) = 0;
virtual bool finished() const = 0;
virtual std::size_t readSome(std::byte* data, std::size_t bufferSize) = 0;
virtual bool finished() const = 0;
};
}
} // namespace lms::core
@@ -20,6 +20,7 @@
#include <filesystem>
#include <memory>
#include <boost/asio/io_service.hpp>
#include "IChildProcess.hpp"
@@ -35,4 +36,4 @@ namespace lms::core
};
std::unique_ptr<IChildProcessManager> createChildProcessManager(boost::asio::io_service& ioService);
}
} // namespace lms::core
+7 -7
View File
@@ -31,13 +31,13 @@ namespace lms::core
virtual ~IConfig() = default;
// Default values are returned in case of setting not found
virtual std::string_view getString(std::string_view setting, std::string_view def = "") = 0;
virtual void visitStrings(std::string_view setting, std::function<void(std::string_view)> _func, std::initializer_list<std::string_view> def = {}) = 0;
virtual std::filesystem::path getPath(std::string_view setting, const std::filesystem::path& def = std::filesystem::path()) = 0;
virtual unsigned long getULong(std::string_view setting, unsigned long def = 0) = 0;
virtual long getLong(std::string_view setting, long def = 0) = 0;
virtual bool getBool(std::string_view setting, bool def = false) = 0;
virtual std::string_view getString(std::string_view setting, std::string_view def = "") = 0;
virtual void visitStrings(std::string_view setting, std::function<void(std::string_view)> _func, std::initializer_list<std::string_view> def = {}) = 0;
virtual std::filesystem::path getPath(std::string_view setting, const std::filesystem::path& def = std::filesystem::path()) = 0;
virtual unsigned long getULong(std::string_view setting, unsigned long def = 0) = 0;
virtual long getLong(std::string_view setting, long def = 0) = 0;
virtual bool getBool(std::string_view setting, bool def = false) = 0;
};
std::unique_ptr<IConfig> createConfig(const std::filesystem::path& p);
}
} // namespace lms::core
+9 -9
View File
@@ -19,11 +19,11 @@
#pragma once
#include <string>
#include <sstream>
#include <string>
#include "core/Service.hpp"
#include "core/String.hpp"
#include "Service.hpp"
namespace lms::core::logging
{
@@ -93,11 +93,11 @@ namespace lms::core::logging
virtual bool isSeverityActive(Severity severity) const = 0;
virtual void processLog(const Log& log) = 0;
};
}
} // namespace lms::core::logging
#define LMS_LOG(module, severity, message) \
do \
{ \
if (auto* logger_ {::lms::core::Service<::lms::core::logging::ILogger>::get()}; logger_ && logger_->isSeverityActive(::lms::core::logging::Severity::severity)) \
::lms::core::logging::Log{ *logger_, ::lms::core::logging::Module::module, ::lms::core::logging::Severity::severity }.getOstream() << message; \
} while(0)
#define LMS_LOG(module, severity, message) \
do \
{ \
if (auto* logger_{ ::lms::core::Service<::lms::core::logging::ILogger>::get() }; logger_ && logger_->isSeverityActive(::lms::core::logging::Severity::severity)) \
::lms::core::logging::Log{ *logger_, ::lms::core::logging::Module::module, ::lms::core::logging::Severity::severity }.getOstream() << message; \
} while (0)
@@ -21,6 +21,7 @@
#include <optional>
#include <thread>
#include <boost/asio/io_service.hpp>
namespace lms::core
@@ -39,7 +40,7 @@ namespace lms::core
IOContextRunner& operator=(const IOContextRunner&) = delete;
boost::asio::io_service& _ioService;
std::optional<boost::asio::io_service::work> _work;
std::vector<std::thread> _threads;
std::optional<boost::asio::io_service::work> _work;
std::vector<std::thread> _threads;
};
}
} // namespace lms::core
@@ -25,13 +25,13 @@
// TODO, move elsewhere
namespace lms
{
// Helper class to serve a resource (must be saved as continuation data if not complete)
class IResourceHandler
{
public:
virtual ~IResourceHandler() = default;
// Helper class to serve a resource (must be saved as continuation data if not complete)
class IResourceHandler
{
public:
virtual ~IResourceHandler() = default;
[[nodiscard]] virtual Wt::Http::ResponseContinuation* processRequest(const Wt::Http::Request& request, Wt::Http::Response& response) = 0;
virtual void abort() = 0;
};
}
[[nodiscard]] virtual Wt::Http::ResponseContinuation* processRequest(const Wt::Http::Request& request, Wt::Http::Response& response) = 0;
virtual void abort() = 0;
};
} // namespace lms
+11 -11
View File
@@ -34,20 +34,20 @@
#define LMS_CONCAT_IMPL(x, y) x##y
#define LMS_CONCAT(x, y) LMS_CONCAT_IMPL(x, y)
#if LMS_SUPPORT_TRACING
#define LMS_SCOPED_TRACE(CATEGORY, LEVEL, NAME, ARGTYPE, ARGVALUE) \
std::optional<::lms::core::tracing::ScopedTrace> LMS_CONCAT(ScopedTrace_, __LINE__); \
if (::lms::core::tracing::ITraceLogger* traceLogger{ ::lms::core::Service<::lms::core::tracing::ITraceLogger>::get() }; traceLogger && traceLogger->isLevelActive(LEVEL)) \
LMS_CONCAT(ScopedTrace_, __LINE__).emplace(CATEGORY, LEVEL, NAME, ARGTYPE, ARGVALUE, traceLogger);
#if LMS_SUPPORT_TRACING
#define LMS_SCOPED_TRACE(CATEGORY, LEVEL, NAME, ARGTYPE, ARGVALUE) \
std::optional<::lms::core::tracing::ScopedTrace> LMS_CONCAT(ScopedTrace_, __LINE__); \
if (::lms::core::tracing::ITraceLogger * traceLogger{ ::lms::core::Service<::lms::core::tracing::ITraceLogger>::get() }; traceLogger && traceLogger->isLevelActive(LEVEL)) \
LMS_CONCAT(ScopedTrace_, __LINE__).emplace(CATEGORY, LEVEL, NAME, ARGTYPE, ARGVALUE, traceLogger);
#else
#define LMS_SCOPED_TRACE(CATEGORY, LEVEL, NAME) (void)0
#define LMS_SCOPED_TRACE(CATEGORY, LEVEL, NAME) (void)0
#endif
#define LMS_SCOPED_TRACE_OVERVIEW_WITH_ARG(CATEGORY, NAME, ARGTYPE, ARGVALUE) LMS_SCOPED_TRACE(CATEGORY, ::lms::core::tracing::Level::Overview, NAME, ARGTYPE, ARGVALUE)
#define LMS_SCOPED_TRACE_DETAILED_WITH_ARG(CATEGORY, NAME, ARGTYPE, ARGVALUE) LMS_SCOPED_TRACE(CATEGORY, ::lms::core::tracing::Level::Detailed, NAME, ARGTYPE, ARGVALUE)
#define LMS_SCOPED_TRACE_OVERVIEW_WITH_ARG(CATEGORY, NAME, ARGTYPE, ARGVALUE) LMS_SCOPED_TRACE(CATEGORY, ::lms::core::tracing::Level::Overview, NAME, ARGTYPE, ARGVALUE)
#define LMS_SCOPED_TRACE_DETAILED_WITH_ARG(CATEGORY, NAME, ARGTYPE, ARGVALUE) LMS_SCOPED_TRACE(CATEGORY, ::lms::core::tracing::Level::Detailed, NAME, ARGTYPE, ARGVALUE)
#define LMS_SCOPED_TRACE_OVERVIEW(CATEGORY, NAME) LMS_SCOPED_TRACE_OVERVIEW_WITH_ARG(CATEGORY, NAME, "", "")
#define LMS_SCOPED_TRACE_DETAILED(CATEGORY, NAME) LMS_SCOPED_TRACE_DETAILED_WITH_ARG(CATEGORY, NAME, "", "")
#define LMS_SCOPED_TRACE_OVERVIEW(CATEGORY, NAME) LMS_SCOPED_TRACE_OVERVIEW_WITH_ARG(CATEGORY, NAME, "", "")
#define LMS_SCOPED_TRACE_DETAILED(CATEGORY, NAME) LMS_SCOPED_TRACE_DETAILED_WITH_ARG(CATEGORY, NAME, "", "")
namespace lms::core::tracing
{
@@ -124,4 +124,4 @@ namespace lms::core::tracing
ITraceLogger* _traceLogger;
ITraceLogger::CompleteEvent _event;
};
}
} // namespace lms::core::tracing
+2 -2
View File
@@ -25,7 +25,7 @@
#include "Exception.hpp"
// TODO, move elsewhere?
// TODO, move elsewhere?
namespace lms::zip
{
struct Entry
@@ -51,4 +51,4 @@ namespace lms::zip
};
std::unique_ptr<IZipper> createArchiveZipper(const EntryContainer& entries);
}
} // namespace lms::zip
+24 -12
View File
@@ -31,7 +31,11 @@ namespace lms::core
public:
constexpr LiteralString() noexcept = default;
template<std::size_t N>
constexpr LiteralString(const char(&str)[N]) noexcept : _str{ str, N - 1 } { static_assert(N > 0); }
constexpr LiteralString(const char (&str)[N]) noexcept
: _str{ str, N - 1 }
{
static_assert(N > 0);
}
constexpr bool empty() const noexcept { return _str.empty(); }
constexpr const char* c_str() const noexcept { return _str.data(); }
@@ -48,7 +52,7 @@ namespace lms::core
os << str.str();
return os;
}
}
} // namespace lms::core
namespace std
{
@@ -60,7 +64,7 @@ namespace std
return hash<std::string_view>{}(str.str());
}
};
}
} // namespace std
namespace lms::core
{
@@ -69,15 +73,18 @@ namespace lms::core
using hash_type = std::hash<std::string_view>;
using is_transparent = void;
[[nodiscard]] size_t operator()(const LiteralString& str) const {
[[nodiscard]] size_t operator()(const LiteralString& str) const
{
return hash_type{}(str.str());
}
[[nodiscard]] size_t operator()(std::string_view str) const {
[[nodiscard]] size_t operator()(std::string_view str) const
{
return hash_type{}(str);
}
[[nodiscard]] size_t operator()(const std::string& str) const {
[[nodiscard]] size_t operator()(const std::string& str) const
{
return hash_type{}(str);
}
};
@@ -86,24 +93,29 @@ namespace lms::core
{
using is_transparent = void;
[[nodiscard]] bool operator()(const LiteralString& lhs, const LiteralString& rhs) const {
[[nodiscard]] bool operator()(const LiteralString& lhs, const LiteralString& rhs) const
{
return lhs == rhs;
}
[[nodiscard]] bool operator()(const LiteralString& lhs, const std::string& rhs) const {
[[nodiscard]] bool operator()(const LiteralString& lhs, const std::string& rhs) const
{
return lhs.str() == rhs;
}
[[nodiscard]] bool operator()(const LiteralString& lhs, std::string_view rhs) const {
[[nodiscard]] bool operator()(const LiteralString& lhs, std::string_view rhs) const
{
return lhs.str() == rhs;
}
[[nodiscard]] bool operator()(const std::string_view& lhs, LiteralString rhs) const {
[[nodiscard]] bool operator()(const std::string_view& lhs, LiteralString rhs) const
{
return lhs == rhs.str();
}
[[nodiscard]] bool operator()(const std::string& lhs, const LiteralString& rhs) const {
[[nodiscard]] bool operator()(const std::string& lhs, const LiteralString& rhs) const
{
return lhs == rhs.str();
}
};
}
} // namespace lms::core
+7 -6
View File
@@ -22,15 +22,16 @@
#include <boost/asio/ip/address.hpp>
#ifndef BOOST_ASIO_HAS_STD_HASH
#include <functional>
#include <functional>
namespace std
{
template<> struct hash<boost::asio::ip::address>
{
std::size_t operator()(const boost::asio::ip::address& ipAddr) const;
};
template<>
struct hash<boost::asio::ip::address>
{
std::size_t operator()(const boost::asio::ip::address& ipAddr) const;
};
}
} // namespace std
#endif // BOOST_ASIO_HAS_STD_HASH
+2 -2
View File
@@ -49,7 +49,7 @@ namespace lms::core::pathUtils
std::filesystem::path getLongestCommonPath(const std::filesystem::path& path1, const std::filesystem::path& path2);
template <typename Iterator>
template<typename Iterator>
std::filesystem::path getLongestCommonPath(Iterator first, Iterator last)
{
std::filesystem::path longestCommonPath;
@@ -64,4 +64,4 @@ namespace lms::core::pathUtils
return longestCommonPath;
}
}
} // namespace lms::core::pathUtils
+5 -5
View File
@@ -29,27 +29,27 @@ namespace lms::core::random
RandGenerator createSeededGenerator(uint_fast32_t seed);
template <typename T>
template<typename T>
T getRandom(T min, T max)
{
std::uniform_int_distribution<> dist{ min, max };
return dist(getRandGenerator());
}
template <typename T>
template<typename T>
T getRealRandom(T min, T max)
{
std::uniform_real_distribution<> dist{ min, max };
return dist(getRandGenerator());
}
template <typename Container>
template<typename Container>
void shuffleContainer(Container& container)
{
std::shuffle(std::begin(container), std::end(container), getRandGenerator());
}
template <typename Container>
template<typename Container>
typename Container::const_iterator pickRandom(const Container& container)
{
if (container.empty())
@@ -57,4 +57,4 @@ namespace lms::core::random
return std::next(std::begin(container), getRandom(0, static_cast<int>(container.size() - 1)));
}
}
} // namespace lms::core::random
@@ -48,4 +48,4 @@ namespace lms::core
std::mutex _sharedCountMutex;
std::unordered_map<std::thread::id, std::size_t> _sharedCounts;
};
}
} // namespace lms::core
+3 -3
View File
@@ -24,7 +24,7 @@
namespace lms::core
{
template <typename Class>
template<typename Class>
class Service
{
public:
@@ -57,7 +57,7 @@ namespace lms::core
static Class* get() { return _service.get(); }
static bool exists() { return _service.get(); }
template <typename SubClass>
template<typename SubClass>
static Class& assign(std::unique_ptr<SubClass> service)
{
assert(!_service);
@@ -70,4 +70,4 @@ namespace lms::core
static inline std::unique_ptr<Class> _service;
};
}
} // namespace lms::core
+1 -1
View File
@@ -39,4 +39,4 @@ namespace lms::core::logging
std::ostream& _os;
const EnumSet<Severity> _severities;
};
}
} // namespace lms::core::logging
+4 -4
View File
@@ -22,9 +22,9 @@
#include <initializer_list>
#include <optional>
#include <span>
#include <sstream>
#include <string>
#include <string_view>
#include <sstream>
#include <vector>
#define QUOTEME(x) QUOTEME_1(x)
@@ -34,7 +34,7 @@ namespace Wt
{
class WDate;
class WDateTime;
}
} // namespace Wt
namespace lms::core::stringUtils
{
@@ -67,7 +67,7 @@ namespace lms::core::stringUtils
{
T res;
std::istringstream iss{ std::string {str} };
std::istringstream iss{ std::string{ str } };
iss >> res;
if (iss.fail())
return std::nullopt;
@@ -100,4 +100,4 @@ namespace lms::core::stringUtils
[[nodiscard]] std::string toISO8601String(const Wt::WDateTime& dateTime);
[[nodiscard]] std::string toISO8601String(const Wt::WDate& date);
}
} // namespace lms::core::stringUtils
+26 -20
View File
@@ -23,27 +23,33 @@
namespace lms::core
{
namespace details
{
template<int... Is>
struct Seq { };
namespace details
{
template<int... Is>
struct Seq
{
};
template<int N, int... Is>
struct GenSeq : GenSeq<N - 1, N - 1, Is...> { };
template<int N, int... Is>
struct GenSeq : GenSeq<N - 1, N - 1, Is...>
{
};
template<int... Is>
struct GenSeq<0, Is...> : Seq<Is...> { };
template<int... Is>
struct GenSeq<0, Is...> : Seq<Is...>
{
};
template<typename T, typename Func, int... Is>
void forEachTypeInTuple(T&& t, Func f, Seq<Is...>)
{
auto l = { (f(std::get<Is>(t)), 0)... };
}
}
template<typename T, typename Func, int... Is>
void forEachTypeInTuple(T&& t, Func f, Seq<Is...>)
{
auto l = { (f(std::get<Is>(t)), 0)... };
}
} // namespace details
template<typename... Ts, typename Func>
void forEachTypeInTuple(std::tuple<Ts...> const& t, Func f)
{
details::forEachTypeInTuple(t, f, details::GenSeq<sizeof...(Ts)>());
}
}
template<typename... Ts, typename Func>
void forEachTypeInTuple(std::tuple<Ts...> const& t, Func f)
{
details::forEachTypeInTuple(t, f, details::GenSeq<sizeof...(Ts)>());
}
} // namespace lms::core
+3 -3
View File
@@ -41,11 +41,11 @@ namespace lms::core
UUID(std::string_view value);
std::string _value;
};
}
} // namespace lms::core
namespace lms::core::stringUtils
{
template <>
template<>
std::optional<UUID>
readAs(std::string_view str);
readAs(std::string_view str);
}
+15 -14
View File
@@ -24,18 +24,19 @@
namespace lms::core::utils
{
template<class T, class Compare = std::less<>>
constexpr T clamp(T v, T lo, T hi, Compare comp = {})
{
assert(!comp(hi, lo));
return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
}
template<class T, class Compare = std::less<>>
constexpr T clamp(T v, T lo, T hi, Compare comp = {})
{
assert(!comp(hi, lo));
return comp(v, lo) ? lo : comp(hi, v) ? hi :
v;
}
template <typename Container, typename T>
void
push_back_if_not_present(Container& container, const T& val)
{
if (std::find(std::cbegin(container), std::cend(container), val) == std::cend(container))
container.push_back(val);
}
}
template<typename Container, typename T>
void
push_back_if_not_present(Container& container, const T& val)
{
if (std::find(std::cbegin(container), std::cend(container), val) == std::cend(container))
container.push_back(val);
}
} // namespace lms::core::utils
+1 -1
View File
@@ -37,4 +37,4 @@ namespace lms::core::logging
void processLog(const Log& log) override;
const Severity _minSeverity;
};
}
} // namespace lms::core::logging
@@ -36,7 +36,7 @@ namespace lms::core::http
Low,
};
Priority priority{ Priority::Normal };
Priority priority{ Priority::Normal };
std::string relativeUrl; // relative to baseUrl used by the client
using OnSuccessFunc = std::function<void(std::string_view msgBody)>;
@@ -56,4 +56,4 @@ namespace lms::core::http
Wt::Http::Message message;
};
}
} // namespace lms::core::http
+10 -9
View File
@@ -20,20 +20,21 @@
#pragma once
#include <string_view>
#include <boost/asio/io_context.hpp>
#include "core/http/ClientRequestParameters.hpp"
namespace lms::core::http
{
class IClient
{
public:
virtual ~IClient() = default;
class IClient
{
public:
virtual ~IClient() = default;
virtual void sendGETRequest(ClientGETRequestParameters&& request) = 0;
virtual void sendPOSTRequest(ClientPOSTRequestParameters&& request) = 0;
};
virtual void sendGETRequest(ClientGETRequestParameters&& request) = 0;
virtual void sendPOSTRequest(ClientPOSTRequestParameters&& request) = 0;
};
std::unique_ptr<IClient> createClient(boost::asio::io_context& ioContext, std::string_view baseUrl);
}
std::unique_ptr<IClient> createClient(boost::asio::io_context& ioContext, std::string_view baseUrl);
} // namespace lms::core::http
+1 -1
View File
@@ -60,4 +60,4 @@ namespace lms::core
EXPECT_EQ(test, test2);
}
}
}
} // namespace lms::core
+4 -4
View File
@@ -18,6 +18,7 @@
*/
#include <unordered_map>
#include <gtest/gtest.h>
#include "core/LiteralString.hpp"
@@ -53,7 +54,7 @@ namespace lms::core
TEST(LiteralString, unordered_map)
{
{
std::unordered_map<LiteralString, int> myMap{ {"abc", 42} };
std::unordered_map<LiteralString, int> myMap{ { "abc", 42 } };
EXPECT_TRUE(myMap.contains("abc"));
EXPECT_TRUE(myMap.contains(LiteralString{ "abc" }));
@@ -61,12 +62,11 @@ namespace lms::core
}
{
std::unordered_map<LiteralString, int, LiteralStringHash, LiteralStringEqual> myMap{ {"abc", 42} };
std::unordered_map<LiteralString, int, LiteralStringHash, LiteralStringEqual> myMap{ { "abc", 42 } };
EXPECT_TRUE(myMap.contains(std::string{ "abc" }));
EXPECT_TRUE(myMap.contains(std::string_view{ "abc" }));
EXPECT_FALSE(myMap.contains(std::string{ "abcd" }));
EXPECT_FALSE(myMap.contains(std::string_view{ "abcd" }));
}
}
}
} // namespace lms::core
+30 -34
View File
@@ -32,14 +32,13 @@ namespace lms::core::pathUtils::tests
std::filesystem::path expectedCommonPath;
};
TestCase tests[]
{
{"foo.txt", "/foo/foo.txt", ""},
{"/", "/file.txt", "/"},
{"/foo/bar/file1.txt", "/foo/bar/file2.txt", "/foo/bar"},
{"/foo/bar/file.txt", "/foo/bar/file.txt", "/foo/bar/file.txt"},
{"/dir1/file.txt", "/dir2/file.txt", "/"},
{"/prefix/folder/file.txt", "/prefix/folder/subfolder/file.txt", "/prefix/folder"},
TestCase tests[]{
{ "foo.txt", "/foo/foo.txt", "" },
{ "/", "/file.txt", "/" },
{ "/foo/bar/file1.txt", "/foo/bar/file2.txt", "/foo/bar" },
{ "/foo/bar/file.txt", "/foo/bar/file.txt", "/foo/bar/file.txt" },
{ "/dir1/file.txt", "/dir2/file.txt", "/" },
{ "/prefix/folder/file.txt", "/prefix/folder/subfolder/file.txt", "/prefix/folder" },
};
for (const TestCase& test : tests)
@@ -48,7 +47,6 @@ namespace lms::core::pathUtils::tests
}
}
TEST(Path, getLongestCommonPathIterator)
{
struct TestCase
@@ -57,17 +55,16 @@ namespace lms::core::pathUtils::tests
std::filesystem::path expectedCommonPath;
};
TestCase tests[]
{
{{}, ""},
{{"/"}, "/"},
{{"/foo", "/bar"}, "/"},
{{"/foo/bar/file1.txt", "/foo/bar/file2.txt"}, "/foo/bar"},
{{"/foo", "/foo/"}, "/foo"},
{{"/foo", "/foo"}, "/foo"},
{{"/foo/", "/foo/"}, "/foo/"},
{{"/foo/", "/foo/", "/bar"}, "/"},
{{"/foo/", "/foo/", "/foo/bar"}, "/foo"},
TestCase tests[]{
{ {}, "" },
{ { "/" }, "/" },
{ { "/foo", "/bar" }, "/" },
{ { "/foo/bar/file1.txt", "/foo/bar/file2.txt" }, "/foo/bar" },
{ { "/foo", "/foo/" }, "/foo" },
{ { "/foo", "/foo" }, "/foo" },
{ { "/foo/", "/foo/" }, "/foo/" },
{ { "/foo/", "/foo/", "/bar" }, "/" },
{ { "/foo/", "/foo/", "/foo/bar" }, "/foo" },
};
for (const TestCase& test : tests)
@@ -85,19 +82,18 @@ namespace lms::core::pathUtils::tests
bool expectedResult;
};
TestCase tests[]
{
{"/file.txt", "/", true},
{"/root/folder/file.txt", "/root", true},
{"/root/file.txt", "/root", true},
{"/root/file.txt", "/root/", true},
{"/root", "/root", true},
{"/root", "/root/", true},
{"/root/", "/root", true},
{"/root/", "/root/", true},
{"/folder/file.txt", "/root", false},
{"/folder/file.txt", "/root/", false},
{"", "/root", false},
TestCase tests[]{
{ "/file.txt", "/", true },
{ "/root/folder/file.txt", "/root", true },
{ "/root/file.txt", "/root", true },
{ "/root/file.txt", "/root/", true },
{ "/root", "/root", true },
{ "/root", "/root/", true },
{ "/root/", "/root", true },
{ "/root/", "/root/", true },
{ "/folder/file.txt", "/root", false },
{ "/folder/file.txt", "/root/", false },
{ "", "/root", false },
};
for (const TestCase& test : tests)
@@ -105,4 +101,4 @@ namespace lms::core::pathUtils::tests
EXPECT_EQ(core::pathUtils::isPathInRootPath(test.path, test.rootPath), test.expectedResult) << "Failed: path = " << test.path << ", rootPath = " << test.rootPath;
}
}
}
} // namespace lms::core::pathUtils::tests
+24 -25
View File
@@ -66,40 +66,39 @@ namespace lms::core
std::atomic<std::size_t> nbShared{};
for (std::size_t i{}; i < nbThreads; ++i)
{
threads.emplace_back([&]
threads.emplace_back([&] {
{
{
std::unique_lock lock{ mutex };
std::unique_lock lock{ mutex };
std::shared_lock lock2{ mutex };
std::shared_lock lock2{ mutex };
assert(nbUnique == 0);
assert(nbShared == 0);
nbUnique++;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
assert(nbUnique == 1);
assert(nbShared == 0);
nbUnique--;
}
assert(nbUnique == 0);
assert(nbShared == 0);
nbUnique++;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
assert(nbUnique == 1);
assert(nbShared == 0);
nbUnique--;
}
{
std::shared_lock lock{ mutex };
std::shared_lock lock2{ mutex };
{
std::shared_lock lock{ mutex };
std::shared_lock lock2{ mutex };
assert(nbUnique == 0);
nbShared++;
assert(nbUnique == 0);
nbShared++;
std::this_thread::sleep_for(std::chrono::milliseconds(15));
std::this_thread::sleep_for(std::chrono::milliseconds(15));
assert(nbShared > 0);
assert(nbShared <= nbThreads);
assert(nbUnique == 0);
nbShared--;
}
});
assert(nbShared > 0);
assert(nbShared <= nbThreads);
assert(nbUnique == 0);
nbShared--;
}
});
}
for (std::thread& t : threads)
t.join();
}
}
} // namespace lms::core
+69 -74
View File
@@ -19,9 +19,10 @@
#include <gtest/gtest.h>
#include <Wt/WDateTime.h>
#include <Wt/WDate.h>
#include <Wt/WDateTime.h>
#include <Wt/WTime.h>
#include "core/String.hpp"
namespace lms::core::stringUtils::tests
@@ -35,30 +36,29 @@ namespace lms::core::stringUtils::tests
std::vector<std::string_view> expectedOutput;
};
TestCase tests[]
{
{"abc", '-', {"abc"}},
{"a", '-', {"a"}},
{"", '-', {""}},
{"a-b-c", '-', {"a", "b", "c"}},
{"a|b|c", '|', {"a", "b", "c"}},
{"a;b;c", ';', {"a", "b", "c"}},
{";b;c", ';', {"", "b", "c"}},
{" ;b;c", ';', {" ", "b", "c"}},
{" ;;c", ';', {" ", "", "c"}},
{" ; ;c", ';', {" ", " ", "c"}},
{"a;b; ", ';', {"a", "b", " "}},
{"a;b", ';', {"a", "b"}},
{";b", ';', {"", "b"}},
{";", ';', {"", ""}},
{";;", ';', {"", "", ""}},
{";;;", ';', {"", "", "", ""}},
{";;a;;b;;", ';', {"", "", "a", "", "b", "", ""}},
{"a b", ' ', {"a", "b"}},
{"", ' ', {""}},
{"a-b|c", '-', {"a","b|c"}},
{"a|b-c", '-', {"a|b", "c"}},
{"test=foo bar", '=', {"test", "foo bar"}},
TestCase tests[]{
{ "abc", '-', { "abc" } },
{ "a", '-', { "a" } },
{ "", '-', { "" } },
{ "a-b-c", '-', { "a", "b", "c" } },
{ "a|b|c", '|', { "a", "b", "c" } },
{ "a;b;c", ';', { "a", "b", "c" } },
{ ";b;c", ';', { "", "b", "c" } },
{ " ;b;c", ';', { " ", "b", "c" } },
{ " ;;c", ';', { " ", "", "c" } },
{ " ; ;c", ';', { " ", " ", "c" } },
{ "a;b; ", ';', { "a", "b", " " } },
{ "a;b", ';', { "a", "b" } },
{ ";b", ';', { "", "b" } },
{ ";", ';', { "", "" } },
{ ";;", ';', { "", "", "" } },
{ ";;;", ';', { "", "", "", "" } },
{ ";;a;;b;;", ';', { "", "", "a", "", "b", "", "" } },
{ "a b", ' ', { "a", "b" } },
{ "", ' ', { "" } },
{ "a-b|c", '-', { "a", "b|c" } },
{ "a|b-c", '-', { "a|b", "c" } },
{ "test=foo bar", '=', { "test", "foo bar" } },
};
for (const TestCase& test : tests)
@@ -77,19 +77,18 @@ namespace lms::core::stringUtils::tests
std::vector<std::string_view> expectedOutput;
};
TestCase tests[]
{
{"abc", "", {"abc"}},
{"abc", "-", {"abc"}},
{"abc", "b", {"a", "c"}},
{"ab/cd", "/", {"ab", "cd"}},
{"ab/cd", "/ ", {"ab/cd"}},
{"ab/cd", " /", {"ab/cd"}},
{"ab /cd", " /", {"ab", "cd"}},
{"ab/ cd", "/ ", {"ab", "cd"}},
{"ab / cd", " / ", {"ab", "cd"}},
{"ab/cd", " / ", {"ab/cd"}},
{"ab/cd / ", " / ", {"ab/cd", ""}},
TestCase tests[]{
{ "abc", "", { "abc" } },
{ "abc", "-", { "abc" } },
{ "abc", "b", { "a", "c" } },
{ "ab/cd", "/", { "ab", "cd" } },
{ "ab/cd", "/ ", { "ab/cd" } },
{ "ab/cd", " /", { "ab/cd" } },
{ "ab /cd", " /", { "ab", "cd" } },
{ "ab/ cd", "/ ", { "ab", "cd" } },
{ "ab / cd", " / ", { "ab", "cd" } },
{ "ab/cd", " / ", { "ab/cd" } },
{ "ab/cd / ", " / ", { "ab/cd", "" } },
};
for (const TestCase& test : tests)
@@ -108,15 +107,14 @@ namespace lms::core::stringUtils::tests
std::string expectedOutput;
};
TestCase tests[]
{
{{"a", "b", "c"}, "-", "a-b-c"},
{{"a", "b", "c"}, ",", "a,b,c"},
{{"a", "b", "c"}, "***", "a***b***c"},
{{"a", "", "c"}, "-", "a--c"},
{{"", "b", "c"}, "-", "-b-c"},
{{"a"}, "-", "a"},
{{"a"}, ",", "a"},
TestCase tests[]{
{ { "a", "b", "c" }, "-", "a-b-c" },
{ { "a", "b", "c" }, ",", "a,b,c" },
{ { "a", "b", "c" }, "***", "a***b***c" },
{ { "a", "", "c" }, "-", "a--c" },
{ { "", "b", "c" }, "-", "-b-c" },
{ { "a" }, "-", "a" },
{ { "a" }, ",", "a" },
};
for (const TestCase& test : tests)
@@ -136,13 +134,12 @@ namespace lms::core::stringUtils::tests
std::string expectedOutput;
};
TestCase tests[]
{
{{""}, ';', '\\', ""},
{{";"}, ';', '\\', "\\;"},
{{";;"}, ';', '\\', "\\;\\;"},
{{"a;", "b"}, ';', '\\', "a\\;;b"},
{{"a;", "b;"}, ';', '\\', "a\\;;b\\;"},
TestCase tests[]{
{ { "" }, ';', '\\', "" },
{ { ";" }, ';', '\\', "\\;" },
{ { ";;" }, ';', '\\', "\\;\\;" },
{ { "a;", "b" }, ';', '\\', "a\\;;b" },
{ { "a;", "b;" }, ';', '\\', "a\\;;b\\;" },
};
for (const TestCase& test : tests)
@@ -162,13 +159,12 @@ namespace lms::core::stringUtils::tests
std::vector<std::string> expectedOutput;
};
TestCase tests[]
{
{"", ';', '\\', {}},
{"\\;", ';', '\\', {";"}},
{"\\;\\;", ';', '\\', {";;"}},
{"a\\;;b", ';', '\\', {"a;", "b"}},
{"a\\;;b\\;", ';', '\\', {"a;", "b;"}},
TestCase tests[]{
{ "", ';', '\\', {} },
{ "\\;", ';', '\\', { ";" } },
{ "\\;\\;", ';', '\\', { ";;" } },
{ "a\\;;b", ';', '\\', { "a;", "b" } },
{ "a\\;;b\\;", ';', '\\', { "a;", "b;" } },
};
for (const TestCase& test : tests)
@@ -250,17 +246,16 @@ namespace lms::core::stringUtils::tests
std::string expectedOutput;
};
TestCase tests[]
{
{"", ""},
{"C", "C"},
{"c", "C"},
{" c", " C"},
{" cc", " Cc"},
{"(c", "(c"},
{"1c", "1c"},
{"&c", "&c"},
{"c c", "C c"}
TestCase tests[]{
{ "", "" },
{ "C", "C" },
{ "c", "C" },
{ " c", " C" },
{ " cc", " Cc" },
{ "(c", "(c" },
{ "1c", "1c" },
{ "&c", "&c" },
{ "c c", "C c" }
};
for (const TestCase& test : tests)
@@ -279,7 +274,7 @@ namespace lms::core::stringUtils::tests
TEST(Stringutils, dateTime)
{
const Wt::WDateTime dateTime{ Wt::WDate {2020, 01, 03 }, Wt::WTime{9, 8, 11, 75} };
const Wt::WDateTime dateTime{ Wt::WDate{ 2020, 01, 03 }, Wt::WTime{ 9, 8, 11, 75 } };
EXPECT_EQ(toISO8601String(dateTime), "2020-01-03T09:08:11.075");
}
@@ -294,4 +289,4 @@ namespace lms::core::stringUtils::tests
EXPECT_FALSE(stringEndsWith("FooBar", "1FooBar"));
EXPECT_FALSE(stringEndsWith("FooBar", "R"));
}
}
} // namespace lms::core::stringUtils::tests
+6 -6
View File
@@ -19,6 +19,7 @@
#include <sstream>
#include <thread>
#include <gtest/gtest.h>
#include "core/ITraceLogger.hpp"
@@ -33,11 +34,10 @@ namespace lms::core::tracing::tests
std::vector<std::thread> threads;
for (std::size_t i{}; i < 16; ++i)
{
threads.emplace_back([&]
{
ScopedTrace loggedEvent{ "MyCategory", Level::Overview, "MyEventLogged", "SomeArgType", "SomeArg", traceLogger.get() };
ScopedTrace notLoggedEvent{ "MyNotLoggedCategory", Level::Detailed, "MyEventNotLogged", "SomeNotLoggedArgType", "SomeNotLoggedArg", traceLogger.get() };
});
threads.emplace_back([&] {
ScopedTrace loggedEvent{ "MyCategory", Level::Overview, "MyEventLogged", "SomeArgType", "SomeArg", traceLogger.get() };
ScopedTrace notLoggedEvent{ "MyNotLoggedCategory", Level::Detailed, "MyEventNotLogged", "SomeNotLoggedArgType", "SomeNotLoggedArg", traceLogger.get() };
});
}
for (std::thread& t : threads)
@@ -56,4 +56,4 @@ namespace lms::core::tracing::tests
EXPECT_EQ(oss.str().find("SomeNotLoggedArgType"), std::string::npos);
EXPECT_EQ(oss.str().find("SomeNotLoggedArg"), std::string::npos);
}
}
} // namespace lms::core::tracing::tests
+1 -1
View File
@@ -37,4 +37,4 @@ namespace lms::core
EXPECT_TRUE(uuid1 >= uuid2);
EXPECT_TRUE(uuid1 <= uuid2);
}
}
} // namespace lms::core
+3 -4
View File
@@ -19,9 +19,8 @@
#include <gtest/gtest.h>
int main(int argc, char **argv)
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}