69 lines
2.1 KiB
C++
69 lines
2.1 KiB
C++
#include <fcntl.h>
|
||
#include <unistd.h>
|
||
|
||
#include <array>
|
||
#include <cstdint>
|
||
#include <filesystem>
|
||
#include <format>
|
||
#include <log.hpp>
|
||
#include <string>
|
||
#include <string_view>
|
||
#include <utils.hpp>
|
||
|
||
namespace utils {
|
||
|
||
/* pads given string to length */
|
||
std::string pad(std::string s, const uint8_t len, just j) {
|
||
if (len > s.size())
|
||
s.insert(j == left ? s.end() : s.begin(), len - s.size(), fill_char);
|
||
return s;
|
||
}
|
||
|
||
/* returns the string centered within given length */
|
||
std::string center(std::string str, const uint8_t len) {
|
||
const uint8_t padding = len - str.size();
|
||
str.insert(str.begin(), padding / 2, fill_char);
|
||
str.insert(str.end(), padding / 2, fill_char);
|
||
return str;
|
||
}
|
||
|
||
/* converts large number in (k)bytes to human-readable numer with suffix and sane decimal */
|
||
std::string pBytes(double bytes, const bool isKbytes) {
|
||
for (constexpr std::array suffix_list = {'K', 'M', 'G', 'T', 'P', 'E', 'Z'}; const auto& suffix : suffix_list) {
|
||
if (suffix == 'K' && isKbytes) continue; // skip first loop if already in Kbytes
|
||
bytes /= 1024.0;
|
||
if (bytes < 1024) {
|
||
if (bytes > 100) return pNum(bytes) + suffix;
|
||
if (bytes > 10) return pNum(bytes, 1) + suffix;
|
||
return pNum(bytes, 2) + suffix;
|
||
}
|
||
}
|
||
return "++++";
|
||
}
|
||
|
||
/* reads maxlen of chars of the file in path into buffer */
|
||
ssize_t readFile(const char* path, char* buffer, size_t maxlen) {
|
||
const int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||
if (fd < 0) {
|
||
applog(LOG::ERR, "Error reading {}", path);
|
||
return 0;
|
||
}
|
||
const ssize_t len = read(fd, buffer, maxlen - 1);
|
||
if (len >= 0) buffer[len] = '\0';
|
||
close(fd);
|
||
return len;
|
||
}
|
||
|
||
/* overload so it takes std::string as path */
|
||
ssize_t readFile(const std::string& path, char* buffer, size_t maxlen) {
|
||
return readFile(path.c_str(), buffer, maxlen);
|
||
}
|
||
|
||
/* finds first dir in path and returns it. don't refactor, you don't understand it, its fast enough, and you only use it on init */
|
||
std::string getFirstDir(const std::string_view& path) {
|
||
for (const auto& entry : std::filesystem::directory_iterator(path))
|
||
return entry.path();
|
||
return "";
|
||
}
|
||
|
||
} |