Skip to content

Commit

Permalink
Add support for integer key formats
Browse files Browse the repository at this point in the history
  • Loading branch information
vtnerd committed Jun 20, 2024
1 parent f2783dc commit 87db8c7
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 11 deletions.
19 changes: 12 additions & 7 deletions contrib/epee/include/serialization/wire/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@

#include "serialization/wire/traits.h"

//! A required field with the same key name and C/C++ name
#define WIRE_FIELD_ID(id, name) \
::wire::field< id >( #name , std::ref( self . name ))

//! A required field has the same key name and C/C++ name
#define WIRE_FIELD(name) \
::wire::field( #name , std::ref( self . name ))
#define WIRE_FIELD(name) \
WIRE_FIELD_ID(0, name)

//! A required field has the same key name and C/C++ name AND is cheap to copy (faster output).
#define WIRE_FIELD_COPY(name) \
Expand Down Expand Up @@ -92,7 +96,7 @@ namespace wire
Basically each input/output format needs a unique type so that the compiler
knows how to "dispatch" the read/write calls. */
template<typename T, bool Required>
template<typename T, bool Required, unsigned I = 0>
struct field_
{
using value_type = unwrap_reference_t<T>;
Expand All @@ -103,6 +107,7 @@ namespace wire

static constexpr bool is_required() noexcept { return Required && !optional_on_empty(); }
static constexpr std::size_t count() noexcept { return 1; }
static constexpr unsigned id() noexcept { return I; }

const char* name;
T value;
Expand All @@ -112,15 +117,15 @@ namespace wire
};

//! Links `name` to `value`. Use `std::ref` if de-serializing.
template<typename T>
constexpr inline field_<T, true> field(const char* name, T value)
template<unsigned I = 0, typename T = void>
constexpr inline field_<T, true, I> field(const char* name, T value)
{
return {name, std::move(value)};
}

//! Links `name` to optional `value`. Use `std::ref` if de-serializing.
template<typename T>
constexpr inline field_<T, false> optional_field(const char* name, T value)
template<unsigned I = 0, typename T = void>
constexpr inline field_<T, false, I> optional_field(const char* name, T value)
{
return {name, std::move(value)};
}
Expand Down
10 changes: 6 additions & 4 deletions contrib/epee/include/serialization/wire/read.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ namespace wire
struct key_map
{
const char* name;
unsigned id; //<! For integer key formats;
};

//! \return Maximum read depth for both objects and arrays before erroring
Expand Down Expand Up @@ -382,16 +383,16 @@ namespace wire_read
array_unchecked(source, dest, min_element_size, max_element_count);
}

template<typename T>
inline void reset_field(wire::field_<T, true>& dest)
template<typename T, unsigned I>
inline void reset_field(wire::field_<T, true, I>& dest)
{
// array fields are always optional, see `wire/field.h`
if (dest.optional_on_empty())
wire::clear(dest.get_value());
}

template<typename T>
inline void reset_field(wire::field_<T, false>& dest)
template<typename T, unsigned I>
inline void reset_field(wire::field_<T, false, I>& dest)
{
dest.get_value().reset();
}
Expand Down Expand Up @@ -437,6 +438,7 @@ namespace wire_read
std::size_t set_mapping(std::size_t index, wire::reader::key_map (&map)[N]) noexcept
{
our_index_ = index;
map[index].id = field_.id();
map[index].name = field_.name;
return index + count();
}
Expand Down

0 comments on commit 87db8c7

Please sign in to comment.