diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | base64.cpp | 23 | ||||
| -rw-r--r-- | base64.h | 12 | ||||
| -rw-r--r-- | os.cpp | 78 | ||||
| -rw-r--r-- | os.h | 12 | 
5 files changed, 127 insertions, 0 deletions
| @@ -18,8 +18,10 @@ CXXFLAGS+=-fvisibility=hidden  CXXFLAGS+=-fPIC  PROGSRC=\ +    base64.cpp \      file.cpp \      mime.cpp \ +    os.cpp \      stringutil.cpp \      tempfile.cpp \      url.cpp diff --git a/base64.cpp b/base64.cpp new file mode 100644 index 0000000..d72dc52 --- /dev/null +++ b/base64.cpp @@ -0,0 +1,23 @@ +#include "base64.h" + +#include <boost/archive/iterators/binary_from_base64.hpp> +#include <boost/archive/iterators/base64_from_binary.hpp> +#include <boost/archive/iterators/transform_width.hpp> +#include <boost/algorithm/string.hpp> + +std::string Reichwein::Base64::decode64(const std::string &val) +{ + using namespace boost::archive::iterators; + using It = transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>; + return boost::algorithm::trim_right_copy_if(std::string(It(std::begin(val)), It(std::end(val))), [](char c) { +  return c == '\0'; + }); +} + +std::string Reichwein::Base64::encode64(const std::string &val) +{ + using namespace boost::archive::iterators; + using It = base64_from_binary<transform_width<std::string::const_iterator, 6, 8>>; + auto tmp = std::string(It(std::begin(val)), It(std::end(val))); + return tmp.append((3 - val.size() % 3) % 3, '='); +} diff --git a/base64.h b/base64.h new file mode 100644 index 0000000..87d6daf --- /dev/null +++ b/base64.h @@ -0,0 +1,12 @@ +#pragma once + +#include <string> + +#define EXPORT __attribute__((visibility("default"))) + +namespace Reichwein::Base64 { + +EXPORT std::string decode64(const std::string &val); +EXPORT std::string encode64(const std::string &val); + +} // namespace @@ -0,0 +1,78 @@ +#include "os.h" + +#include <boost/algorithm/string/split.hpp> + +#include <unistd.h> + +#include <fstream> +#include <vector> + +using namespace std::string_literals; + +namespace { + + std::string to_string(uint32_t v, size_t size) + { +  std::string result{std::to_string(v)}; + +  return (size > result.size() ? std::string(size - result.size(), char('0')) : ""s) + result; + } + + std::string to_time_string(uint32_t sec) + { +  uint32_t days = sec / (24 * 3600); +  uint32_t hours = (sec % (24 * 3600)) / 3600; +  uint32_t minutes = (sec % 3600) / 60; +  uint32_t seconds = (sec % 60); + +  return std::to_string(days) + " days, "s + to_string(hours, 2) + ":"s + to_string(minutes, 2) + ":"s + to_string(seconds, 2); + } + + uint64_t uptime() + { +  double uptime_seconds{}; +  if (std::ifstream("/proc/uptime", std::ios::in) >> uptime_seconds) +  { +   return static_cast<uint64_t>(uptime_seconds); +  } + +  return 0; + } + +} // anonymous namespace + +std::string Reichwein::OS::uptime_host() +{ + return to_time_string(uptime()); +} + +std::string Reichwein::OS::uptime_process() +{ + std::string filepath{"/proc/self/stat"}; + std::ifstream f(filepath, std::ios::in); + if (f.is_open()) { +  std::string line; +  std::getline(f, line); +  std::vector<std::string> elements; +  boost::algorithm::split(elements, line, [](char c){ return c == ' '; }); +  if (elements.size() < 22) +   throw std::runtime_error("Bad contents of /proc/self/stat"); + +  long jiffies_per_second {sysconf(_SC_CLK_TCK)}; +  if (jiffies_per_second == 0) +   throw std::runtime_error("Jiffies per second is 0"); + +  try { +   unsigned long starttime { std::stoul(elements[21])}; + +   unsigned long runtime = uptime() - starttime / jiffies_per_second; + +   return to_time_string(runtime); +  } catch (const std::exception& ex) { +   throw std::runtime_error("Bad value in /proc/self/stat: "s + ex.what()); +  } + + } else +  throw std::runtime_error("Reading /proc/self/stat"); +} + @@ -0,0 +1,12 @@ +#pragma once + +#include <string> + +#define EXPORT __attribute__((visibility("default"))) + +namespace Reichwein::OS { + +EXPORT std::string uptime_host(); +EXPORT std::string uptime_process(); + +} // namespace | 
