Files
integration/luprex/cpp/drv/drvutil.hpp

122 lines
3.8 KiB
C++

////////////////////////////////////////////////////////////////////////////////
//
// DRIVER_UTIL
//
////////////////////////////////////////////////////////////////////////////////
#ifndef DRVUTIL_HPP
#define DRVUTIL_HPP
#include <vector>
#include <string>
#include <memory>
#include <string_view>
#include <ostream>
#include <sstream>
#include <algorithm>
#include <filesystem>
namespace drvutil {
// Read the lua source from disk into an ostringstream.
//
// To pass the lua source into the DLL, here is what you do: Construct an
// ostringstream. Use package_lua_source to package all the lua source into
// the ostringstream. Fetch the packaged source code using ostringstream::str.
// Pass the packaged source code into drv_set_lua_source.
//
// The DLL must then decode the source package. Here is how it does that:
// It creates a StreamBuffer from the packaged up source. Then it must
// call these StreamBuffer methods:
//
// - read the number of source files using read_uint32.
// - for each file, read the filename using read_string.
// - for each file, read the contents using read_string.
//
// If package_lua_source encounters an error reading the source code, then it
// returns an error message. In this case, the ostream contains garbage. If
// there is no error, returns the empty string.
//
std::string package_lua_source(const std::filesystem::path &base, std::ostream *oss);
// Parse a target designation.
//
// A target consists of 'cert::host::port'.
//
void split_target(std::string_view target, std::string &cert, std::string &host, std::string &port);
// Return true if the unicode codepoint can be converted to a single 16-bit wchar_t.
//
bool is_single_wchar_t(char32_t c);
// Convert a codepoint string into a UTF8-string.
// If the codepoint string contains invalid codepoints, they're silently dropped.
//
std::string to_utf8(const std::u32string &cps);
// Convert a UTF8 string to a codepoint string.
//
// If the UTF8 string contains invalid sequences, they're silently dropped.
// Some of the bytes may not be consumed, if the source ends with an unfinished
// utf-8 sequence. Returns the Codepoint string and the number of bytes consumed.
//
std::u32string from_utf8(std::string_view source, int *consumed);
// Get a system error message, in an OS-independent manner.
//
// These versions of strerror is thread-safe, and it never fails
// to put a message into the buffer.
//
void strerror_safe(int errnum, char result[256]);
std::string strerror_str(int errnum);
// Get the amount of time elapsed since program start.
//
// This is guaranteed to be monotonically increasing. It is not
// guaranteed to be accurate. Error could gradually accumulate over
// time.
//
double get_monotonic_clock();
// drvutil::ostringstream
//
// This is a variant of ostringstream in which it is possible
// to get the contents without copying. To get the contents
// without copying, use oss.size() and oss.c_str()
//
class ostringstream : public std::ostringstream {
class rstringbuf : public std::basic_stringbuf<char_type, traits_type, allocator_type> {
public:
char *eback() const { return std::streambuf::eback(); }
char *pptr() const { return std::streambuf::pptr(); }
};
rstringbuf rstringbuf_;
public:
ostringstream() {
std::basic_ostream<char>::rdbuf(&rstringbuf_);
}
std::string_view view() const {
char *p = rstringbuf_.eback();
size_t size = rstringbuf_.pptr() - p;
return std::string_view(p, size);
}
std::string str() const {
return rstringbuf_.str();
}
};
// Remove items from a vector that are marked for deletion.
//
template<class T>
void remove_marked_items(T &vec) {
auto iter = std::partition(vec.begin(), vec.end(), [] (const auto &x) { return !x.marked_for_deletion(); });
vec.erase(iter, vec.end());
}
} // namespace drvutil
#endif // DRVUTIL_HPP