libsshpp v0.1.7
Modern C++17 wrapper for libssh
Loading...
Searching...
No Matches
types.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later
2#pragma once
3
4#include <cstddef>
5#include <cstring>
6#include <memory>
7#include <string>
8#include <string_view>
9#include <type_traits>
10#include <vector>
11
12namespace sshpp {
13
16enum class Ownership { owning, borrowed };
17
19template <class T>
21public:
22 using element_type = T;
23
24 constexpr BasicByteSpan() noexcept = default;
25 constexpr BasicByteSpan(T* data, std::size_t size) noexcept : data_(data), size_(size) {}
26
27 template <class Byte, class = std::enable_if_t<sizeof(Byte) == 1 && std::is_const_v<T>>>
28 BasicByteSpan(const Byte* data, std::size_t size) noexcept
29 : data_(reinterpret_cast<T*>(data)), size_(size) {}
30
31 // Mutable view constructed from a contiguous non-const byte-sized buffer.
32 template <class Byte, class = std::enable_if_t<sizeof(Byte) == 1 && !std::is_const_v<T>>>
33 BasicByteSpan(Byte* data, std::size_t size) noexcept
34 : data_(reinterpret_cast<T*>(data)), size_(size) {}
35
36 constexpr T* data() const noexcept { return data_; }
37 constexpr std::size_t size() const noexcept { return size_; }
38 constexpr bool empty() const noexcept { return size_ == 0; }
39 constexpr T& operator[](std::size_t i) const noexcept { return data_[i]; }
40 constexpr T* begin() const noexcept { return data_; }
41 constexpr T* end() const noexcept { return data_ + size_; }
42
43 BasicByteSpan subspan(std::size_t offset, std::size_t count = static_cast<std::size_t>(-1)) const noexcept {
44 std::size_t n = (count == static_cast<std::size_t>(-1)) ? (size_ - offset) : count;
45 return BasicByteSpan(data_ + offset, n);
46 }
47
48private:
49 T* data_ = nullptr;
50 std::size_t size_ = 0;
51};
52
54class ByteView : public BasicByteSpan<const std::byte> {
55public:
57 constexpr ByteView() noexcept = default;
58 ByteView(std::string_view sv) noexcept : BasicByteSpan(sv.data(), sv.size()) {}
59 ByteView(const std::vector<std::byte>& v) noexcept : BasicByteSpan(v.data(), v.size()) {}
60
61 std::string_view as_string_view() const noexcept {
62 return {reinterpret_cast<const char*>(data()), size()};
63 }
64};
65
67class MutableByteView : public BasicByteSpan<std::byte> {
68public:
70 constexpr MutableByteView() noexcept = default;
71 MutableByteView(std::vector<std::byte>& v) noexcept : BasicByteSpan(v.data(), v.size()) {}
72};
73
77public:
78 RemotePath() = default;
79 RemotePath(std::string p) : path_(std::move(p)) {}
80 RemotePath(const char* p) : path_(p) {}
81
82 const std::string& str() const noexcept { return path_; }
83 bool empty() const noexcept { return path_.empty(); }
84
85 RemotePath operator/(std::string_view child) const {
86 std::string result = path_;
87 if (!result.empty() && result.back() != '/' && !child.empty() && child.front() != '/') {
88 result.push_back('/');
89 }
90 result.append(child);
91 return RemotePath{std::move(result)};
92 }
93
94 friend bool operator==(const RemotePath& a, const RemotePath& b) noexcept {
95 return a.path_ == b.path_;
96 }
97 friend bool operator!=(const RemotePath& a, const RemotePath& b) noexcept { return !(a == b); }
98
99private:
100 std::string path_;
101};
102
103namespace detail {
104
106template <class T>
107struct ZeroingAllocator {
108 using value_type = T;
109
110 ZeroingAllocator() noexcept = default;
111 template <class U> ZeroingAllocator(const ZeroingAllocator<U>&) noexcept {}
112
113 T* allocate(std::size_t n) {
114 return static_cast<T*>(::operator new(n * sizeof(T)));
115 }
116 void deallocate(T* p, std::size_t n) noexcept {
117 if (p != nullptr && n != 0) {
118 volatile auto* vp = reinterpret_cast<volatile unsigned char*>(p);
119 for (std::size_t i = 0; i < n * sizeof(T); ++i) vp[i] = 0;
120 }
121 ::operator delete(p);
122 }
123
124 template <class U> bool operator==(const ZeroingAllocator<U>&) const noexcept { return true; }
125 template <class U> bool operator!=(const ZeroingAllocator<U>&) const noexcept { return false; }
126};
127
128} // namespace detail
129
133public:
134 using storage_type = std::basic_string<char, std::char_traits<char>, detail::ZeroingAllocator<char>>;
135
136 SecureString() = default;
137 SecureString(const char* s) : data_(s) {}
138 SecureString(std::string_view sv) : data_(sv.begin(), sv.end()) {}
139 SecureString(std::string s) : data_(s.begin(), s.end()) {
140 // Best effort: scrub the caller's temporary now that we've copied it.
141 volatile auto* vp = reinterpret_cast<volatile char*>(s.data());
142 for (std::size_t i = 0; i < s.size(); ++i) vp[i] = 0;
143 }
144
145 const char* c_str() const noexcept { return data_.c_str(); }
146 std::size_t size() const noexcept { return data_.size(); }
147 bool empty() const noexcept { return data_.empty(); }
148 std::string_view view() const noexcept { return {data_.data(), data_.size()}; }
149
150private:
151 storage_type data_;
152};
153
154} // namespace sshpp
A minimal span-like non-owning view over contiguous bytes (C++17 has no std::span).
Definition types.hpp:20
T element_type
Definition types.hpp:22
constexpr T * begin() const noexcept
Definition types.hpp:40
BasicByteSpan(const Byte *data, std::size_t size) noexcept
Definition types.hpp:28
constexpr bool empty() const noexcept
Definition types.hpp:38
BasicByteSpan subspan(std::size_t offset, std::size_t count=static_cast< std::size_t >(-1)) const noexcept
Definition types.hpp:43
constexpr BasicByteSpan() noexcept=default
constexpr T * end() const noexcept
Definition types.hpp:41
constexpr std::size_t size() const noexcept
Definition types.hpp:37
BasicByteSpan(Byte *data, std::size_t size) noexcept
Definition types.hpp:33
constexpr T & operator[](std::size_t i) const noexcept
Definition types.hpp:39
constexpr T * data() const noexcept
Definition types.hpp:36
Input byte range. Implicitly constructible from std::string_view / std::vector<std::byte>.
Definition types.hpp:54
ByteView(const std::vector< std::byte > &v) noexcept
Definition types.hpp:59
std::string_view as_string_view() const noexcept
Definition types.hpp:61
constexpr BasicByteSpan() noexcept=default
constexpr ByteView() noexcept=default
Output byte range (caller-owned, mutable buffer to write into).
Definition types.hpp:67
constexpr MutableByteView() noexcept=default
Definition types.hpp:76
friend bool operator!=(const RemotePath &a, const RemotePath &b) noexcept
Definition types.hpp:97
RemotePath(std::string p)
Definition types.hpp:79
RemotePath()=default
RemotePath operator/(std::string_view child) const
Definition types.hpp:85
bool empty() const noexcept
Definition types.hpp:83
const std::string & str() const noexcept
Definition types.hpp:82
RemotePath(const char *p)
Definition types.hpp:80
friend bool operator==(const RemotePath &a, const RemotePath &b) noexcept
Definition types.hpp:94
Definition types.hpp:132
SecureString(const char *s)
Definition types.hpp:137
SecureString(std::string_view sv)
Definition types.hpp:138
SecureString(std::string s)
Definition types.hpp:139
std::string_view view() const noexcept
Definition types.hpp:148
std::basic_string< char, std::char_traits< char >, detail::ZeroingAllocator< char > > storage_type
Definition types.hpp:134
std::size_t size() const noexcept
Definition types.hpp:146
bool empty() const noexcept
Definition types.hpp:147
const char * c_str() const noexcept
Definition types.hpp:145
SecureString()=default
Definition auth.hpp:18
Ownership
Definition types.hpp:16
Definition error.hpp:110