summaryrefslogtreecommitdiffstats
path: root/src/libutil/cxx
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2023-07-26 10:49:23 +0100
committerVsevolod Stakhov <vsevolod@rspamd.com>2023-07-26 10:49:23 +0100
commit537a7180a0d5132c11636c4fd8b1450cd99d352c (patch)
treefb9f8c84955a411bdffbd6371ea32f2716fb3687 /src/libutil/cxx
parent5fd7a90fdaa33f52c59bdb0ca84451e5c1e22365 (diff)
downloadrspamd-537a7180a0d5132c11636c4fd8b1450cd99d352c.tar.gz
rspamd-537a7180a0d5132c11636c4fd8b1450cd99d352c.zip
[Rework] Use clang-format to unify formatting in all sources
No meaningful changes.
Diffstat (limited to 'src/libutil/cxx')
-rw-r--r--src/libutil/cxx/error.hxx36
-rw-r--r--src/libutil/cxx/file_util.cxx296
-rw-r--r--src/libutil/cxx/file_util.hxx99
-rw-r--r--src/libutil/cxx/hash_util.hxx46
-rw-r--r--src/libutil/cxx/local_shared_ptr.hxx222
-rw-r--r--src/libutil/cxx/utf8_util.cxx232
-rw-r--r--src/libutil/cxx/utf8_util.h10
-rw-r--r--src/libutil/cxx/util.hxx92
-rw-r--r--src/libutil/cxx/util_tests.cxx36
9 files changed, 630 insertions, 439 deletions
diff --git a/src/libutil/cxx/error.hxx b/src/libutil/cxx/error.hxx
index 714ed309b..91f9d0cf4 100644
--- a/src/libutil/cxx/error.hxx
+++ b/src/libutil/cxx/error.hxx
@@ -44,8 +44,10 @@ public:
* @param code
* @param category
*/
- error(const char *msg, int code, error_category category = error_category::INFORMAL) :
- error_message(msg), error_code(code), category(category) {}
+ error(const char *msg, int code, error_category category = error_category::INFORMAL)
+ : error_message(msg), error_code(code), category(category)
+ {
+ }
/**
* Construct error from a temporary string taking membership
* @param msg
@@ -53,7 +55,8 @@ public:
* @param category
*/
error(std::string &&msg, int code, error_category category = error_category::INFORMAL)
- : error_code(code), category(category) {
+ : error_code(code), category(category)
+ {
static_storage = std::move(msg);
error_message = static_storage.value();
}
@@ -64,12 +67,15 @@ public:
* @param category
*/
error(const std::string &msg, int code, error_category category = error_category::INFORMAL)
- : error_code(code), category(category) {
+ : error_code(code), category(category)
+ {
static_storage = msg;
error_message = static_storage.value();
}
- error(const error &other) : error_code(other.error_code), category(other.category) {
+ error(const error &other)
+ : error_code(other.error_code), category(other.category)
+ {
if (other.static_storage) {
static_storage = other.static_storage;
error_message = static_storage.value();
@@ -79,11 +85,13 @@ public:
}
}
- error(error &&other) noexcept {
+ error(error &&other) noexcept
+ {
*this = std::move(other);
}
- error& operator = (error &&other) noexcept {
+ error &operator=(error &&other) noexcept
+ {
if (other.static_storage.has_value()) {
std::swap(static_storage, other.static_storage);
error_message = static_storage.value();
@@ -101,28 +109,32 @@ public:
* Convert into GError
* @return
*/
- auto into_g_error() const -> GError * {
+ auto into_g_error() const -> GError *
+ {
return g_error_new(g_quark_from_static_string("rspamd"), error_code, "%s",
- error_message.data());
+ error_message.data());
}
/**
* Convenience alias for the `into_g_error`
* @param err
*/
- auto into_g_error_set(GError **err) const -> void {
+ auto into_g_error_set(GError **err) const -> void
+ {
if (err && *err == nullptr) {
*err = into_g_error();
}
}
+
public:
std::string_view error_message;
int error_code;
error_category category;
+
private:
std::optional<std::string> static_storage;
};
-} // namespace rspamd::util
+}// namespace rspamd::util
-#endif //RSPAMD_ERROR_HXX
+#endif//RSPAMD_ERROR_HXX
diff --git a/src/libutil/cxx/file_util.cxx b/src/libutil/cxx/file_util.cxx
index bc9028aa8..9baf062a5 100644
--- a/src/libutil/cxx/file_util.cxx
+++ b/src/libutil/cxx/file_util.cxx
@@ -32,7 +32,7 @@ auto raii_file::open(const char *fname, int flags) -> tl::expected<raii_file, er
#endif
if (fname == nullptr) {
- return tl::make_unexpected(error {"cannot open file; filename is nullptr", EINVAL, error_category::CRITICAL});
+ return tl::make_unexpected(error{"cannot open file; filename is nullptr", EINVAL, error_category::CRITICAL});
}
auto fd = ::open(fname, oflags);
@@ -44,7 +44,7 @@ auto raii_file::open(const char *fname, int flags) -> tl::expected<raii_file, er
auto ret = raii_file{fname, fd, false};
if (fstat(ret.fd, &ret.st) == -1) {
- return tl::make_unexpected(error {fmt::format("cannot stat file {}: {}", fname, ::strerror(errno)), errno});
+ return tl::make_unexpected(error{fmt::format("cannot stat file {}: {}", fname, ::strerror(errno)), errno});
}
return ret;
@@ -52,13 +52,13 @@ auto raii_file::open(const char *fname, int flags) -> tl::expected<raii_file, er
auto raii_file::create(const char *fname, int flags, int perms) -> tl::expected<raii_file, error>
{
- int oflags = flags|O_CREAT;
+ int oflags = flags | O_CREAT;
#ifdef O_CLOEXEC
oflags |= O_CLOEXEC;
#endif
if (fname == nullptr) {
- return tl::make_unexpected(error {"cannot create file; filename is nullptr", EINVAL, error_category::CRITICAL});
+ return tl::make_unexpected(error{"cannot create file; filename is nullptr", EINVAL, error_category::CRITICAL});
}
auto fd = ::open(fname, oflags, perms);
@@ -83,19 +83,19 @@ auto raii_file::create_temp(const char *fname, int flags, int perms) -> tl::expe
oflags |= O_CLOEXEC | O_CREAT | O_EXCL;
#endif
if (fname == nullptr) {
- return tl::make_unexpected(error {"cannot open file; filename is nullptr", EINVAL, error_category::CRITICAL});
+ return tl::make_unexpected(error{"cannot open file; filename is nullptr", EINVAL, error_category::CRITICAL});
}
auto fd = ::open(fname, oflags, perms);
if (fd == -1) {
- return tl::make_unexpected(error {fmt::format("cannot create file {}: {}", fname, ::strerror(errno)), errno});
+ return tl::make_unexpected(error{fmt::format("cannot create file {}: {}", fname, ::strerror(errno)), errno});
}
auto ret = raii_file{fname, fd, true};
if (fstat(ret.fd, &ret.st) == -1) {
- return tl::make_unexpected(error {fmt::format("cannot stat file {}: {}", fname, ::strerror(errno)), errno});
+ return tl::make_unexpected(error{fmt::format("cannot stat file {}: {}", fname, ::strerror(errno)), errno});
}
return ret;
@@ -108,8 +108,7 @@ auto raii_file::mkstemp(const char *pattern, int flags, int perms) -> tl::expect
oflags |= O_CLOEXEC | O_CREAT | O_EXCL;
#endif
if (pattern == nullptr) {
- return tl::make_unexpected(error {"cannot open file; pattern is nullptr", EINVAL, error_category::CRITICAL});
-
+ return tl::make_unexpected(error{"cannot open file; pattern is nullptr", EINVAL, error_category::CRITICAL});
}
std::string mutable_pattern = pattern;
@@ -117,14 +116,15 @@ auto raii_file::mkstemp(const char *pattern, int flags, int perms) -> tl::expect
auto fd = g_mkstemp_full(mutable_pattern.data(), oflags, perms);
if (fd == -1) {
- return tl::make_unexpected(error {fmt::format("cannot create file {}: {}", pattern, ::strerror(errno)), errno});
+ return tl::make_unexpected(error{fmt::format("cannot create file {}: {}", pattern, ::strerror(errno)), errno});
}
auto ret = raii_file{mutable_pattern.c_str(), fd, true};
if (fstat(ret.fd, &ret.st) == -1) {
- return tl::make_unexpected(error { fmt::format("cannot stat file {}: {}",
- mutable_pattern, ::strerror(errno)), errno} );
+ return tl::make_unexpected(error{fmt::format("cannot stat file {}: {}",
+ mutable_pattern, ::strerror(errno)),
+ errno});
}
return ret;
@@ -134,7 +134,7 @@ raii_file::~raii_file() noexcept
{
if (fd != -1) {
if (temp) {
- (void)unlink(fname.c_str());
+ (void) unlink(fname.c_str());
}
close(fd);
}
@@ -145,7 +145,8 @@ auto raii_file::update_stat() noexcept -> bool
return fstat(fd, &st) != -1;
}
-raii_file::raii_file(const char *fname, int fd, bool temp) : fd(fd), temp(temp)
+raii_file::raii_file(const char *fname, int fd, bool temp)
+ : fd(fd), temp(temp)
{
std::size_t nsz;
@@ -167,22 +168,23 @@ auto raii_locked_file::lock_raii_file(raii_file &&unlocked) -> tl::expected<raii
{
if (!rspamd_file_lock(unlocked.get_fd(), TRUE)) {
return tl::make_unexpected(
- error { fmt::format("cannot lock file {}: {}", unlocked.get_name(), ::strerror(errno)), errno});
+ error{fmt::format("cannot lock file {}: {}", unlocked.get_name(), ::strerror(errno)), errno});
}
return raii_locked_file{std::move(unlocked)};
}
-auto raii_locked_file::unlock() -> raii_file {
+auto raii_locked_file::unlock() -> raii_file
+{
if (fd != -1) {
(void) rspamd_file_unlock(fd, FALSE);
}
- return raii_file{static_cast<raii_file&&>(std::move(*this))};
+ return raii_file{static_cast<raii_file &&>(std::move(*this))};
}
raii_mmaped_file::raii_mmaped_file(raii_file &&file, void *map, std::size_t sz)
- : file(std::move(file)), map(map), map_size(sz)
+ : file(std::move(file)), map(map), map_size(sz)
{
}
@@ -192,21 +194,22 @@ auto raii_mmaped_file::mmap_shared(raii_file &&file,
void *map;
if (file.get_stat().st_size < offset || offset < 0) {
- return tl::make_unexpected(error {
+ return tl::make_unexpected(error{
fmt::format("cannot mmap file {} due to incorrect offset; offset={}, size={}",
- file.get_name(), offset, file.get_size()), EINVAL});
+ file.get_name(), offset, file.get_size()),
+ EINVAL});
}
/* Update stat on file to ensure it is up-to-date */
file.update_stat();
map = mmap(nullptr, (std::size_t)(file.get_size() - offset), flags, MAP_SHARED, file.get_fd(), offset);
if (map == MAP_FAILED) {
- return tl::make_unexpected(error { fmt::format("cannot mmap file {}: {}",
- file.get_name(), ::strerror(errno)), errno });
-
+ return tl::make_unexpected(error{fmt::format("cannot mmap file {}: {}",
+ file.get_name(), ::strerror(errno)),
+ errno});
}
- return raii_mmaped_file{std::move(file), map, (std::size_t)(file.get_size() - offset)};
+ return raii_mmaped_file{std::move(file), map, (std::size_t)(file.get_size() - offset)};
}
auto raii_mmaped_file::mmap_shared(const char *fname, int open_flags,
@@ -229,7 +232,7 @@ raii_mmaped_file::~raii_mmaped_file()
}
raii_mmaped_file::raii_mmaped_file(raii_mmaped_file &&other) noexcept
- : file(std::move(other.file))
+ : file(std::move(other.file))
{
std::swap(map, other.map);
std::swap(map_size, other.map_size);
@@ -239,7 +242,7 @@ auto raii_file_sink::create(const char *fname, int flags, int perms,
const char *suffix) -> tl::expected<raii_file_sink, error>
{
if (!fname || !suffix) {
- return tl::make_unexpected(error {"cannot create file; filename is nullptr", EINVAL, error_category::CRITICAL});
+ return tl::make_unexpected(error{"cannot create file; filename is nullptr", EINVAL, error_category::CRITICAL});
}
auto tmp_fname = fmt::format("{}.{}", fname, suffix);
@@ -277,34 +280,37 @@ raii_file_sink::~raii_file_sink()
}
raii_file_sink::raii_file_sink(raii_locked_file &&_file, const char *_output, std::string &&_tmp_fname)
- : file(std::move(_file)), output_fname(_output), tmp_fname(std::move(_tmp_fname)), success(false)
+ : file(std::move(_file)), output_fname(_output), tmp_fname(std::move(_tmp_fname)), success(false)
{
}
raii_file_sink::raii_file_sink(raii_file_sink &&other) noexcept
- : file(std::move(other.file)),
- output_fname(std::move(other.output_fname)),
- tmp_fname(std::move(other.tmp_fname)),
- success(other.success)
+ : file(std::move(other.file)),
+ output_fname(std::move(other.output_fname)),
+ tmp_fname(std::move(other.tmp_fname)),
+ success(other.success)
{
}
namespace tests {
template<class T>
-static auto test_read_file(const T& f) {
+static auto test_read_file(const T &f)
+{
auto fd = f.get_fd();
- (void)::lseek(fd, 0, SEEK_SET);
- std::string buf('\0', (std::size_t)f.get_size());
+ (void) ::lseek(fd, 0, SEEK_SET);
+ std::string buf('\0', (std::size_t) f.get_size());
::read(fd, buf.data(), buf.size());
return buf;
}
template<class T>
-static auto test_write_file(const T& f, const std::string_view &buf) {
+static auto test_write_file(const T &f, const std::string_view &buf)
+{
auto fd = f.get_fd();
- (void)::lseek(fd, 0, SEEK_SET);
+ (void) ::lseek(fd, 0, SEEK_SET);
return ::write(fd, buf.data(), buf.size());
}
-auto random_fname(std::string_view extension) {
+auto random_fname(std::string_view extension)
+{
const auto *tmpdir = getenv("TMPDIR");
if (tmpdir == nullptr) {
tmpdir = G_DIR_SEPARATOR_S "tmp";
@@ -315,7 +321,7 @@ auto random_fname(std::string_view extension) {
unsigned char hexbuf[32];
rspamd_random_hex(hexbuf, sizeof(hexbuf));
- out_fname.append((const char *)hexbuf, sizeof(hexbuf));
+ out_fname.append((const char *) hexbuf, sizeof(hexbuf));
if (!extension.empty()) {
out_fname.append(".");
out_fname.append(extension);
@@ -323,123 +329,129 @@ auto random_fname(std::string_view extension) {
return out_fname;
}
-TEST_SUITE("loked files utils") {
+TEST_SUITE("loked files utils")
+{
-TEST_CASE("create and delete file") {
- auto fname = random_fname("tmp");
+ TEST_CASE("create and delete file")
{
- auto raii_locked_file = raii_locked_file::create_temp(fname.c_str(), O_RDONLY, 00600);
- CHECK(raii_locked_file.has_value());
- CHECK(raii_locked_file.value().get_extension() == "tmp");
- CHECK(::access(fname.c_str(), R_OK) == 0);
- }
- // File must be deleted after this call
- auto ret = ::access(fname.c_str(), R_OK);
- auto serrno = errno;
- CHECK(ret == -1);
- CHECK(serrno == ENOENT);
- // Create one more time
+ auto fname = random_fname("tmp");
+ {
+ auto raii_locked_file = raii_locked_file::create_temp(fname.c_str(), O_RDONLY, 00600);
+ CHECK(raii_locked_file.has_value());
+ CHECK(raii_locked_file.value().get_extension() == "tmp");
+ CHECK(::access(fname.c_str(), R_OK) == 0);
+ }
+ // File must be deleted after this call
+ auto ret = ::access(fname.c_str(), R_OK);
+ auto serrno = errno;
+ CHECK(ret == -1);
+ CHECK(serrno == ENOENT);
+ // Create one more time
+ {
+ auto raii_locked_file = raii_locked_file::create_temp(fname.c_str(), O_RDONLY, 00600);
+ CHECK(raii_locked_file.has_value());
+ CHECK(::access(fname.c_str(), R_OK) == 0);
+ }
+ ret = ::access(fname.c_str(), R_OK);
+ serrno = errno;
+ CHECK(ret == -1);
+ CHECK(serrno == ENOENT);
+ }
+
+ TEST_CASE("check lock")
{
- auto raii_locked_file = raii_locked_file::create_temp(fname.c_str(), O_RDONLY, 00600);
- CHECK(raii_locked_file.has_value());
- CHECK(::access(fname.c_str(), R_OK) == 0);
- }
- ret = ::access(fname.c_str(), R_OK);
- serrno = errno;
- CHECK(ret == -1);
- CHECK(serrno == ENOENT);
-}
+ auto fname = random_fname("");
+ {
+ auto raii_locked_file = raii_locked_file::create_temp(fname.c_str(), O_RDONLY, 00600);
+ CHECK(raii_locked_file.has_value());
+ CHECK(raii_locked_file.value().get_extension() == "");
+ CHECK(::access(fname.c_str(), R_OK) == 0);
+ auto raii_locked_file2 = raii_locked_file::open(fname.c_str(), O_RDONLY);
+ CHECK(!raii_locked_file2.has_value());
+ CHECK(::access(fname.c_str(), R_OK) == 0);
+ }
+ // File must be deleted after this call
+ auto ret = ::access(fname.c_str(), R_OK);
+ auto serrno = errno;
+ CHECK(ret == -1);
+ CHECK(serrno == ENOENT);
+ }
-TEST_CASE("check lock") {
- auto fname = random_fname("");
+ auto get_tmpdir()->std::string
{
- auto raii_locked_file = raii_locked_file::create_temp(fname.c_str(), O_RDONLY, 00600);
- CHECK(raii_locked_file.has_value());
- CHECK(raii_locked_file.value().get_extension() == "");
- CHECK(::access(fname.c_str(), R_OK) == 0);
- auto raii_locked_file2 = raii_locked_file::open(fname.c_str(), O_RDONLY);
- CHECK(!raii_locked_file2.has_value());
- CHECK(::access(fname.c_str(), R_OK) == 0);
- }
- // File must be deleted after this call
- auto ret = ::access(fname.c_str(), R_OK);
- auto serrno = errno;
- CHECK(ret == -1);
- CHECK(serrno == ENOENT);
-}
+ const auto *tmpdir = getenv("TMPDIR");
+ if (tmpdir == nullptr) {
+ tmpdir = G_DIR_SEPARATOR_S "tmp";
+ }
-auto get_tmpdir() -> std::string {
- const auto *tmpdir = getenv("TMPDIR");
- if (tmpdir == nullptr) {
- tmpdir = G_DIR_SEPARATOR_S "tmp";
- }
+ std::size_t sz;
+ std::string mut_fname = tmpdir;
+ rspamd_normalize_path_inplace(mut_fname.data(), mut_fname.size(), &sz);
+ mut_fname.resize(sz);
- std::size_t sz;
- std::string mut_fname = tmpdir;
- rspamd_normalize_path_inplace(mut_fname.data(), mut_fname.size(), &sz);
- mut_fname.resize(sz);
+ if (!mut_fname.ends_with(G_DIR_SEPARATOR)) {
+ mut_fname += G_DIR_SEPARATOR;
+ }
- if (!mut_fname.ends_with(G_DIR_SEPARATOR)) {
- mut_fname += G_DIR_SEPARATOR;
+ return mut_fname;
}
- return mut_fname;
-}
-
-TEST_CASE("tempfile") {
- std::string tmpname;
- const std::string tmpdir{get_tmpdir()};
+ TEST_CASE("tempfile")
{
- auto raii_locked_file = raii_locked_file::mkstemp(std::string(tmpdir + G_DIR_SEPARATOR_S + "doctest-XXXXXXXX").c_str(),
- O_RDONLY, 00600);
- CHECK(raii_locked_file.has_value());
- CHECK(raii_locked_file.value().get_dir() == tmpdir);
- CHECK(access(raii_locked_file.value().get_name().data(), R_OK) == 0);
- auto raii_locked_file2 = raii_locked_file::open(raii_locked_file.value().get_name().data(), O_RDONLY);
- CHECK(!raii_locked_file2.has_value());
- CHECK(access(raii_locked_file.value().get_name().data(), R_OK) == 0);
- tmpname = raii_locked_file.value().get_name();
- }
- // File must be deleted after this call
- auto ret = ::access(tmpname.c_str(), R_OK);
- auto serrno = errno;
- CHECK(ret == -1);
- CHECK(serrno == ENOENT);
-}
+ std::string tmpname;
+ const std::string tmpdir{get_tmpdir()};
+ {
+ auto raii_locked_file = raii_locked_file::mkstemp(std::string(tmpdir + G_DIR_SEPARATOR_S + "doctest-XXXXXXXX").c_str(),
+ O_RDONLY, 00600);
+ CHECK(raii_locked_file.has_value());
+ CHECK(raii_locked_file.value().get_dir() == tmpdir);
+ CHECK(access(raii_locked_file.value().get_name().data(), R_OK) == 0);
+ auto raii_locked_file2 = raii_locked_file::open(raii_locked_file.value().get_name().data(), O_RDONLY);
+ CHECK(!raii_locked_file2.has_value());
+ CHECK(access(raii_locked_file.value().get_name().data(), R_OK) == 0);
+ tmpname = raii_locked_file.value().get_name();
+ }
+ // File must be deleted after this call
+ auto ret = ::access(tmpname.c_str(), R_OK);
+ auto serrno = errno;
+ CHECK(ret == -1);
+ CHECK(serrno == ENOENT);
+ }
-TEST_CASE("mmap") {
- std::string tmpname;
- const std::string tmpdir{get_tmpdir()};
+ TEST_CASE("mmap")
{
- auto raii_file = raii_file::mkstemp(std::string(tmpdir + G_DIR_SEPARATOR_S + "doctest-XXXXXXXX").c_str(),
- O_RDWR|O_CREAT|O_EXCL, 00600);
- CHECK(raii_file.has_value());
- CHECK(raii_file->get_dir() == tmpdir);
- CHECK(access(raii_file->get_name().data(), R_OK) == 0);
- tmpname = std::string{raii_file->get_name()};
- char payload[] = {'1', '2', '3'};
- CHECK(write(raii_file->get_fd(), payload, sizeof(payload)) == sizeof(payload));
- auto mmapped_file1 = raii_mmaped_file::mmap_shared(std::move(raii_file.value()), PROT_READ|PROT_WRITE);
- CHECK(mmapped_file1.has_value());
- CHECK(!raii_file->is_valid());
- CHECK(mmapped_file1->get_size() == sizeof(payload));
- CHECK(memcmp(mmapped_file1->get_map(), payload, sizeof(payload)) == 0);
- *(char *)mmapped_file1->get_map() = '2';
- auto mmapped_file2 = raii_mmaped_file::mmap_shared(tmpname.c_str(), O_RDONLY, PROT_READ);
- CHECK(mmapped_file2.has_value());
- CHECK(mmapped_file2->get_size() == sizeof(payload));
- CHECK(memcmp(mmapped_file2->get_map(), payload, sizeof(payload)) != 0);
- CHECK(memcmp(mmapped_file2->get_map(), mmapped_file1->get_map(), sizeof(payload)) == 0);
- }
- // File must be deleted after this call
- auto ret = ::access(tmpname.c_str(), R_OK);
- auto serrno = errno;
- CHECK(ret == -1);
- CHECK(serrno == ENOENT);
-}
+ std::string tmpname;
+ const std::string tmpdir{get_tmpdir()};
+ {
+ auto raii_file = raii_file::mkstemp(std::string(tmpdir + G_DIR_SEPARATOR_S + "doctest-XXXXXXXX").c_str(),
+ O_RDWR | O_CREAT | O_EXCL, 00600);
+ CHECK(raii_file.has_value());
+ CHECK(raii_file->get_dir() == tmpdir);
+ CHECK(access(raii_file->get_name().data(), R_OK) == 0);
+ tmpname = std::string{raii_file->get_name()};
+ char payload[] = {'1', '2', '3'};
+ CHECK(write(raii_file->get_fd(), payload, sizeof(payload)) == sizeof(payload));
+ auto mmapped_file1 = raii_mmaped_file::mmap_shared(std::move(raii_file.value()), PROT_READ | PROT_WRITE);
+ CHECK(mmapped_file1.has_value());
+ CHECK(!raii_file->is_valid());
+ CHECK(mmapped_file1->get_size() == sizeof(payload));
+ CHECK(memcmp(mmapped_file1->get_map(), payload, sizeof(payload)) == 0);
+ *(char *) mmapped_file1->get_map() = '2';
+ auto mmapped_file2 = raii_mmaped_file::mmap_shared(tmpname.c_str(), O_RDONLY, PROT_READ);
+ CHECK(mmapped_file2.has_value());
+ CHECK(mmapped_file2->get_size() == sizeof(payload));
+ CHECK(memcmp(mmapped_file2->get_map(), payload, sizeof(payload)) != 0);
+ CHECK(memcmp(mmapped_file2->get_map(), mmapped_file1->get_map(), sizeof(payload)) == 0);
+ }
+ // File must be deleted after this call
+ auto ret = ::access(tmpname.c_str(), R_OK);
+ auto serrno = errno;
+ CHECK(ret == -1);
+ CHECK(serrno == ENOENT);
+ }
-} // TEST_SUITE
+}// TEST_SUITE
-} // namespace tests
+}// namespace tests
-} // namespace rspamd::util
+}// namespace rspamd::util
diff --git a/src/libutil/cxx/file_util.hxx b/src/libutil/cxx/file_util.hxx
index e712fcb15..a0c624726 100644
--- a/src/libutil/cxx/file_util.hxx
+++ b/src/libutil/cxx/file_util.hxx
@@ -37,23 +37,28 @@ public:
static auto create_temp(const char *fname, int flags, int perms) -> tl::expected<raii_file, error>;
static auto mkstemp(const char *pattern, int flags, int perms) -> tl::expected<raii_file, error>;
- auto get_fd() const -> int {
+ auto get_fd() const -> int
+ {
return fd;
}
- auto get_stat() const -> const struct stat& {
+ auto get_stat() const -> const struct stat &
+ {
return st;
};
- auto get_size() const -> std::size_t {
+ auto get_size() const -> std::size_t
+ {
return st.st_size;
};
- auto get_name() const -> std::string_view {
+ auto get_name() const -> std::string_view
+ {
return std::string_view{fname};
}
- auto get_dir() const -> std::string_view {
+ auto get_dir() const -> std::string_view
+ {
auto sep_pos = fname.rfind(G_DIR_SEPARATOR);
if (sep_pos == std::string::npos) {
@@ -61,13 +66,14 @@ public:
}
while (sep_pos >= 1 && fname[sep_pos - 1] == G_DIR_SEPARATOR) {
- sep_pos --;
+ sep_pos--;
}
return std::string_view{fname.c_str(), sep_pos + 1};
}
- auto get_extension() const -> std::string_view {
+ auto get_extension() const -> std::string_view
+ {
auto sep_pos = fname.rfind(G_DIR_SEPARATOR);
if (sep_pos == std::string::npos) {
@@ -85,7 +91,8 @@ public:
}
}
- raii_file& operator=(raii_file &&other) noexcept {
+ raii_file &operator=(raii_file &&other) noexcept
+ {
std::swap(fd, other.fd);
std::swap(temp, other.temp);
std::swap(fname, other.fname);
@@ -94,7 +101,8 @@ public:
return *this;
}
- raii_file(raii_file &&other) noexcept {
+ raii_file(raii_file &&other) noexcept
+ {
*this = std::move(other);
}
@@ -102,7 +110,8 @@ public:
* Prevent file from being deleted
* @return
*/
- auto make_immortal() noexcept {
+ auto make_immortal() noexcept
+ {
temp = false;
}
@@ -112,14 +121,16 @@ public:
*/
auto update_stat() noexcept -> bool;
- auto is_valid() noexcept -> bool {
+ auto is_valid() noexcept -> bool
+ {
return fd != -1;
}
/* Do not allow copy/default ctor */
- const raii_file& operator=(const raii_file &other) = delete;
+ const raii_file &operator=(const raii_file &other) = delete;
raii_file() = delete;
raii_file(const raii_file &other) = delete;
+
protected:
int fd = -1;
bool temp;
@@ -136,28 +147,32 @@ struct raii_locked_file final : public raii_file {
public:
~raii_locked_file() noexcept override;
- static auto open(const char *fname, int flags) -> tl::expected<raii_locked_file, error> {
+ static auto open(const char *fname, int flags) -> tl::expected<raii_locked_file, error>
+ {
auto locked = raii_file::open(fname, flags).and_then([]<class T>(T &&file) {
return lock_raii_file(std::forward<T>(file));
});
return locked;
}
- static auto create(const char *fname, int flags, int perms) -> tl::expected<raii_locked_file, error> {
+ static auto create(const char *fname, int flags, int perms) -> tl::expected<raii_locked_file, error>
+ {
auto locked = raii_file::create(fname, flags, perms).and_then([]<class T>(T &&file) {
return lock_raii_file(std::forward<T>(file));
});
return locked;
}
- static auto create_temp(const char *fname, int flags, int perms) -> tl::expected<raii_locked_file, error> {
+ static auto create_temp(const char *fname, int flags, int perms) -> tl::expected<raii_locked_file, error>
+ {
auto locked = raii_file::create_temp(fname, flags, perms).and_then([]<class T>(T &&file) {
return lock_raii_file(std::forward<T>(file));
});
return locked;
}
- static auto mkstemp(const char *pattern, int flags, int perms) -> tl::expected<raii_locked_file, error> {
+ static auto mkstemp(const char *pattern, int flags, int perms) -> tl::expected<raii_locked_file, error>
+ {
auto locked = raii_file::mkstemp(pattern, flags, perms).and_then([]<class T>(T &&file) {
return lock_raii_file(std::forward<T>(file));
});
@@ -165,7 +180,8 @@ public:
return locked;
}
- raii_locked_file& operator=(raii_locked_file &&other) noexcept {
+ raii_locked_file &operator=(raii_locked_file &&other) noexcept
+ {
std::swap(fd, other.fd);
std::swap(temp, other.temp);
std::swap(fname, other.fname);
@@ -180,15 +196,25 @@ public:
*/
auto unlock() -> raii_file;
- raii_locked_file(raii_locked_file &&other) noexcept : raii_file(static_cast<raii_file &&>(std::move(other))) {}
+ raii_locked_file(raii_locked_file &&other) noexcept
+ : raii_file(static_cast<raii_file &&>(std::move(other)))
+ {
+ }
/* Do not allow copy/default ctor */
- const raii_locked_file& operator=(const raii_locked_file &other) = delete;
+ const raii_locked_file &operator=(const raii_locked_file &other) = delete;
raii_locked_file() = delete;
raii_locked_file(const raii_locked_file &other) = delete;
+
private:
static auto lock_raii_file(raii_file &&unlocked) -> tl::expected<raii_locked_file, error>;
- raii_locked_file(raii_file &&other) noexcept : raii_file(std::move(other)) {}
- explicit raii_locked_file(const char *fname, int fd, bool temp) : raii_file(fname, fd, temp) {}
+ raii_locked_file(raii_file &&other) noexcept
+ : raii_file(std::move(other))
+ {
+ }
+ explicit raii_locked_file(const char *fname, int fd, bool temp)
+ : raii_file(fname, fd, temp)
+ {
+ }
};
/**
@@ -199,18 +225,29 @@ struct raii_mmaped_file final {
static auto mmap_shared(raii_file &&file, int flags, std::int64_t offset = 0) -> tl::expected<raii_mmaped_file, error>;
static auto mmap_shared(const char *fname, int open_flags, int mmap_flags, std::int64_t offset = 0) -> tl::expected<raii_mmaped_file, error>;
// Returns a constant pointer to the underlying map
- auto get_map() const -> void* {return map;}
- auto get_file() const -> const raii_file& { return file; }
+ auto get_map() const -> void *
+ {
+ return map;
+ }
+ auto get_file() const -> const raii_file &
+ {
+ return file;
+ }
// Passes the ownership of the mmaped memory to the callee
- auto steal_map() -> std::tuple<void *, std::size_t> {
+ auto steal_map() -> std::tuple<void *, std::size_t>
+ {
auto ret = std::make_tuple(this->map, map_size);
this->map = nullptr;
return ret;
}
- auto get_size() const -> std::size_t { return file.get_stat().st_size; }
+ auto get_size() const -> std::size_t
+ {
+ return file.get_stat().st_size;
+ }
- raii_mmaped_file& operator=(raii_mmaped_file &&other) noexcept {
+ raii_mmaped_file &operator=(raii_mmaped_file &&other) noexcept
+ {
std::swap(map, other.map);
std::swap(map_size, other.map_size);
file = std::move(other.file);
@@ -221,9 +258,10 @@ struct raii_mmaped_file final {
raii_mmaped_file(raii_mmaped_file &&other) noexcept;
/* Do not allow copy/default ctor */
- const raii_mmaped_file& operator=(const raii_mmaped_file &other) = delete;
+ const raii_mmaped_file &operator=(const raii_mmaped_file &other) = delete;
raii_mmaped_file() = delete;
raii_mmaped_file(const raii_mmaped_file &other) = delete;
+
private:
/* Is intended to be used with map_shared */
explicit raii_mmaped_file(raii_file &&_file, void *_map, std::size_t sz);
@@ -248,9 +286,10 @@ struct raii_file_sink final {
raii_file_sink(raii_file_sink &&other) noexcept;
/* Do not allow copy/default ctor */
- const raii_file_sink& operator=(const raii_file_sink &other) = delete;
+ const raii_file_sink &operator=(const raii_file_sink &other) = delete;
raii_file_sink() = delete;
raii_file_sink(const raii_file_sink &other) = delete;
+
private:
explicit raii_file_sink(raii_locked_file &&_file, const char *_output, std::string &&_tmp_fname);
raii_locked_file file;
@@ -259,6 +298,6 @@ private:
bool success;
};
-}
+}// namespace rspamd::util
-#endif //RSPAMD_FILE_UTIL_HXX
+#endif//RSPAMD_FILE_UTIL_HXX
diff --git a/src/libutil/cxx/hash_util.hxx b/src/libutil/cxx/hash_util.hxx
index 86f094083..972165850 100644
--- a/src/libutil/cxx/hash_util.hxx
+++ b/src/libutil/cxx/hash_util.hxx
@@ -30,22 +30,28 @@ namespace rspamd {
template<typename T>
struct smart_ptr_equal {
using is_transparent = void; /* We want to find values in a set of shared_ptr by reference */
- auto operator()(const std::shared_ptr<T> &a, const std::shared_ptr<T> &b) const {
+ auto operator()(const std::shared_ptr<T> &a, const std::shared_ptr<T> &b) const
+ {
return (*a) == (*b);
}
- auto operator()(const std::shared_ptr<T> &a, const T &b) const {
+ auto operator()(const std::shared_ptr<T> &a, const T &b) const
+ {
return (*a) == b;
}
- auto operator()(const T &a, const std::shared_ptr<T> &b) const {
+ auto operator()(const T &a, const std::shared_ptr<T> &b) const
+ {
return a == (*b);
}
- auto operator()(const std::unique_ptr<T> &a, const std::unique_ptr<T> &b) const {
+ auto operator()(const std::unique_ptr<T> &a, const std::unique_ptr<T> &b) const
+ {
return (*a) == (*b);
}
- auto operator()(const std::unique_ptr<T> &a, const T &b) const {
+ auto operator()(const std::unique_ptr<T> &a, const T &b) const
+ {
return (*a) == b;
}
- auto operator()(const T &a, const std::unique_ptr<T> &b) const {
+ auto operator()(const T &a, const std::unique_ptr<T> &b) const
+ {
return a == (*b);
}
};
@@ -53,13 +59,16 @@ struct smart_ptr_equal {
template<typename T>
struct smart_ptr_hash {
using is_transparent = void; /* We want to find values in a set of shared_ptr by reference */
- auto operator()(const std::shared_ptr<T> &a) const {
+ auto operator()(const std::shared_ptr<T> &a) const
+ {
return std::hash<T>()(*a);
}
- auto operator()(const std::unique_ptr<T> &a) const {
+ auto operator()(const std::unique_ptr<T> &a) const
+ {
return std::hash<T>()(*a);
}
- auto operator()(const T &a) const {
+ auto operator()(const T &a) const
+ {
return std::hash<T>()(a);
}
};
@@ -67,13 +76,16 @@ struct smart_ptr_hash {
/* Enable lookup by string view */
struct smart_str_equal {
using is_transparent = void;
- auto operator()(const std::string &a, const std::string &b) const {
+ auto operator()(const std::string &a, const std::string &b) const
+ {
return a == b;
}
- auto operator()(const std::string_view &a, const std::string &b) const {
+ auto operator()(const std::string_view &a, const std::string &b) const
+ {
return a == b;
}
- auto operator()(const std::string &a, const std::string_view &b) const {
+ auto operator()(const std::string &a, const std::string_view &b) const
+ {
return a == b;
}
};
@@ -81,14 +93,16 @@ struct smart_str_equal {
struct smart_str_hash {
using is_transparent = void;
using is_avalanching = typename ankerl::unordered_dense::hash<std::string_view>::is_avalanching;
- auto operator()(const std::string &a) const {
+ auto operator()(const std::string &a) const
+ {
return ankerl::unordered_dense::hash<std::string>()(a);
}
- auto operator()(const std::string_view &a) const {
+ auto operator()(const std::string_view &a) const
+ {
return ankerl::unordered_dense::hash<std::string_view>()(a);
}
};
-}
+}// namespace rspamd
-#endif //RSPAMD_HASH_UTIL_HXX
+#endif//RSPAMD_HASH_UTIL_HXX
diff --git a/src/libutil/cxx/local_shared_ptr.hxx b/src/libutil/cxx/local_shared_ptr.hxx
index 233c5df1e..78ed5ba92 100644
--- a/src/libutil/cxx/local_shared_ptr.hxx
+++ b/src/libutil/cxx/local_shared_ptr.hxx
@@ -21,8 +21,8 @@
#include <memory>
#include <algorithm> // for std::swap
-#include <cstddef> // for std::size_t
-#include <functional> // for std::less
+#include <cstddef> // for std::size_t
+#include <functional>// for std::less
/*
* Smart pointers with no atomic refcounts to speed up Rspamd which is
@@ -36,51 +36,64 @@ class ref_cnt {
public:
using refcount_t = int;
- constexpr auto add_shared() -> refcount_t {
+ constexpr auto add_shared() -> refcount_t
+ {
return ++ref_shared;
}
- constexpr auto add_weak() -> refcount_t {
+ constexpr auto add_weak() -> refcount_t
+ {
return ++ref_weak;
}
- constexpr auto release_shared() -> refcount_t {
+ constexpr auto release_shared() -> refcount_t
+ {
return --ref_shared;
}
- constexpr auto release_weak() -> refcount_t {
+ constexpr auto release_weak() -> refcount_t
+ {
return --ref_weak;
}
- constexpr auto shared_count() const -> refcount_t {
+ constexpr auto shared_count() const -> refcount_t
+ {
return ref_shared;
}
- constexpr auto weak_count() const -> refcount_t {
+ constexpr auto weak_count() const -> refcount_t
+ {
return ref_weak;
}
- virtual ~ref_cnt() {}
+ virtual ~ref_cnt()
+ {
+ }
virtual void dispose() = 0;
+
private:
refcount_t ref_weak = 0;
refcount_t ref_shared = 1;
};
-template <class T>
+template<class T>
class obj_and_refcnt : public ref_cnt {
private:
typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type storage_type;
storage_type storage;
bool initialized;
- virtual void dispose() override {
+ virtual void dispose() override
+ {
if (initialized) {
T *p = reinterpret_cast<T *>(&storage);
p->~T();
initialized = false;
}
}
+
public:
- template <typename... Args>
- explicit obj_and_refcnt(Args&&... args) : initialized(true)
+ template<typename... Args>
+ explicit obj_and_refcnt(Args &&...args)
+ : initialized(true)
{
- new(&storage) T(std::forward<Args>(args)...);
+ new (&storage) T(std::forward<Args>(args)...);
}
- auto get(void) -> T* {
+ auto get(void) -> T *
+ {
if (initialized) {
return reinterpret_cast<T *>(&storage);
}
@@ -90,26 +103,32 @@ public:
virtual ~obj_and_refcnt() = default;
};
-template <class T, class D = typename std::default_delete<T>>
+template<class T, class D = typename std::default_delete<T>>
class ptr_and_refcnt : public ref_cnt {
private:
- T* ptr;
+ T *ptr;
D deleter;
- virtual void dispose() override {
+ virtual void dispose() override
+ {
deleter(ptr);
ptr = nullptr;
}
+
public:
- explicit ptr_and_refcnt(T *_ptr, D &&d = std::default_delete<T>()) : ptr(_ptr),
- deleter(std::move(d)) {}
+ explicit ptr_and_refcnt(T *_ptr, D &&d = std::default_delete<T>())
+ : ptr(_ptr),
+ deleter(std::move(d))
+ {
+ }
virtual ~ptr_and_refcnt() = default;
};
-}
+}// namespace detail
-template <class T> class local_weak_ptr;
+template<class T>
+class local_weak_ptr;
-template <class T>
+template<class T>
class local_shared_ptr {
public:
typedef T element_type;
@@ -117,38 +136,53 @@ public:
// Simplified comparing to libc++, no custom deleter and no rebind here
// constructors:
- constexpr local_shared_ptr() noexcept : px(nullptr), cnt(nullptr) {}
+ constexpr local_shared_ptr() noexcept
+ : px(nullptr), cnt(nullptr)
+ {
+ }
template<class Y, typename std::enable_if<
- std::is_convertible<Y*, element_type*>::value, bool>::type = true>
- explicit local_shared_ptr(Y* p) : px(p), cnt(new detail::ptr_and_refcnt(p))
+ std::is_convertible<Y *, element_type *>::value, bool>::type = true>
+ explicit local_shared_ptr(Y *p)
+ : px(p), cnt(new detail::ptr_and_refcnt(p))
{
}
// custom deleter
- template<class Y, class D, typename std::enable_if<
- std::is_convertible<Y*, element_type*>::value, bool>::type = true>
- explicit local_shared_ptr(Y* p, D &&d) : px(p), cnt(new detail::ptr_and_refcnt<Y, D>(p, std::forward<D>(d)))
+ template<class Y, class D, typename std::enable_if<std::is_convertible<Y *, element_type *>::value, bool>::type = true>
+ explicit local_shared_ptr(Y *p, D &&d)
+ : px(p), cnt(new detail::ptr_and_refcnt<Y, D>(p, std::forward<D>(d)))
{
}
- local_shared_ptr(const local_shared_ptr& r) noexcept : px(r.px), cnt(r.cnt) {
+ local_shared_ptr(const local_shared_ptr &r) noexcept
+ : px(r.px), cnt(r.cnt)
+ {
if (cnt) {
cnt->add_shared();
}
}
- local_shared_ptr(local_shared_ptr&& r) noexcept : px(r.px), cnt(r.cnt) {
+ local_shared_ptr(local_shared_ptr &&r) noexcept
+ : px(r.px), cnt(r.cnt)
+ {
r.px = nullptr;
r.cnt = nullptr;
}
- template<class Y> explicit local_shared_ptr(const local_weak_ptr<Y>& r) : px(r.px), cnt(r.cnt) {
+ template<class Y>
+ explicit local_shared_ptr(const local_weak_ptr<Y> &r)
+ : px(r.px), cnt(r.cnt)
+ {
if (cnt) {
cnt->add_shared();
}
}
- local_shared_ptr(std::nullptr_t) : local_shared_ptr() { }
+ local_shared_ptr(std::nullptr_t)
+ : local_shared_ptr()
+ {
+ }
- ~local_shared_ptr() {
+ ~local_shared_ptr()
+ {
if (cnt) {
if (cnt->release_shared() <= 0) {
cnt->dispose();
@@ -161,73 +195,85 @@ public:
}
// assignment:
- local_shared_ptr& operator=(const local_shared_ptr& r) noexcept {
+ local_shared_ptr &operator=(const local_shared_ptr &r) noexcept
+ {
local_shared_ptr(r).swap(*this);
return *this;
}
- local_shared_ptr& operator=(local_shared_ptr&& r) noexcept {
+ local_shared_ptr &operator=(local_shared_ptr &&r) noexcept
+ {
local_shared_ptr(std::move(r)).swap(*this);
return *this;
}
// Mutators
- void swap(local_shared_ptr& r) noexcept {
+ void swap(local_shared_ptr &r) noexcept
+ {
std::swap(this->cnt, r.cnt);
std::swap(this->px, r.px);
}
- void reset() noexcept {
+ void reset() noexcept
+ {
local_shared_ptr().swap(*this);
}
// Observers:
- T* get() const noexcept {
+ T *get() const noexcept
+ {
return px;
}
- T& operator*() const noexcept {
+ T &operator*() const noexcept
+ {
return *px;
}
- T* operator->() const noexcept {
+ T *operator->() const noexcept
+ {
return px;
}
- long use_count() const noexcept {
+ long use_count() const noexcept
+ {
if (cnt) {
return cnt->shared_count();
}
return 0;
}
- bool unique() const noexcept {
+ bool unique() const noexcept
+ {
return use_count() == 1;
}
- explicit operator bool() const noexcept {
+ explicit operator bool() const noexcept
+ {
return px != nullptr;
}
template<class Y, typename std::enable_if<
- std::is_convertible<Y*, element_type*>::value, bool>::type = true>
- auto operator ==(const local_shared_ptr<Y> &other) const -> bool {
+ std::is_convertible<Y *, element_type *>::value, bool>::type = true>
+ auto operator==(const local_shared_ptr<Y> &other) const -> bool
+ {
return px == other.px;
}
template<class Y, typename std::enable_if<
- std::is_convertible<Y*, element_type*>::value, bool>::type = true>
- auto operator <(const local_shared_ptr<Y> &other) const -> auto {
+ std::is_convertible<Y *, element_type *>::value, bool>::type = true>
+ auto operator<(const local_shared_ptr<Y> &other) const -> auto
+ {
return *px < *other.px;
}
private:
- T *px; // contained pointer
+ T *px;// contained pointer
detail::ref_cnt *cnt;
- template<class _T, class ... Args>
- friend local_shared_ptr<_T> local_make_shared(Args && ... args);
+ template<class _T, class... Args>
+ friend local_shared_ptr<_T> local_make_shared(Args &&...args);
friend class local_weak_ptr<T>;
};
-template<class T, class ... Args>
-local_shared_ptr<T> local_make_shared(Args && ... args)
+template<class T, class... Args>
+local_shared_ptr<T> local_make_shared(Args &&...args)
{
local_shared_ptr<T> ptr;
auto tmp_object = new detail::obj_and_refcnt<T>(std::forward<Args>(args)...);
@@ -238,27 +284,35 @@ local_shared_ptr<T> local_make_shared(Args && ... args)
}
template<class T>
-class local_weak_ptr
-{
+class local_weak_ptr {
public:
typedef T element_type;
// constructors
- constexpr local_weak_ptr() noexcept : px(nullptr), cnt(nullptr) {}
+ constexpr local_weak_ptr() noexcept
+ : px(nullptr), cnt(nullptr)
+ {
+ }
template<class Y, typename std::enable_if<
- std::is_convertible<Y*, element_type*>::value, bool>::type = true>
- local_weak_ptr(local_shared_ptr<Y> const& r) noexcept : px(r.px),cnt(r.cnt) {
+ std::is_convertible<Y *, element_type *>::value, bool>::type = true>
+ local_weak_ptr(local_shared_ptr<Y> const &r) noexcept
+ : px(r.px), cnt(r.cnt)
+ {
if (cnt) {
cnt->add_weak();
}
}
- local_weak_ptr(local_weak_ptr const& r) noexcept : px(r.px),cnt(r.cnt) {
+ local_weak_ptr(local_weak_ptr const &r) noexcept
+ : px(r.px), cnt(r.cnt)
+ {
if (cnt) {
cnt->add_weak();
}
}
- local_weak_ptr(local_weak_ptr && r) noexcept : px(r.px), cnt(r.cnt) {
+ local_weak_ptr(local_weak_ptr &&r) noexcept
+ : px(r.px), cnt(r.cnt)
+ {
r.px = nullptr;
r.cnt = nullptr;
}
@@ -273,43 +327,51 @@ public:
}
// assignment
- local_weak_ptr& operator=(local_weak_ptr const& r) noexcept {
+ local_weak_ptr &operator=(local_weak_ptr const &r) noexcept
+ {
local_weak_ptr(r).swap(*this);
return *this;
}
- local_weak_ptr& operator=(local_shared_ptr<T> const& r) noexcept {
+ local_weak_ptr &operator=(local_shared_ptr<T> const &r) noexcept
+ {
local_weak_ptr(r).swap(*this);
return *this;
}
template<class Y, typename std::enable_if<
- std::is_convertible<Y*, element_type*>::value, bool>::type = true>
- local_weak_ptr& operator=(local_weak_ptr<Y> const& r) noexcept {
+ std::is_convertible<Y *, element_type *>::value, bool>::type = true>
+ local_weak_ptr &operator=(local_weak_ptr<Y> const &r) noexcept
+ {
local_weak_ptr(r).swap(*this);
return *this;
}
- local_weak_ptr& operator=(local_weak_ptr&& r) noexcept {
+ local_weak_ptr &operator=(local_weak_ptr &&r) noexcept
+ {
local_weak_ptr(std::move(r)).swap(*this);
return *this;
}
// modifiers
- void swap(local_weak_ptr& r) noexcept {
+ void swap(local_weak_ptr &r) noexcept
+ {
std::swap(this->cnt, r.cnt);
std::swap(this->px, r.px);
}
- void reset() noexcept {
+ void reset() noexcept
+ {
local_weak_ptr().swap(*this);
}
// observers
- long use_count() const noexcept {
+ long use_count() const noexcept
+ {
if (cnt) {
return cnt->shared_count();
}
return 0;
}
- bool expired() const noexcept {
+ bool expired() const noexcept
+ {
if (cnt) {
return cnt->shared_count() == 0;
}
@@ -317,7 +379,8 @@ public:
return true;
}
- local_shared_ptr<T> lock() const noexcept {
+ local_shared_ptr<T> lock() const noexcept
+ {
local_shared_ptr<T> tmp;
tmp.cnt = cnt;
@@ -328,28 +391,31 @@ public:
return tmp;
}
+
private:
- element_type* px;
+ element_type *px;
detail::ref_cnt *cnt;
};
-}
+}// namespace rspamd
/* Hashing stuff */
namespace std {
-template <class T>
+template<class T>
struct hash<rspamd::local_shared_ptr<T>> {
- inline auto operator()(const rspamd::local_shared_ptr<T> &p) const -> auto {
+ inline auto operator()(const rspamd::local_shared_ptr<T> &p) const -> auto
+ {
if (!p) {
throw std::logic_error("no hash for dangling pointer");
}
return hash<T>()(*p.get());
}
};
-template <class T>
+template<class T>
struct hash<rspamd::local_weak_ptr<T>> {
- inline auto operator()(const rspamd::local_weak_ptr<T> &p) const -> auto {
+ inline auto operator()(const rspamd::local_weak_ptr<T> &p) const -> auto
+ {
if (!p) {
throw std::logic_error("no hash for dangling pointer");
}
@@ -369,6 +435,6 @@ inline void swap(rspamd::local_weak_ptr<T> &x, rspamd::local_weak_ptr<T> &y) noe
x.swap(y);
}
-}
+}// namespace std
-#endif //RSPAMD_LOCAL_SHARED_PTR_HXX
+#endif//RSPAMD_LOCAL_SHARED_PTR_HXX
diff --git a/src/libutil/cxx/utf8_util.cxx b/src/libutil/cxx/utf8_util.cxx
index 8bb709abf..166fe1cfa 100644
--- a/src/libutil/cxx/utf8_util.cxx
+++ b/src/libutil/cxx/utf8_util.cxx
@@ -34,7 +34,7 @@
#include "doctest/doctest.h"
const char *
-rspamd_string_unicode_trim_inplace (const char *str, size_t *len)
+rspamd_string_unicode_trim_inplace(const char *str, size_t *len)
{
const auto *p = str, *end = str + *len;
auto i = 0;
@@ -97,12 +97,12 @@ rspamd_normalise_unicode_inplace(char *start, size_t *len)
int ret = RSPAMD_UNICODE_NORM_NORMAL;
- g_assert (U_SUCCESS (uc_err));
+ g_assert(U_SUCCESS(uc_err));
auto uc_string = icu::UnicodeString::fromUTF8(icu::StringPiece(start, *len));
auto is_normal = nfkc_norm->quickCheck(uc_string, uc_err);
- if (!U_SUCCESS (uc_err)) {
+ if (!U_SUCCESS(uc_err)) {
return RSPAMD_UNICODE_NORM_ERROR;
}
@@ -111,7 +111,7 @@ rspamd_normalise_unicode_inplace(char *start, size_t *len)
icu::StringCharacterIterator it{input};
size_t i = 0;
- while(it.hasNext()) {
+ while (it.hasNext()) {
/* libicu is very 'special' if it comes to 'safe' macro */
if (i >= *len) {
ret |= RSPAMD_UNICODE_NORM_ERROR;
@@ -129,7 +129,7 @@ rspamd_normalise_unicode_inplace(char *start, size_t *len)
if (uc == 0xFFFD) {
ret |= RSPAMD_UNICODE_NORM_UNNORMAL;
}
- U8_APPEND((uint8_t*)start, i, *len, uc, err);
+ U8_APPEND((uint8_t *) start, i, *len, uc, err);
if (err) {
ret |= RSPAMD_UNICODE_NORM_ERROR;
@@ -147,7 +147,7 @@ rspamd_normalise_unicode_inplace(char *start, size_t *len)
auto normalised = nfkc_norm->normalize(uc_string, uc_err);
- if (!U_SUCCESS (uc_err)) {
+ if (!U_SUCCESS(uc_err)) {
return RSPAMD_UNICODE_NORM_ERROR;
}
@@ -160,7 +160,7 @@ rspamd_normalise_unicode_inplace(char *start, size_t *len)
return static_cast<enum rspamd_utf8_normalise_result>(ret);
}
-gchar*
+gchar *
rspamd_utf8_transliterate(const gchar *start, gsize len, gsize *target_len)
{
UErrorCode uc_err = U_ZERO_ERROR;
@@ -177,14 +177,13 @@ rspamd_utf8_transliterate(const gchar *start, gsize len, gsize *target_len)
":: Latin-ASCII;"
":: Lower();"
":: NULL;"
- "[:Space Separator:] > ' '"
- };
+ "[:Space Separator:] > ' '"};
transliterator = std::unique_ptr<icu::Transliterator>(
icu::Transliterator::createFromRules("RspamdTranslit", rules, UTRANS_FORWARD, parse_err, uc_err));
if (U_FAILURE(uc_err) || !transliterator) {
auto context = icu::UnicodeString(parse_err.postContext, sizeof(parse_err.preContext) / sizeof(UChar));
- g_error ("fatal error: cannot init libicu transliteration engine: %s, line: %d, offset: %d",
+ g_error("fatal error: cannot init libicu transliteration engine: %s, line: %d, offset: %d",
u_errorName(uc_err), parse_err.line, parse_err.offset);
abort();
}
@@ -195,7 +194,7 @@ rspamd_utf8_transliterate(const gchar *start, gsize len, gsize *target_len)
// We assume that all characters are now ascii
auto dest_len = uc_string.length();
- gchar *dest = (gchar *)g_malloc(dest_len + 1);
+ gchar *dest = (gchar *) g_malloc(dest_len + 1);
auto sink = icu::CheckedArrayByteSink(dest, dest_len);
uc_string.toUTF8(sink);
@@ -206,13 +205,14 @@ rspamd_utf8_transliterate(const gchar *start, gsize len, gsize *target_len)
}
struct rspamd_icu_collate_storage {
- icu::Collator* collator = nullptr;
- rspamd_icu_collate_storage() {
+ icu::Collator *collator = nullptr;
+ rspamd_icu_collate_storage()
+ {
UErrorCode uc_err = U_ZERO_ERROR;
collator = icu::Collator::createInstance(icu::Locale::getEnglish(), uc_err);
if (U_FAILURE(uc_err) || collator == nullptr) {
- g_error ("fatal error: cannot init libicu collation engine: %s",
+ g_error("fatal error: cannot init libicu collation engine: %s",
u_errorName(uc_err));
abort();
}
@@ -220,7 +220,8 @@ struct rspamd_icu_collate_storage {
collator->setStrength(icu::Collator::PRIMARY);
}
- ~rspamd_icu_collate_storage() {
+ ~rspamd_icu_collate_storage()
+ {
if (collator) {
delete collator;
}
@@ -229,8 +230,7 @@ struct rspamd_icu_collate_storage {
static rspamd_icu_collate_storage collate_storage;
-int
-rspamd_utf8_strcmp_sizes(const char *s1, gsize n1, const char *s2, gsize n2)
+int rspamd_utf8_strcmp_sizes(const char *s1, gsize n1, const char *s2, gsize n2)
{
if (n1 >= std::numeric_limits<int>::max() || n2 >= std::numeric_limits<int>::max()) {
/*
@@ -247,7 +247,7 @@ rspamd_utf8_strcmp_sizes(const char *s1, gsize n1, const char *s2, gsize n2)
UErrorCode success = U_ZERO_ERROR;
auto res = collate_storage.collator->compareUTF8({s1, (int) n1}, {s2, (int) n2},
- success);
+ success);
switch (res) {
case UCOL_EQUAL:
@@ -260,81 +260,101 @@ rspamd_utf8_strcmp_sizes(const char *s1, gsize n1, const char *s2, gsize n2)
}
}
-int
-rspamd_utf8_strcmp(const char *s1, const char *s2, gsize n)
+int rspamd_utf8_strcmp(const char *s1, const char *s2, gsize n)
{
return rspamd_utf8_strcmp_sizes(s1, n, s2, n);
}
-TEST_SUITE("utf8 utils") {
-TEST_CASE("utf8 normalise") {
- std::tuple<const char *, const char *, int> cases[] = {
+TEST_SUITE("utf8 utils")
+{
+ TEST_CASE("utf8 normalise")
+ {
+ std::tuple<const char *, const char *, int> cases[] = {
{"abc", "abc", RSPAMD_UNICODE_NORM_NORMAL},
{"тест", "тест", RSPAMD_UNICODE_NORM_NORMAL},
/* Zero width spaces */
- {"\xE2\x80\x8B""те""\xE2\x80\x8B""ст", "тест", RSPAMD_UNICODE_NORM_ZERO_SPACES},
+ {"\xE2\x80\x8B"
+ "те"
+ "\xE2\x80\x8B"
+ "ст",
+ "тест", RSPAMD_UNICODE_NORM_ZERO_SPACES},
/* Special case of diacritic */
{"13_\u0020\u0308\u0301\u038e\u03ab", "13_ ̈́ΎΫ", RSPAMD_UNICODE_NORM_UNNORMAL},
// String containing a non-joiner character
- { "س\u200Cت", "ست", RSPAMD_UNICODE_NORM_ZERO_SPACES },
+ {"س\u200Cت", "ست", RSPAMD_UNICODE_NORM_ZERO_SPACES},
// String containing a soft hyphen
- { "in\u00ADter\u00ADest\u00ADing", "interesting", RSPAMD_UNICODE_NORM_ZERO_SPACES },
+ {"in\u00ADter\u00ADest\u00ADing", "interesting", RSPAMD_UNICODE_NORM_ZERO_SPACES},
// String with ligature
- { "fish", "fish", RSPAMD_UNICODE_NORM_UNNORMAL },
+ {"fish", "fish", RSPAMD_UNICODE_NORM_UNNORMAL},
// String with accented characters and zero-width spaces
- { "café\u200Blatté\u200C", "cafélatté", RSPAMD_UNICODE_NORM_ZERO_SPACES },
+ {"café\u200Blatté\u200C", "cafélatté", RSPAMD_UNICODE_NORM_ZERO_SPACES},
/* Same with zw spaces */
{"13\u200C_\u0020\u0308\u0301\u038e\u03ab", "13_ ̈́ΎΫ",
- RSPAMD_UNICODE_NORM_UNNORMAL|RSPAMD_UNICODE_NORM_ZERO_SPACES},
+ RSPAMD_UNICODE_NORM_UNNORMAL | RSPAMD_UNICODE_NORM_ZERO_SPACES},
/* Buffer overflow case */
- {"u\xC2\xC2\xC2\xC2\xC2\xC2""abcdef""abcdef", "u\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD",
- RSPAMD_UNICODE_NORM_UNNORMAL|RSPAMD_UNICODE_NORM_ERROR},
+ {"u\xC2\xC2\xC2\xC2\xC2\xC2"
+ "abcdef"
+ "abcdef",
+ "u\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD",
+ RSPAMD_UNICODE_NORM_UNNORMAL | RSPAMD_UNICODE_NORM_ERROR},
// String with a mix of special characters, ligatures, and zero-width spaces
- { "fish\u200Bcafé\u200C\u200Dlatté\u200D\u00AD", "fishcafé\u200Dlatté\u200D", RSPAMD_UNICODE_NORM_UNNORMAL | RSPAMD_UNICODE_NORM_ZERO_SPACES },
+ {"fish\u200Bcafé\u200C\u200Dlatté\u200D\u00AD", "fishcafé\u200Dlatté\u200D", RSPAMD_UNICODE_NORM_UNNORMAL | RSPAMD_UNICODE_NORM_ZERO_SPACES},
// Empty string
- { "", "", RSPAMD_UNICODE_NORM_NORMAL},
- };
+ {"", "", RSPAMD_UNICODE_NORM_NORMAL},
+ };
- for (const auto &c : cases) {
- std::string cpy{std::get<0>(c)};
- auto ns = cpy.size();
- auto res = rspamd_normalise_unicode_inplace(cpy.data(), &ns);
- cpy.resize(ns);
- CHECK(cpy == std::string(std::get<1>(c)));
- CHECK(res == std::get<2>(c));
+ for (const auto &c: cases) {
+ std::string cpy{std::get<0>(c)};
+ auto ns = cpy.size();
+ auto res = rspamd_normalise_unicode_inplace(cpy.data(), &ns);
+ cpy.resize(ns);
+ CHECK(cpy == std::string(std::get<1>(c)));
+ CHECK(res == std::get<2>(c));
+ }
}
-}
-TEST_CASE("utf8 trim") {
- std::pair<const char *, const char *> cases[] = {
- {" \u200B""abc ", "abc"},
- {" ", ""},
+ TEST_CASE("utf8 trim")
+ {
+ std::pair<const char *, const char *> cases[] = {
+ {" \u200B"
+ "abc ",
+ "abc"},
+ {" ", ""},
{" a", "a"},
{"a ", "a"},
- {"a a", "a a"},
- {"abc", "abc"},
+ {"a a", "a a"},
+ {"abc", "abc"},
{"a ", "a"},
{" abc ", "abc"},
{" abc ", "abc"},
- {" \xE2\x80\x8B""a\xE2\x80\x8B""bc ", "a\xE2\x80\x8B""bc"},
- {" \xE2\x80\x8B""abc\xE2\x80\x8B ", "abc"},
- {" \xE2\x80\x8B""abc \xE2\x80\x8B ", "abc"},
- };
+ {" \xE2\x80\x8B"
+ "a\xE2\x80\x8B"
+ "bc ",
+ "a\xE2\x80\x8B"
+ "bc"},
+ {" \xE2\x80\x8B"
+ "abc\xE2\x80\x8B ",
+ "abc"},
+ {" \xE2\x80\x8B"
+ "abc \xE2\x80\x8B ",
+ "abc"},
+ };
- for (const auto &c : cases) {
- std::string cpy{c.first};
- auto ns = cpy.size();
- auto *nstart = rspamd_string_unicode_trim_inplace(cpy.data(), &ns);
- std::string res{nstart, ns};
- CHECK(res == std::string{c.second});
+ for (const auto &c: cases) {
+ std::string cpy{c.first};
+ auto ns = cpy.size();
+ auto *nstart = rspamd_string_unicode_trim_inplace(cpy.data(), &ns);
+ std::string res{nstart, ns};
+ CHECK(res == std::string{c.second});
+ }
}
-}
-TEST_CASE("utf8 strcmp") {
- std::tuple<const char *, const char *, int, int> cases[] = {
+ TEST_CASE("utf8 strcmp")
+ {
+ std::tuple<const char *, const char *, int, int> cases[] = {
{"abc", "abc", -1, 0},
- {"", "", -1, 0},
+ {"", "", -1, 0},
{"aBc", "AbC", -1, 0},
{"abc", "ab", 2, 0},
{"теСт", "ТесТ", -1, 0},
@@ -343,52 +363,58 @@ TEST_CASE("utf8 strcmp") {
{"abc", "ABD", -1, -1},
{"\0a\0", "\0a\1", 2, 0},
{"\0a\0", "\0b\1", 3, -1},
- };
+ };
- for (const auto &c : cases) {
- auto [s1, s2, n, expected] = c;
- if (n == -1) {
- n = MIN(strlen(s1), strlen(s2));
- }
- SUBCASE((std::string("test case: ") + s1 + " <=> " + s2).c_str()) {
- auto ret = rspamd_utf8_strcmp(s1, s2, n);
- CHECK(ret == expected);
+ for (const auto &c: cases) {
+ auto [s1, s2, n, expected] = c;
+ if (n == -1) {
+ n = MIN(strlen(s1), strlen(s2));
+ }
+ SUBCASE((std::string("test case: ") + s1 + " <=> " + s2).c_str())
+ {
+ auto ret = rspamd_utf8_strcmp(s1, s2, n);
+ CHECK(ret == expected);
+ }
}
}
-}
-TEST_CASE("transliterate") {
- using namespace std::literals;
- std::tuple<std::string_view, const char *> cases[] = {
- {"abc"sv, "abc"},
- {""sv, ""},
- {"тест"sv, "test"},
- // Diacritic to ascii
- {"Ύ"sv, "y"},
- // Chinese to pinyin
- {"你好"sv, "ni hao"},
- // Japanese to romaji
- {"こんにちは"sv, "konnichiha"},
- // Devanagari to latin
- {"नमस्ते"sv, "namaste"},
- // Arabic to latin
- {"مرحبا"sv, "mrhba"},
- // Remove of punctuation
- {"a.b.c"sv, "abc"},
- // Lowercase
- {"ABC"sv, "abc"},
- // Remove zero-width spaces
- {"\xE2\x80\x8B""abc\xE2\x80\x8B""def"sv, "abcdef"},
- };
+ TEST_CASE("transliterate")
+ {
+ using namespace std::literals;
+ std::tuple<std::string_view, const char *> cases[] = {
+ {"abc"sv, "abc"},
+ {""sv, ""},
+ {"тест"sv, "test"},
+ // Diacritic to ascii
+ {"Ύ"sv, "y"},
+ // Chinese to pinyin
+ {"你好"sv, "ni hao"},
+ // Japanese to romaji
+ {"こんにちは"sv, "konnichiha"},
+ // Devanagari to latin
+ {"नमस्ते"sv, "namaste"},
+ // Arabic to latin
+ {"مرحبا"sv, "mrhba"},
+ // Remove of punctuation
+ {"a.b.c"sv, "abc"},
+ // Lowercase
+ {"ABC"sv, "abc"},
+ // Remove zero-width spaces
+ {"\xE2\x80\x8B"
+ "abc\xE2\x80\x8B"
+ "def"sv,
+ "abcdef"},
+ };
- for (const auto &c : cases) {
- auto [s1, s2] = c;
- SUBCASE((std::string("test case: ") + std::string(s1) + " => " + s2).c_str()) {
- gsize tlen;
- auto *ret = rspamd_utf8_transliterate(s1.data(), s1.length(), &tlen);
- CHECK(tlen == strlen(s2));
- CHECK(strcmp(s2, ret) == 0);
+ for (const auto &c: cases) {
+ auto [s1, s2] = c;
+ SUBCASE((std::string("test case: ") + std::string(s1) + " => " + s2).c_str())
+ {
+ gsize tlen;
+ auto *ret = rspamd_utf8_transliterate(s1.data(), s1.length(), &tlen);
+ CHECK(tlen == strlen(s2));
+ CHECK(strcmp(s2, ret) == 0);
+ }
}
}
-}
} \ No newline at end of file
diff --git a/src/libutil/cxx/utf8_util.h b/src/libutil/cxx/utf8_util.h
index 7f28ea45e..044beae36 100644
--- a/src/libutil/cxx/utf8_util.h
+++ b/src/libutil/cxx/utf8_util.h
@@ -22,7 +22,7 @@
#include "config.h"
#include "mem_pool.h"
-#ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
@@ -32,7 +32,7 @@ extern "C" {
* @param len length
* @return new length of the string trimmed
*/
-const char* rspamd_string_unicode_trim_inplace (const char *str, size_t *len);
+const char *rspamd_string_unicode_trim_inplace(const char *str, size_t *len);
enum rspamd_utf8_normalise_result {
RSPAMD_UNICODE_NORM_NORMAL = 0,
@@ -58,7 +58,7 @@ enum rspamd_utf8_normalise_result rspamd_normalise_unicode_inplace(gchar *start,
* @param target_len
* @return a new string that should be freed with g_free
*/
-gchar* rspamd_utf8_transliterate(const gchar *start, gsize len, gsize *target_len);
+gchar *rspamd_utf8_transliterate(const gchar *start, gsize len, gsize *target_len);
/**
* Compare two strings using libicu collator
@@ -78,8 +78,8 @@ int rspamd_utf8_strcmp(const char *s1, const char *s2, gsize n);
*/
int rspamd_utf8_strcmp_sizes(const char *s1, gsize n1, const char *s2, gsize n2);
-#ifdef __cplusplus
+#ifdef __cplusplus
}
#endif
-#endif //RSPAMD_UTF8_UTIL_H
+#endif//RSPAMD_UTF8_UTIL_H
diff --git a/src/libutil/cxx/util.hxx b/src/libutil/cxx/util.hxx
index 2d009c6cd..9ef2f6295 100644
--- a/src/libutil/cxx/util.hxx
+++ b/src/libutil/cxx/util.hxx
@@ -33,16 +33,14 @@ namespace rspamd {
/*
* Creates std::array from a standard C style array with automatic size calculation
*/
-template <typename... Ts>
-constexpr auto array_of(Ts&&... t) -> std::array<typename std::decay_t<typename std::common_type_t<Ts...>>, sizeof...(Ts)>
+template<typename... Ts>
+constexpr auto array_of(Ts &&...t) -> std::array<typename std::decay_t<typename std::common_type_t<Ts...>>, sizeof...(Ts)>
{
using T = typename std::decay_t<typename std::common_type_t<Ts...>>;
- return {{ std::forward<T>(t)... }};
+ return {{std::forward<T>(t)...}};
}
-template<class C, class K, class V = typename C::mapped_type, typename std::enable_if_t<
- std::is_constructible_v<typename C::key_type, K>
- && std::is_constructible_v<typename C::mapped_type, V>, bool> = false>
+template<class C, class K, class V = typename C::mapped_type, typename std::enable_if_t<std::is_constructible_v<typename C::key_type, K> && std::is_constructible_v<typename C::mapped_type, V>, bool> = false>
constexpr auto find_map(const C &c, const K &k) -> std::optional<std::reference_wrapper<const V>>
{
auto f = c.find(k);
@@ -55,15 +53,14 @@ constexpr auto find_map(const C &c, const K &k) -> std::optional<std::reference_
}
-template <typename _It>
+template<typename _It>
inline constexpr auto make_string_view_from_it(_It begin, _It end)
{
using result_type = std::string_view;
return result_type{((begin != end) ? &*begin : nullptr),
- (typename result_type::size_type)std::max(std::distance(begin, end),
- (typename result_type::difference_type)0)
- };
+ (typename result_type::size_type) std::max(std::distance(begin, end),
+ (typename result_type::difference_type) 0)};
}
/**
@@ -74,8 +71,7 @@ inline constexpr auto make_string_view_from_it(_It begin, _It end)
* @param functor
* @return
*/
-template<class S, class F, typename std::enable_if_t<std::is_invocable_v<F, std::string_view> &&
- std::is_constructible_v<std::string_view, S>, bool> = true>
+template<class S, class F, typename std::enable_if_t<std::is_invocable_v<F, std::string_view> && std::is_constructible_v<std::string_view, S>, bool> = true>
inline auto string_foreach_line(const S &input, const F &functor)
{
auto it = input.begin();
@@ -105,7 +101,7 @@ inline auto string_split_on(const S &input, std::string_view::value_type chr) ->
while (*pos == chr && pos != input.end()) {
++pos;
}
- auto last = std::string_view{pos, static_cast<std::size_t>(std::distance(pos, std::end(input)))};
+ auto last = std::string_view{pos, static_cast<std::size_t>(std::distance(pos, std::end(input)))};
return {first, last};
}
@@ -116,49 +112,73 @@ inline auto string_split_on(const S &input, std::string_view::value_type chr) ->
/**
* Enumerate for range loop
*/
-template <typename T,
- typename TIter = decltype(std::begin(std::declval<T>())),
- typename = decltype(std::end(std::declval<T>()))>
-constexpr auto enumerate(T && iterable)
+template<typename T,
+ typename TIter = decltype(std::begin(std::declval<T>())),
+ typename = decltype(std::end(std::declval<T>()))>
+constexpr auto enumerate(T &&iterable)
{
- struct iterator
- {
+ struct iterator {
size_t i;
TIter iter;
- bool operator != (const iterator & other) const { return iter != other.iter; }
- void operator ++ () { ++i; ++iter; }
- auto operator * () const { return std::tie(i, *iter); }
+ bool operator!=(const iterator &other) const
+ {
+ return iter != other.iter;
+ }
+ void operator++()
+ {
+ ++i;
+ ++iter;
+ }
+ auto operator*() const
+ {
+ return std::tie(i, *iter);
+ }
};
- struct iterable_wrapper
- {
+ struct iterable_wrapper {
T iterable;
- auto begin() { return iterator{ 0, std::begin(iterable) }; }
- auto end() { return iterator{ 0, std::end(iterable) }; }
+ auto begin()
+ {
+ return iterator{0, std::begin(iterable)};
+ }
+ auto end()
+ {
+ return iterator{0, std::end(iterable)};
+ }
};
- return iterable_wrapper{ std::forward<T>(iterable) };
+ return iterable_wrapper{std::forward<T>(iterable)};
}
/**
* Allocator that cleans up memory in a secure way on destruction
* @tparam T
*/
-template <class T> class secure_mem_allocator : public std::allocator<T>
-{
+template<class T>
+class secure_mem_allocator : public std::allocator<T> {
public:
using value_type = typename std::allocator<T>::value_type;
using size_type = typename std::allocator<T>::size_type;
- template<class U> struct rebind { typedef secure_mem_allocator<U> other; };
+ template<class U>
+ struct rebind {
+ typedef secure_mem_allocator<U> other;
+ };
secure_mem_allocator() noexcept = default;
- secure_mem_allocator(const secure_mem_allocator &_) noexcept : std::allocator<T>(_) {}
- template <class U> explicit secure_mem_allocator(const secure_mem_allocator<U>&) noexcept {}
+ secure_mem_allocator(const secure_mem_allocator &_) noexcept
+ : std::allocator<T>(_)
+ {
+ }
+ template<class U>
+ explicit secure_mem_allocator(const secure_mem_allocator<U> &) noexcept
+ {
+ }
- void deallocate(value_type *p, size_type num) noexcept {
- rspamd_explicit_memzero((void *)p, num);
+ void deallocate(value_type *p, size_type num) noexcept
+ {
+ rspamd_explicit_memzero((void *) p, num);
std::allocator<T>::deallocate(p, num);
}
};
-}
+}// namespace rspamd
-#endif //RSPAMD_UTIL_HXX
+#endif//RSPAMD_UTIL_HXX
diff --git a/src/libutil/cxx/util_tests.cxx b/src/libutil/cxx/util_tests.cxx
index 6d7f4dd55..2b3092779 100644
--- a/src/libutil/cxx/util_tests.cxx
+++ b/src/libutil/cxx/util_tests.cxx
@@ -22,23 +22,25 @@
using namespace rspamd;
using namespace std::literals::string_view_literals;
-TEST_SUITE("cxx utils") {
-TEST_CASE("string_split_on") {
- std::tuple<std::string_view, char, std::pair<std::string_view, std::string_view>> cases[] = {
- {"test test"sv, ' ', std::pair{"test"sv, "test"sv}},
- {"test test"sv, ' ', std::pair{"test"sv, "test"sv}},
- {"test test "sv, ' ', std::pair{"test"sv, "test "sv}},
- {"testtest "sv, ' ', std::pair{"testtest"sv, ""sv}},
- {" testtest "sv, ' ', std::pair{""sv, "testtest "sv}},
- {"testtest"sv, ' ', std::pair{"testtest"sv, ""sv}},
- {""sv, ' ', std::pair{""sv, ""sv}},
- };
+TEST_SUITE("cxx utils")
+{
+ TEST_CASE("string_split_on")
+ {
+ std::tuple<std::string_view, char, std::pair<std::string_view, std::string_view>> cases[] = {
+ {"test test"sv, ' ', std::pair{"test"sv, "test"sv}},
+ {"test test"sv, ' ', std::pair{"test"sv, "test"sv}},
+ {"test test "sv, ' ', std::pair{"test"sv, "test "sv}},
+ {"testtest "sv, ' ', std::pair{"testtest"sv, ""sv}},
+ {" testtest "sv, ' ', std::pair{""sv, "testtest "sv}},
+ {"testtest"sv, ' ', std::pair{"testtest"sv, ""sv}},
+ {""sv, ' ', std::pair{""sv, ""sv}},
+ };
- for (const auto& c : cases) {
- auto res = string_split_on(std::get<0>(c), std::get<1>(c));
- auto expected = std::get<2>(c);
- CHECK(res.first == expected.first);
- CHECK(res.second == expected.second);
+ for (const auto &c: cases) {
+ auto res = string_split_on(std::get<0>(c), std::get<1>(c));
+ auto expected = std::get<2>(c);
+ CHECK(res.first == expected.first);
+ CHECK(res.second == expected.second);
+ }
}
-}
} \ No newline at end of file