oxen-core/src/common/hex.h
Jason Rhinelander f09857de2b More string_view (mostly in wallet code)
This started out with a few string_view simplifications, but unwinding
the string_view calls resulted in quite a few changes.

- use constexpr string_view instead of macros for constants

- use constexpr ints for other macros instead of constants (to be
consistent with the string_view constexprs); also eliminated a couple of
unused variables.

- convert amount parsing to string_view, and rewrite it with comments to
be far less confusing.  (Previously it was remove a "." from a string,
chopping 0s off the end then putting them back on which was hard to
follow).

- fixed some not-quite-right amount parsing unit tests

- replace a bunch of string code (including lots of code allocating new
strings with .substr on a string) with std::string_view.

- avoid using C functions for strings

- convert epee http uri conversion methods to string_view (and fix one
typoed func name "conver" -> "convert")

- Add a `tools::hex_to_type` that converts hex directly into a (simple)
type, with hex and length verification for the type, and use it to
eliminate a bunch of intermediate std::string conversions.

- Convert a bunch of error-prone raw pointer string appends into
more type-safe `tools::view_guts(val)` calls.  (In particular view_guts
always gets the sizeof() correct, while the individual call could easily
put the wrong type in the `sizeof()`).
2020-07-02 12:55:28 -03:00

19 lines
729 B
C++

#pragma once
#include <lokimq/hex.h>
#include <type_traits>
#include "span.h" // epee
namespace tools {
// Reads a hex string directly into a trivially copyable type T without performing any temporary
// allocation. Returns false if the given string is not hex or does not match T in length,
// otherwise copies directly into `x` and returns true.
template <typename T, typename = std::enable_if_t<
!std::is_const_v<T> && (std::is_trivially_copyable_v<T> || epee::is_byte_spannable<T>)
>>
bool hex_to_type(std::string_view hex, T& x) {
if (!lokimq::is_hex(hex) || hex.size() != 2*sizeof(T))
return false;
lokimq::to_hex(hex.begin(), hex.end(), reinterpret_cast<char*>(&x));
return true;
}
}