summaryrefslogtreecommitdiff
path: root/louloulibs/utils
diff options
context:
space:
mode:
Diffstat (limited to 'louloulibs/utils')
-rw-r--r--louloulibs/utils/encoding.cpp21
-rw-r--r--louloulibs/utils/get_first_non_empty.cpp11
-rw-r--r--louloulibs/utils/get_first_non_empty.hpp20
-rw-r--r--louloulibs/utils/scopeguard.hpp7
-rw-r--r--louloulibs/utils/sha1.cpp33
-rw-r--r--louloulibs/utils/sha1.hpp2
-rw-r--r--louloulibs/utils/time.cpp70
-rw-r--r--louloulibs/utils/time.hpp10
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(&timestamp)) != 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