diff options
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/dirname.cpp | 2 | ||||
-rw-r--r-- | src/utils/dirname.hpp | 4 | ||||
-rw-r--r-- | src/utils/encoding.cpp | 26 | ||||
-rw-r--r-- | src/utils/get_first_non_empty.cpp | 5 | ||||
-rw-r--r-- | src/utils/get_first_non_empty.hpp | 7 | ||||
-rw-r--r-- | src/utils/optional_bool.hpp | 2 | ||||
-rw-r--r-- | src/utils/string.cpp | 4 | ||||
-rw-r--r-- | src/utils/time.cpp | 8 | ||||
-rw-r--r-- | src/utils/tokens_bucket.hpp | 60 |
9 files changed, 91 insertions, 27 deletions
diff --git a/src/utils/dirname.cpp b/src/utils/dirname.cpp index 71c9c38..a304117 100644 --- a/src/utils/dirname.cpp +++ b/src/utils/dirname.cpp @@ -2,7 +2,7 @@ namespace utils { - std::string dirname(const std::string filename) + std::string dirname(const std::string& filename) { if (filename.empty()) return "./"; diff --git a/src/utils/dirname.hpp b/src/utils/dirname.hpp index c1df81b..c13393d 100644 --- a/src/utils/dirname.hpp +++ b/src/utils/dirname.hpp @@ -1,6 +1,8 @@ +#pragma once + #include <string> namespace utils { -std::string dirname(const std::string filename); +std::string dirname(const std::string& filename); } diff --git a/src/utils/encoding.cpp b/src/utils/encoding.cpp index cff0039..8532292 100644 --- a/src/utils/encoding.cpp +++ b/src/utils/encoding.cpp @@ -48,16 +48,16 @@ namespace utils if (codepoint_size == 4) { if (!str[1] || !str[2] || !str[3] - || ((str[1] & 0b11000000) != 0b10000000) - || ((str[2] & 0b11000000) != 0b10000000) - || ((str[3] & 0b11000000) != 0b10000000)) + || ((str[1] & 0b11000000u) != 0b10000000u) + || ((str[2] & 0b11000000u) != 0b10000000u) + || ((str[3] & 0b11000000u) != 0b10000000u)) return false; } else if (codepoint_size == 3) { if (!str[1] || !str[2] - || ((str[1] & 0b11000000) != 0b10000000) - || ((str[2] & 0b11000000) != 0b10000000)) + || ((str[1] & 0b11000000u) != 0b10000000u) + || ((str[2] & 0b11000000u) != 0b10000000u)) return false; } else if (codepoint_size == 2) @@ -81,7 +81,7 @@ namespace utils // pointer where we write valid chars char* r = res.data(); - const char* str = original.c_str(); + const unsigned char* str = reinterpret_cast<const unsigned char*>(original.c_str()); std::bitset<20> codepoint; while (*str) @@ -89,10 +89,10 @@ namespace utils // 4 bytes: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx if ((str[0] & 0b11111000) == 0b11110000) { - codepoint = ((str[0] & 0b00000111) << 18); - codepoint |= ((str[1] & 0b00111111) << 12); - codepoint |= ((str[2] & 0b00111111) << 6 ); - codepoint |= ((str[3] & 0b00111111) << 0 ); + codepoint = ((str[0] & 0b00000111u) << 18u); + codepoint |= ((str[1] & 0b00111111u) << 12u); + codepoint |= ((str[2] & 0b00111111u) << 6u ); + codepoint |= ((str[3] & 0b00111111u) << 0u ); if (codepoint.to_ulong() <= 0x10FFFF) { ::memcpy(r, str, 4); @@ -103,9 +103,9 @@ namespace utils // 3 bytes: 1110xxx 10xxxxxx 10xxxxxx else if ((str[0] & 0b11110000) == 0b11100000) { - codepoint = ((str[0] & 0b00001111) << 12); - codepoint |= ((str[1] & 0b00111111) << 6); - codepoint |= ((str[2] & 0b00111111) << 0 ); + codepoint = ((str[0] & 0b00001111u) << 12u); + codepoint |= ((str[1] & 0b00111111u) << 6u); + codepoint |= ((str[2] & 0b00111111u) << 0u ); if (codepoint.to_ulong() <= 0xD7FF || (codepoint.to_ulong() >= 0xE000 && codepoint.to_ulong() <= 0xFFFD)) { diff --git a/src/utils/get_first_non_empty.cpp b/src/utils/get_first_non_empty.cpp index 5b3bedb..17585b1 100644 --- a/src/utils/get_first_non_empty.cpp +++ b/src/utils/get_first_non_empty.cpp @@ -1,11 +1,8 @@ #include <utils/get_first_non_empty.hpp> +template <> bool is_empty(const std::string& val) { return val.empty(); } -bool is_empty(const int& val) -{ - return val == 0; -} diff --git a/src/utils/get_first_non_empty.hpp b/src/utils/get_first_non_empty.hpp index a38f5fb..1877ee8 100644 --- a/src/utils/get_first_non_empty.hpp +++ b/src/utils/get_first_non_empty.hpp @@ -2,8 +2,13 @@ #include <string> +template <typename T> +bool is_empty(const T& val) +{ + return val == 0; +} +template <> bool is_empty(const std::string& val); -bool is_empty(const int& val); template <typename T> T get_first_non_empty(T&& last) diff --git a/src/utils/optional_bool.hpp b/src/utils/optional_bool.hpp index 867aca2..3d00d23 100644 --- a/src/utils/optional_bool.hpp +++ b/src/utils/optional_bool.hpp @@ -6,7 +6,7 @@ struct OptionalBool { OptionalBool() = default; - OptionalBool(bool value): + explicit OptionalBool(bool value): is_set(true), value(value) {} void set_value(bool value) diff --git a/src/utils/string.cpp b/src/utils/string.cpp index 635e71a..366ec1f 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -15,11 +15,11 @@ std::vector<std::string> cut(const std::string& val, const std::size_t size) // Get the number of chars, <= size, that contain only whole // UTF-8 codepoints. std::size_t s = 0; - auto codepoint_size = utils::get_next_codepoint_size(val[pos + s]); + auto codepoint_size = utils::get_next_codepoint_size(static_cast<unsigned char>(val[pos + s])); while (s + codepoint_size <= size && pos + s < val.size()) { s += codepoint_size; - codepoint_size = utils::get_next_codepoint_size(val[pos + s]); + codepoint_size = utils::get_next_codepoint_size(static_cast<unsigned char>(val[pos + s])); } res.emplace_back(val.substr(pos, s)); pos += s; diff --git a/src/utils/time.cpp b/src/utils/time.cpp index 71306fd..d848e70 100644 --- a/src/utils/time.cpp +++ b/src/utils/time.cpp @@ -1,9 +1,8 @@ #include <utils/time.hpp> -#include <ctime> +#include <time.h> #include <sstream> #include <iomanip> -#include <locale> #include "biboumi.h" @@ -12,9 +11,10 @@ namespace utils std::string to_string(const std::chrono::system_clock::time_point::rep& time) { constexpr std::size_t stamp_size = 21; - const std::time_t timestamp = static_cast<std::time_t>(time); + const auto timestamp = static_cast<std::time_t>(time); char date_buf[stamp_size]; - if (std::strftime(date_buf, stamp_size, "%FT%TZ", std::gmtime(×tamp)) != stamp_size - 1) + struct tm tm; + if (std::strftime(date_buf, stamp_size, "%FT%TZ", gmtime_r(×tamp, &tm)) != stamp_size - 1) return ""; return {std::begin(date_buf), std::end(date_buf) - 1}; } diff --git a/src/utils/tokens_bucket.hpp b/src/utils/tokens_bucket.hpp new file mode 100644 index 0000000..263359a --- /dev/null +++ b/src/utils/tokens_bucket.hpp @@ -0,0 +1,60 @@ +/** + * Implementation of the token bucket algorithm. + * + * It uses a repetitive TimedEvent, started at construction, to fill the + * bucket. + * + * Every n seconds, it executes the given callback. If the callback + * returns true, we add a token (if the limit is not yet reached). + * + */ + +#pragma once + +#include <utils/timed_events.hpp> +#include <logger/logger.hpp> + +class TokensBucket +{ +public: + TokensBucket(long int max_size, std::chrono::milliseconds fill_duration, std::function<bool()> callback, std::string name): + limit(max_size), + tokens(static_cast<std::size_t>(limit)), + callback(std::move(callback)) + { + log_debug("creating TokensBucket with max size: ", max_size); + TimedEvent event(std::move(fill_duration), [this]() { this->add_token(); }, std::move(name)); + TimedEventsManager::instance().add_event(std::move(event)); + } + + bool use_token() + { + if (this->limit < 0) + return true; + if (this->tokens > 0) + { + this->tokens--; + return true; + } + else + return false; + } + + void set_limit(long int limit) + { + this->limit = limit; + } + +private: + long int limit; + std::size_t tokens; + std::function<bool()> callback; + + void add_token() + { + if (this->limit < 0) + return; + if (this->callback() && this->tokens != static_cast<decltype(this->tokens)>(this->limit)) + this->tokens++; + } +}; |