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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#pragma once
#include <algorithm>
#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <memory>
#include <stddef.h>
#include <string>
#include <vector>
typedef unsigned char byte;
namespace securefs
{
template <class CharT>
class BasicStringRef
{
private:
const CharT* m_buffer;
size_t m_size;
public:
BasicStringRef() : m_buffer(nullptr), m_size(0) {}
BasicStringRef(const CharT* str) : m_buffer(str), m_size(std::char_traits<CharT>::length(str))
{
}
BasicStringRef(const std::basic_string<CharT>& str) : m_buffer(str.c_str()), m_size(str.size())
{
}
const CharT* data() const noexcept { return m_buffer; }
const CharT* c_str() const noexcept { return m_buffer; }
size_t size() const noexcept { return m_size; }
size_t length() const noexcept { return m_size; }
CharT operator[](size_t i) const noexcept { return m_buffer[i]; }
const CharT* begin() const noexcept { return data(); }
const CharT* end() const noexcept { return data() + size(); }
CharT front() const noexcept { return m_buffer[0]; }
CharT back() const noexcept { return m_buffer[m_size - 1]; }
bool empty() const noexcept { return size() == 0; }
std::basic_string<CharT> to_string() const
{
return std::basic_string<CharT>(m_buffer, m_size);
}
bool starts_with(BasicStringRef<CharT> prefix) const noexcept
{
return size() >= prefix.size()
&& std::char_traits<CharT>::compare(data(), prefix.data(), prefix.size()) == 0;
}
bool ends_with(BasicStringRef<CharT> suffix) const noexcept
{
return size() >= suffix.size()
&& std::char_traits<CharT>::compare(
data() + size() - suffix.size(), suffix.data(), suffix.size())
== 0;
}
std::basic_string<CharT> substr(size_t start, size_t count) const
{
return std::basic_string<CharT>(data() + start, std::min(size() - start, count));
}
};
template <class CharT>
inline std::basic_string<CharT> operator+(BasicStringRef<CharT> a, BasicStringRef<CharT> b)
{
std::basic_string<CharT> result;
result.reserve(a.size() + b.size());
result.insert(0, a.data(), a.size());
result.insert(a.size(), b.data(), b.size());
return result;
}
template <class CharT>
inline std::basic_string<CharT> operator+(const CharT* a, BasicStringRef<CharT> b)
{
return BasicStringRef<CharT>(a) + b;
}
template <class CharT>
inline std::basic_string<CharT> operator+(BasicStringRef<CharT> a, const CharT* b)
{
return a + BasicStringRef<CharT>(b);
}
template <class CharT>
inline std::basic_string<CharT> operator+(const std::basic_string<CharT>& a,
BasicStringRef<CharT> b)
{
return BasicStringRef<CharT>(a) + b;
}
template <class CharT>
inline std::basic_string<CharT> operator+(BasicStringRef<CharT> a,
const std::basic_string<CharT>& b)
{
return a + BasicStringRef<CharT>(b);
}
template <class CharT>
bool operator==(BasicStringRef<CharT> a, BasicStringRef<CharT> b)
{
return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
}
template <class CharT>
bool operator!=(BasicStringRef<CharT> a, BasicStringRef<CharT> b)
{
return !(a == b);
}
template <class CharT>
bool operator==(BasicStringRef<CharT> a, const char* b)
{
return a == BasicStringRef<CharT>(b);
}
template <class CharT>
bool operator!=(BasicStringRef<CharT> a, const char* b)
{
return a != BasicStringRef<CharT>(b);
}
typedef BasicStringRef<char> StringRef;
typedef BasicStringRef<wchar_t> WideStringRef;
std::string strprintf(const char* format, ...)
#ifndef WIN32
__attribute__((format(printf, 1, 2)))
#endif
;
std::string vstrprintf(const char* format, va_list args);
std::vector<std::string> split(StringRef str, char separator);
std::string hexify(const byte* data, size_t length);
void parse_hex(StringRef hex, byte* output, size_t len);
template <class ByteContainer>
inline std::string hexify(const ByteContainer& c)
{
return hexify(c.data(), c.size());
}
void base32_encode(const byte* input, size_t size, std::string& output);
void base32_decode(const char* input, size_t size, std::string& output);
std::string escape_nonprintable(const char* str, size_t size);
std::string case_fold(StringRef str);
using ManagedCharPointer = std::unique_ptr<const char, void (*)(const char*)>;
ManagedCharPointer transform(StringRef str, bool case_fold, bool nfc);
bool is_ascii(StringRef str);
} // namespace securefs
|