diff options
Diffstat (limited to 'louloulibs/utils')
-rw-r--r-- | louloulibs/utils/encoding.cpp | 21 | ||||
-rw-r--r-- | louloulibs/utils/get_first_non_empty.cpp | 11 | ||||
-rw-r--r-- | louloulibs/utils/get_first_non_empty.hpp | 20 | ||||
-rw-r--r-- | louloulibs/utils/scopeguard.hpp | 7 | ||||
-rw-r--r-- | louloulibs/utils/sha1.cpp | 33 | ||||
-rw-r--r-- | louloulibs/utils/sha1.hpp | 2 | ||||
-rw-r--r-- | louloulibs/utils/time.cpp | 70 | ||||
-rw-r--r-- | louloulibs/utils/time.hpp | 10 |
8 files changed, 126 insertions, 48 deletions
diff --git a/louloulibs/utils/encoding.cpp b/louloulibs/utils/encoding.cpp index 507f38a..60f2212 100644 --- a/louloulibs/utils/encoding.cpp +++ b/louloulibs/utils/encoding.cpp @@ -75,13 +75,12 @@ namespace utils std::string remove_invalid_xml_chars(const std::string& original) { // The given string MUST be a valid utf-8 string - unsigned char* res = new unsigned char[original.size()]; - ScopeGuard sg([&res]() { delete[] res;}); + std::vector<char> res(original.size(), '\0'); // pointer where we write valid chars - unsigned char* r = res; + char* r = res.data(); - const unsigned char* str = reinterpret_cast<const unsigned char*>(original.c_str()); + const char* str = original.c_str(); std::bitset<20> codepoint; while (*str) @@ -140,7 +139,7 @@ namespace utils else throw std::runtime_error("Invalid UTF-8 passed to remove_invalid_xml_chars"); } - return std::string(reinterpret_cast<char*>(res), r-res); + return {res.data(), static_cast<size_t>(r - res.data())}; } std::string convert_to_utf8(const std::string& str, const char* charset) @@ -152,7 +151,7 @@ namespace utils throw std::runtime_error("Cannot convert into UTF-8"); // Make sure cd is always closed when we leave this function - ScopeGuard sg([&]{ iconv_close(cd); }); + const auto sg = utils::make_scope_guard([&cd](auto&&){ iconv_close(cd); }); size_t inbytesleft = str.size(); @@ -169,7 +168,7 @@ namespace utils char* outbuf_ptr = outbuf; // Make sure outbuf is always deleted when we leave this function - sg.add_callback([&]{ delete[] outbuf; }); + const auto sg2 = utils::make_scope_guard([outbuf](auto&&){ delete[] outbuf; }); bool done = false; while (done == false) @@ -197,12 +196,8 @@ namespace utils outbuf_ptr++; done = true; break; - case E2BIG: - // This should never happen - done = true; - break; - default: - // This should happen even neverer + case E2BIG: // This should never happen + default: // This should happen even neverer done = true; break; } diff --git a/louloulibs/utils/get_first_non_empty.cpp b/louloulibs/utils/get_first_non_empty.cpp new file mode 100644 index 0000000..5b3bedb --- /dev/null +++ b/louloulibs/utils/get_first_non_empty.cpp @@ -0,0 +1,11 @@ +#include <utils/get_first_non_empty.hpp> + +bool is_empty(const std::string& val) +{ + return val.empty(); +} + +bool is_empty(const int& val) +{ + return val == 0; +} diff --git a/louloulibs/utils/get_first_non_empty.hpp b/louloulibs/utils/get_first_non_empty.hpp new file mode 100644 index 0000000..a38f5fb --- /dev/null +++ b/louloulibs/utils/get_first_non_empty.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include <string> + +bool is_empty(const std::string& val); +bool is_empty(const int& val); + +template <typename T> +T get_first_non_empty(T&& last) +{ + return last; +} + +template <typename T, typename... Args> +T get_first_non_empty(T&& first, Args&&... args) +{ + if (!is_empty(first)) + return first; + return get_first_non_empty(std::forward<Args>(args)...); +} diff --git a/louloulibs/utils/scopeguard.hpp b/louloulibs/utils/scopeguard.hpp index ee1e2ef..cd0e89e 100644 --- a/louloulibs/utils/scopeguard.hpp +++ b/louloulibs/utils/scopeguard.hpp @@ -1,6 +1,7 @@ #pragma once #include <functional> +#include <memory> #include <vector> /** @@ -85,5 +86,11 @@ private: }; +template<typename F> +auto make_scope_guard(F&& f) +{ + return std::unique_ptr<void, std::decay_t<F>>{(void*)1, std::forward<F>(f)}; +} + } diff --git a/louloulibs/utils/sha1.cpp b/louloulibs/utils/sha1.cpp index 76476df..f75bc2a 100644 --- a/louloulibs/utils/sha1.cpp +++ b/louloulibs/utils/sha1.cpp @@ -119,36 +119,3 @@ uint8_t* sha1_result(sha1nfo *s) { // Return pointer to hash (20 characters) return s->state.b; } - -#define HMAC_IPAD 0x36 -#define HMAC_OPAD 0x5c - -void sha1_initHmac(sha1nfo *s, const uint8_t* key, int keyLength) { - uint8_t i; - memset(s->keyBuffer, 0, BLOCK_LENGTH); - if (keyLength > BLOCK_LENGTH) { - // Hash long keys - sha1_init(s); - for (;keyLength--;) sha1_writebyte(s, *key++); - memcpy(s->keyBuffer, sha1_result(s), HASH_LENGTH); - } else { - // Block length keys are used as is - memcpy(s->keyBuffer, key, keyLength); - } - // Start inner hash - sha1_init(s); - for (i=0; i<BLOCK_LENGTH; i++) { - sha1_writebyte(s, s->keyBuffer[i] ^ HMAC_IPAD); - } -} - -uint8_t* sha1_resultHmac(sha1nfo *s) { - uint8_t i; - // Complete inner hash - memcpy(s->innerHash,sha1_result(s),HASH_LENGTH); - // Calculate outer hash - sha1_init(s); - for (i=0; i<BLOCK_LENGTH; i++) sha1_writebyte(s, s->keyBuffer[i] ^ HMAC_OPAD); - for (i=0; i<HASH_LENGTH; i++) sha1_writebyte(s, s->innerHash[i]); - return sha1_result(s); -} diff --git a/louloulibs/utils/sha1.hpp b/louloulibs/utils/sha1.hpp index d02de75..d436782 100644 --- a/louloulibs/utils/sha1.hpp +++ b/louloulibs/utils/sha1.hpp @@ -31,5 +31,3 @@ void sha1_init(sha1nfo *s); void sha1_writebyte(sha1nfo *s, uint8_t data); void sha1_write(sha1nfo *s, const char *data, size_t len); uint8_t* sha1_result(sha1nfo *s); -void sha1_initHmac(sha1nfo *s, const uint8_t* key, int keyLength); -uint8_t* sha1_resultHmac(sha1nfo *s); diff --git a/louloulibs/utils/time.cpp b/louloulibs/utils/time.cpp new file mode 100644 index 0000000..afd6117 --- /dev/null +++ b/louloulibs/utils/time.cpp @@ -0,0 +1,70 @@ +#include <utils/time.hpp> +#include <time.h> + +#include <sstream> +#include <iomanip> +#include <locale> + +#include "louloulibs.h" + +namespace utils +{ +std::string to_string(const std::time_t& timestamp) +{ + constexpr std::size_t stamp_size = 21; + char date_buf[stamp_size]; + if (std::strftime(date_buf, stamp_size, "%FT%TZ", std::gmtime(×tamp)) != stamp_size - 1) + return ""; + return {std::begin(date_buf), std::end(date_buf) - 1}; +} + +std::time_t parse_datetime(const std::string& stamp) +{ + static const char* format = "%Y-%m-%dT%H:%M:%S"; + std::tm t = {}; +#ifdef HAS_GET_TIME + std::istringstream ss(stamp); + ss.imbue(std::locale("en_US.utf-8")); + + std::string timezone; + ss >> std::get_time(&t, format) >> timezone; + if (ss.fail()) + return -1; +#else + /* Y - m - d T H : M : S */ + constexpr std::size_t stamp_size_without_tz = 4 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2; + if (!strptime(stamp.data(), format, &t)) { + return -1; + } + const std::string timezone(stamp.data() + stamp_size_without_tz); +#endif + + if (timezone.empty()) + return -1; + + if (timezone.compare(0, 1, "Z") != 0) + { + std::stringstream tz_ss; + tz_ss << timezone; + int multiplier = -1; + char prefix; + int hours; + char sep; + int minutes; + tz_ss >> prefix >> hours >> sep >> minutes; + if (tz_ss.fail()) + return -1; + if (prefix == '-') + multiplier = +1; + else if (prefix != '+') + return -1; + + t.tm_hour += multiplier * hours; + t.tm_min += multiplier * minutes; + } + return ::timegm(&t); +} + +} + + diff --git a/louloulibs/utils/time.hpp b/louloulibs/utils/time.hpp new file mode 100644 index 0000000..c71cd9c --- /dev/null +++ b/louloulibs/utils/time.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include <ctime> +#include <string> + +namespace utils +{ +std::string to_string(const std::time_t& timestamp); +std::time_t parse_datetime(const std::string& stamp); +}
\ No newline at end of file |