diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2021-11-28 22:48:30 -0500 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2021-11-28 22:48:30 -0500 |
commit | e1703aea3fd597b23bde90e6c505278c517be611 (patch) | |
tree | 37d98fc90c9cd0844388bfb79beda2204f44af92 /src/discord/snowflake.cpp | |
parent | fd53a76bf6f53a095a639765923a30f2206b2cd6 (diff) | |
parent | e02107feea8214a045e6faa969f00dcbc0d2b072 (diff) | |
download | abaddon-portaudio-e1703aea3fd597b23bde90e6c505278c517be611.tar.gz abaddon-portaudio-e1703aea3fd597b23bde90e6c505278c517be611.zip |
merge master
Diffstat (limited to 'src/discord/snowflake.cpp')
-rw-r--r-- | src/discord/snowflake.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/discord/snowflake.cpp b/src/discord/snowflake.cpp new file mode 100644 index 0000000..6909a15 --- /dev/null +++ b/src/discord/snowflake.cpp @@ -0,0 +1,66 @@ +#include "snowflake.hpp" +#include <ctime> +#include <iomanip> +#include <chrono> +#include <glibmm.h> + +constexpr static uint64_t DiscordEpochSeconds = 1420070400; + +const Snowflake Snowflake::Invalid = -1ULL; + +Snowflake::Snowflake() + : m_num(Invalid) {} + +Snowflake::Snowflake(uint64_t n) + : m_num(n) {} + +Snowflake::Snowflake(const std::string &str) { + if (str.size()) + m_num = std::stoull(str); + else + m_num = Invalid; +} +Snowflake::Snowflake(const Glib::ustring &str) { + if (str.size()) + m_num = std::strtoull(str.c_str(), nullptr, 10); + else + m_num = Invalid; +}; + +Snowflake Snowflake::FromNow() { + using namespace std::chrono; + // not guaranteed to work but it probably will anyway + static uint64_t counter = 0; + const auto millis_since_epoch = static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count()); + const auto epoch = millis_since_epoch - DiscordEpochSeconds * 1000; + uint64_t snowflake = epoch << 22; + // worker id and process id would be OR'd in here but there's no point + snowflake |= counter++ % 4096; + return snowflake; +} + +bool Snowflake::IsValid() const { + return m_num != Invalid; +} + +Glib::ustring Snowflake::GetLocalTimestamp() const { + const time_t secs_since_epoch = (m_num / SecondsInterval) + DiscordEpochSeconds; + const std::tm tm = *localtime(&secs_since_epoch); + std::array<char, 256> tmp; + std::strftime(tmp.data(), sizeof(tmp), "%X %x", &tm); + return tmp.data(); +} + +void from_json(const nlohmann::json &j, Snowflake &s) { + if (j.is_string()) { + std::string tmp; + j.get_to(tmp); + s.m_num = std::stoull(tmp); + } else { + j.get_to(s.m_num); + } +} + +void to_json(nlohmann::json &j, const Snowflake &s) { + j = std::to_string(s); +} |