mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
merge bitcoin#23451: Add std::byte helpers
This commit is contained in:
parent
dba0dc9501
commit
bb8bd9a94d
@ -139,7 +139,7 @@ public:
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
unsigned int len = ::ReadCompactSize(s);
|
||||
const unsigned int len(::ReadCompactSize(s));
|
||||
if (len <= SIZE) {
|
||||
s.read((char*)vch, len);
|
||||
if (len != size()) {
|
||||
@ -147,9 +147,7 @@ public:
|
||||
}
|
||||
} else {
|
||||
// invalid pubkey, skip available data
|
||||
char dummy;
|
||||
while (len--)
|
||||
s.read(&dummy, 1);
|
||||
s.ignore(len);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
25
src/span.h
25
src/span.h
@ -180,6 +180,7 @@ public:
|
||||
return m_data[m_size - 1];
|
||||
}
|
||||
constexpr std::size_t size() const noexcept { return m_size; }
|
||||
constexpr std::size_t size_bytes() const noexcept { return sizeof(C) * m_size; }
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
CONSTEXPR_IF_NOT_DEBUG C& operator[](std::size_t pos) const noexcept
|
||||
{
|
||||
@ -236,11 +237,35 @@ T& SpanPopBack(Span<T>& span)
|
||||
return back;
|
||||
}
|
||||
|
||||
// From C++20 as_bytes and as_writeable_bytes
|
||||
template <typename T>
|
||||
Span<const std::byte> AsBytes(Span<T> s) noexcept
|
||||
{
|
||||
return {reinterpret_cast<const std::byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
template <typename T>
|
||||
Span<std::byte> AsWritableBytes(Span<T> s) noexcept
|
||||
{
|
||||
return {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
Span<const std::byte> MakeByteSpan(V&& v) noexcept
|
||||
{
|
||||
return AsBytes(MakeSpan(std::forward<V>(v)));
|
||||
}
|
||||
template <typename V>
|
||||
Span<std::byte> MakeWritableByteSpan(V&& v) noexcept
|
||||
{
|
||||
return AsWritableBytes(MakeSpan(std::forward<V>(v)));
|
||||
}
|
||||
|
||||
// Helper functions to safely cast to unsigned char pointers.
|
||||
inline unsigned char* UCharCast(char* c) { return (unsigned char*)c; }
|
||||
inline unsigned char* UCharCast(unsigned char* c) { return c; }
|
||||
inline const unsigned char* UCharCast(const char* c) { return (unsigned char*)c; }
|
||||
inline const unsigned char* UCharCast(const unsigned char* c) { return c; }
|
||||
inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast<const unsigned char*>(c); }
|
||||
|
||||
// Helper function to safely convert a Span to a Span<[const] unsigned char>.
|
||||
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()}; }
|
||||
|
@ -230,7 +230,7 @@ public:
|
||||
: nType{nTypeIn},
|
||||
nVersion{nVersionIn} {}
|
||||
|
||||
explicit CDataStream(Span<const uint8_t> sp, int nTypeIn, int nVersionIn)
|
||||
explicit CDataStream(Span<const value_type> sp, int nTypeIn, int nVersionIn)
|
||||
: vch(sp.data(), sp.data() + sp.size()),
|
||||
nType{nTypeIn},
|
||||
nVersion{nVersionIn} {}
|
||||
@ -258,17 +258,17 @@ public:
|
||||
iterator end() { return vch.end(); }
|
||||
size_type size() const { return vch.size() - nReadPos; }
|
||||
bool empty() const { return vch.size() == nReadPos; }
|
||||
void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); }
|
||||
void resize(size_type n, value_type c = value_type{}) { vch.resize(n + nReadPos, c); }
|
||||
void reserve(size_type n) { vch.reserve(n + nReadPos); }
|
||||
const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; }
|
||||
reference operator[](size_type pos) { return vch[pos + nReadPos]; }
|
||||
void clear() { vch.clear(); nReadPos = 0; }
|
||||
iterator insert(iterator it, const uint8_t x) { return vch.insert(it, x); }
|
||||
void insert(iterator it, size_type n, const uint8_t x) { vch.insert(it, n, x); }
|
||||
iterator insert(iterator it, const value_type x) { return vch.insert(it, x); }
|
||||
void insert(iterator it, size_type n, const value_type x) { vch.insert(it, n, x); }
|
||||
value_type* data() { return vch.data() + nReadPos; }
|
||||
const value_type* data() const { return vch.data() + nReadPos; }
|
||||
|
||||
void insert(iterator it, std::vector<uint8_t>::const_iterator first, std::vector<uint8_t>::const_iterator last)
|
||||
void insert(iterator it, std::vector<value_type>::const_iterator first, std::vector<value_type>::const_iterator last)
|
||||
{
|
||||
if (last == first) return;
|
||||
assert(last - first > 0);
|
||||
@ -282,7 +282,7 @@ public:
|
||||
vch.insert(it, first, last);
|
||||
}
|
||||
|
||||
void insert(iterator it, const char* first, const char* last)
|
||||
void insert(iterator it, const value_type* first, const value_type* last)
|
||||
{
|
||||
if (last == first) return;
|
||||
assert(last - first > 0);
|
||||
|
@ -24,6 +24,16 @@ BOOST_AUTO_TEST_CASE(base64_testvectors)
|
||||
BOOST_CHECK_EQUAL(strDec, vstrIn[i]);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<uint8_t> in_u{0xff, 0x01, 0xff};
|
||||
const std::vector<std::byte> in_b{std::byte{0xff}, std::byte{0x01}, std::byte{0xff}};
|
||||
const std::string in_s{"\xff\x01\xff"};
|
||||
const std::string out_exp{"/wH/"};
|
||||
BOOST_CHECK_EQUAL(EncodeBase64(in_u), out_exp);
|
||||
BOOST_CHECK_EQUAL(EncodeBase64(in_b), out_exp);
|
||||
BOOST_CHECK_EQUAL(EncodeBase64(in_s), out_exp);
|
||||
}
|
||||
|
||||
// Decoding strings with embedded NUL characters should fail
|
||||
bool failure;
|
||||
(void)DecodeBase64("invalid\0"s, &failure);
|
||||
|
@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
|
||||
ds.Xor(key);
|
||||
BOOST_CHECK_EQUAL(
|
||||
std::string(expected_xor.begin(), expected_xor.end()),
|
||||
std::string(ds.begin(), ds.end()));
|
||||
ds.str());
|
||||
|
||||
in.push_back('\x0f');
|
||||
in.push_back('\xf0');
|
||||
@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
|
||||
ds.Xor(key);
|
||||
BOOST_CHECK_EQUAL(
|
||||
std::string(expected_xor.begin(), expected_xor.end()),
|
||||
std::string(ds.begin(), ds.end()));
|
||||
ds.str());
|
||||
|
||||
// Multi character key
|
||||
|
||||
@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
|
||||
ds.Xor(key);
|
||||
BOOST_CHECK_EQUAL(
|
||||
std::string(expected_xor.begin(), expected_xor.end()),
|
||||
std::string(ds.begin(), ds.end()));
|
||||
ds.str());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(streams_buffered_file)
|
||||
|
@ -186,12 +186,25 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
|
||||
HexStr(Span<const unsigned char>(ParseHex_expected, ParseHex_expected)),
|
||||
"");
|
||||
|
||||
std::vector<unsigned char> ParseHex_vec(ParseHex_expected, ParseHex_expected + 5);
|
||||
{
|
||||
const std::vector<char> in_s{ParseHex_expected, ParseHex_expected + 5};
|
||||
const Span<const uint8_t> in_u{MakeUCharSpan(in_s)};
|
||||
const Span<const std::byte> in_b{MakeByteSpan(in_s)};
|
||||
const std::string out_exp{"04678afdb0"};
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
HexStr(ParseHex_vec),
|
||||
"04678afdb0"
|
||||
);
|
||||
BOOST_CHECK_EQUAL(HexStr(in_u), out_exp);
|
||||
BOOST_CHECK_EQUAL(HexStr(in_s), out_exp);
|
||||
BOOST_CHECK_EQUAL(HexStr(in_b), out_exp);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(span_write_bytes)
|
||||
{
|
||||
std::array mut_arr{uint8_t{0xaa}, uint8_t{0xbb}};
|
||||
const auto mut_bytes{MakeWritableByteSpan(mut_arr)};
|
||||
mut_bytes[1] = std::byte{0x11};
|
||||
BOOST_CHECK_EQUAL(mut_arr.at(0), 0xaa);
|
||||
BOOST_CHECK_EQUAL(mut_arr.at(1), 0x11);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(util_Join)
|
||||
|
@ -138,11 +138,6 @@ std::string EncodeBase64(Span<const unsigned char> input)
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string EncodeBase64(const std::string& str)
|
||||
{
|
||||
return EncodeBase64(MakeUCharSpan(str));
|
||||
}
|
||||
|
||||
std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid)
|
||||
{
|
||||
static const int8_t decode64_table[256]{
|
||||
|
@ -49,8 +49,8 @@ bool IsHexNumber(const std::string& str);
|
||||
std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid = nullptr);
|
||||
std::string DecodeBase64(const std::string& str, bool* pf_invalid = nullptr);
|
||||
std::string EncodeBase64(Span<const unsigned char> input);
|
||||
std::string EncodeBase64(const std::string& str);
|
||||
|
||||
inline std::string EncodeBase64(Span<const std::byte> input) { return EncodeBase64(MakeUCharSpan(input)); }
|
||||
inline std::string EncodeBase64(const std::string& str) { return EncodeBase64(MakeUCharSpan(str)); }
|
||||
std::vector<unsigned char> DecodeBase32(const char* p, bool* pf_invalid = nullptr);
|
||||
std::string DecodeBase32(const std::string& str, bool* pf_invalid = nullptr);
|
||||
|
||||
@ -194,6 +194,7 @@ std::optional<T> ToIntegral(const std::string& str)
|
||||
*/
|
||||
std::string HexStr(const Span<const uint8_t> s);
|
||||
inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); }
|
||||
inline std::string HexStr(const Span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); }
|
||||
|
||||
/**
|
||||
* Format a paragraph of text to a fixed width, adding spaces for
|
||||
|
Loading…
Reference in New Issue
Block a user