aboutsummaryrefslogtreecommitdiff
path: root/src/shared/shared.hh
blob: f070425e9d8d11ff560c2b413e12706af6093c8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#ifndef SHARED_SHARED_HH_
#define SHARED_SHARED_HH_

#include <algorithm>
#include <atomic>
#include <chrono>
#include <cstdlib>
#include <execinfo.h>
#include <fstream>
#include <getopt.h>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <optional>
#include <ranges>
#include <signal.h>
#include <string>

#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>

#include "shared/math/math.hh"
#include "shared/net/proto.hh"

namespace shared {

using time_point_t = decltype(std::chrono::steady_clock::now());
using time_duration_t = decltype(std::chrono::steady_clock::now() -
                                 std::chrono::steady_clock::now());
float get_duration_seconds(const time_duration_t& duration) noexcept;

std::string make_string_lower(std::string str) noexcept;
std::string read_file(const std::string& path);

[[nodiscard]] std::string compress_string(const std::string& str);
[[nodiscard]] std::optional<std::string>
maybe_decompress_string(const std::string& str) noexcept;

std::ofstream open_file(const std::string& dir,
                        const std::ios_base::openmode mode = std::ios::trunc);

constexpr unsigned long MAX_SAY_LENGTH = 32ul;
constexpr unsigned long MAX_USER_PASS_LENGTH = 64;

using tick_t = std::uint32_t;

// Thread safe printing - this MESS will be cleaned up when we have std::print.
namespace print { 
class print_base {
protected:
    static inline std::mutex lock;

public:
    enum class colour {
        black = 30,
        red = 31,
        green = 32,
        yellow = 33,
        blue = 34,
        magenta = 35,
        cyan = 36,
        white = 37,
        none = 39,
        grey = 90,
        bright_red = 91,
        bright_green = 92,
        bright_yellow = 93,
        bright_blue = 94,
        bright_magenta = 95,
        bright_cyan = 96,
        bright_white = 97
    };
    static std::string make_colour(const colour clr) noexcept {
        return {"\033[" + std::to_string(static_cast<int>(clr)) + "m"};
    }

protected:
    static void print_message(std::ostream& os, const std::string_view colour,
                              const bool cerr = false) noexcept {
        const std::lock_guard<std::mutex> guard(lock);
        static const std::string none = make_colour(colour::none);
        (cerr ? std::cerr : std::cout) << colour << os.rdbuf() << none;
    }
};

class print_time { // operator<< returns time as stringstream
public:
    friend std::ostream& operator<<(std::ostream& os,
                                    const print_time&) noexcept {
        const auto epoch = std::time(nullptr);
        struct tm* local = localtime(&epoch);

        using pb = print_base;
        static const std::string white = pb::make_colour(pb::colour::white);
        static const std::string none = pb::make_colour(pb::colour::none);
        os << white << std::put_time(local, "[%F %T] ") << none;
        return os;
    }
};

class print_colour : public print_base {
private:
    enum print_base::colour colour;
    bool cerr;

public:
    print_colour(const decltype(colour) colour,
                 const decltype(cerr) cerr) noexcept
        : colour(colour), cerr(cerr) {}

    template <typename T>
    print_colour& operator<<(const T& obj) noexcept {
        std::stringstream ss{};
        ss << obj;
        print_base::print_message(ss, make_colour(this->colour), this->cerr);
        return *this;
    }
};

inline auto time = print_time{};
inline print_colour message{print_base::colour::white, false};
inline print_colour notify{print_base::colour::cyan, false};
inline print_colour warn{print_base::colour::bright_yellow, true};
inline print_colour fault{print_base::colour::bright_red, true};
inline print_colour debug{print_base::colour::magenta, true};
} // namespace print

inline std::atomic<bool> should_exit = false;

}; // namespace shared

#endif