Skip to content

Commit faa3ec2

Browse files
author
MarcoFalke
committed
span: Add std::byte helpers
Also, add Span<std::byte> interface to strencondings.
1 parent fa18038 commit faa3ec2

File tree

5 files changed

+56
-11
lines changed

5 files changed

+56
-11
lines changed

src/span.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ class Span
180180
return m_data[m_size - 1];
181181
}
182182
constexpr std::size_t size() const noexcept { return m_size; }
183+
constexpr std::size_t size_bytes() const noexcept { return sizeof(C) * m_size; }
183184
constexpr bool empty() const noexcept { return size() == 0; }
184185
CONSTEXPR_IF_NOT_DEBUG C& operator[](std::size_t pos) const noexcept
185186
{
@@ -236,11 +237,35 @@ T& SpanPopBack(Span<T>& span)
236237
return back;
237238
}
238239

240+
// From C++20 as_bytes and as_writeable_bytes
241+
template <typename T>
242+
Span<const std::byte> AsBytes(Span<T> s) noexcept
243+
{
244+
return {reinterpret_cast<const std::byte*>(s.data()), s.size_bytes()};
245+
}
246+
template <typename T>
247+
Span<std::byte> AsWritableBytes(Span<T> s) noexcept
248+
{
249+
return {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()};
250+
}
251+
252+
template <typename V>
253+
Span<const std::byte> MakeByteSpan(V&& v) noexcept
254+
{
255+
return AsBytes(MakeSpan(std::forward<V>(v)));
256+
}
257+
template <typename V>
258+
Span<std::byte> MakeWritableByteSpan(V&& v) noexcept
259+
{
260+
return AsWritableBytes(MakeSpan(std::forward<V>(v)));
261+
}
262+
239263
// Helper functions to safely cast to unsigned char pointers.
240264
inline unsigned char* UCharCast(char* c) { return (unsigned char*)c; }
241265
inline unsigned char* UCharCast(unsigned char* c) { return c; }
242266
inline const unsigned char* UCharCast(const char* c) { return (unsigned char*)c; }
243267
inline const unsigned char* UCharCast(const unsigned char* c) { return c; }
268+
inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast<const unsigned char*>(c); }
244269

245270
// Helper function to safely convert a Span to a Span<[const] unsigned char>.
246271
template <typename T> constexpr auto UCharSpanCast(Span<T> s) -> Span<typename std::remove_pointer<decltype(UCharCast(s.data()))>::type> { return {UCharCast(s.data()), s.size()}; }

src/test/base64_tests.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ BOOST_AUTO_TEST_CASE(base64_testvectors)
2323
BOOST_CHECK_EQUAL(strDec, vstrIn[i]);
2424
}
2525

26+
{
27+
const std::vector<uint8_t> in_u{0xff, 0x01, 0xff};
28+
const std::vector<std::byte> in_b{std::byte{0xff}, std::byte{0x01}, std::byte{0xff}};
29+
const std::string in_s{"\xff\x01\xff"};
30+
const std::string out_exp{"/wH/"};
31+
BOOST_CHECK_EQUAL(EncodeBase64(in_u), out_exp);
32+
BOOST_CHECK_EQUAL(EncodeBase64(in_b), out_exp);
33+
BOOST_CHECK_EQUAL(EncodeBase64(in_s), out_exp);
34+
}
35+
2636
// Decoding strings with embedded NUL characters should fail
2737
bool failure;
2838
(void)DecodeBase64("invalid\0"s, &failure);

src/test/util_tests.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,25 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
151151
HexStr(Span<const unsigned char>(ParseHex_expected, ParseHex_expected)),
152152
"");
153153

154-
std::vector<unsigned char> ParseHex_vec(ParseHex_expected, ParseHex_expected + 5);
154+
{
155+
const std::vector<char> in_s{ParseHex_expected, ParseHex_expected + 5};
156+
const Span<const uint8_t> in_u{MakeUCharSpan(in_s)};
157+
const Span<const std::byte> in_b{MakeByteSpan(in_s)};
158+
const std::string out_exp{"04678afdb0"};
159+
160+
BOOST_CHECK_EQUAL(HexStr(in_u), out_exp);
161+
BOOST_CHECK_EQUAL(HexStr(in_s), out_exp);
162+
BOOST_CHECK_EQUAL(HexStr(in_b), out_exp);
163+
}
164+
}
155165

156-
BOOST_CHECK_EQUAL(
157-
HexStr(ParseHex_vec),
158-
"04678afdb0"
159-
);
166+
BOOST_AUTO_TEST_CASE(span_write_bytes)
167+
{
168+
std::array mut_arr{uint8_t{0xaa}, uint8_t{0xbb}};
169+
const auto mut_bytes{MakeWritableByteSpan(mut_arr)};
170+
mut_bytes[1] = std::byte{0x11};
171+
BOOST_CHECK_EQUAL(mut_arr.at(0), 0xaa);
172+
BOOST_CHECK_EQUAL(mut_arr.at(1), 0x11);
160173
}
161174

162175
BOOST_AUTO_TEST_CASE(util_Join)

src/util/strencodings.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,6 @@ std::string EncodeBase64(Span<const unsigned char> input)
138138
return str;
139139
}
140140

141-
std::string EncodeBase64(const std::string& str)
142-
{
143-
return EncodeBase64(MakeUCharSpan(str));
144-
}
145-
146141
std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid)
147142
{
148143
static const int decode64_table[256] =

src/util/strencodings.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ bool IsHexNumber(const std::string& str);
5050
std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid = nullptr);
5151
std::string DecodeBase64(const std::string& str, bool* pf_invalid = nullptr);
5252
std::string EncodeBase64(Span<const unsigned char> input);
53-
std::string EncodeBase64(const std::string& str);
53+
inline std::string EncodeBase64(Span<const std::byte> input) { return EncodeBase64(MakeUCharSpan(input)); }
54+
inline std::string EncodeBase64(const std::string& str) { return EncodeBase64(MakeUCharSpan(str)); }
5455
std::vector<unsigned char> DecodeBase32(const char* p, bool* pf_invalid = nullptr);
5556
std::string DecodeBase32(const std::string& str, bool* pf_invalid = nullptr);
5657

@@ -189,6 +190,7 @@ std::optional<T> ToIntegral(const std::string& str)
189190
*/
190191
std::string HexStr(const Span<const uint8_t> s);
191192
inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); }
193+
inline std::string HexStr(const Span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); }
192194

193195
/**
194196
* Format a paragraph of text to a fixed width, adding spaces for

0 commit comments

Comments
 (0)