mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-05 03:35:51 +00:00
Per XLS-0095, we are taking steps to rename ripple(d) to xrpl(d). This change specifically removes all copyright notices referencing Ripple, XRPLF, and certain affiliated contributors upon mutual agreement, so the notice in the LICENSE.md file applies throughout. Copyright notices referencing external contributions remain as-is. Duplicate verbiage is also removed.
161 lines
3.5 KiB
C++
161 lines
3.5 KiB
C++
#ifndef XRPL_PROTOCOL_STEXCHANGE_H_INCLUDED
|
|
#define XRPL_PROTOCOL_STEXCHANGE_H_INCLUDED
|
|
|
|
#include <xrpl/basics/Blob.h>
|
|
#include <xrpl/basics/Buffer.h>
|
|
#include <xrpl/basics/Slice.h>
|
|
#include <xrpl/basics/contract.h>
|
|
#include <xrpl/protocol/SField.h>
|
|
#include <xrpl/protocol/STBlob.h>
|
|
#include <xrpl/protocol/STInteger.h>
|
|
#include <xrpl/protocol/STObject.h>
|
|
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <stdexcept>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
namespace ripple {
|
|
|
|
/** Convert between serialized type U and C++ type T. */
|
|
template <class U, class T>
|
|
struct STExchange;
|
|
|
|
template <class U, class T>
|
|
struct STExchange<STInteger<U>, T>
|
|
{
|
|
explicit STExchange() = default;
|
|
|
|
using value_type = U;
|
|
|
|
static void
|
|
get(std::optional<T>& t, STInteger<U> const& u)
|
|
{
|
|
t = u.value();
|
|
}
|
|
|
|
static std::unique_ptr<STInteger<U>>
|
|
set(SField const& f, T const& t)
|
|
{
|
|
return std::make_unique<STInteger<U>>(f, t);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct STExchange<STBlob, Slice>
|
|
{
|
|
explicit STExchange() = default;
|
|
|
|
using value_type = Slice;
|
|
|
|
static void
|
|
get(std::optional<value_type>& t, STBlob const& u)
|
|
{
|
|
t.emplace(u.data(), u.size());
|
|
}
|
|
|
|
static std::unique_ptr<STBlob>
|
|
set(TypedField<STBlob> const& f, Slice const& t)
|
|
{
|
|
return std::make_unique<STBlob>(f, t.data(), t.size());
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct STExchange<STBlob, Buffer>
|
|
{
|
|
explicit STExchange() = default;
|
|
|
|
using value_type = Buffer;
|
|
|
|
static void
|
|
get(std::optional<Buffer>& t, STBlob const& u)
|
|
{
|
|
t.emplace(u.data(), u.size());
|
|
}
|
|
|
|
static std::unique_ptr<STBlob>
|
|
set(TypedField<STBlob> const& f, Buffer const& t)
|
|
{
|
|
return std::make_unique<STBlob>(f, t.data(), t.size());
|
|
}
|
|
|
|
static std::unique_ptr<STBlob>
|
|
set(TypedField<STBlob> const& f, Buffer&& t)
|
|
{
|
|
return std::make_unique<STBlob>(f, std::move(t));
|
|
}
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
/** Return the value of a field in an STObject as a given type. */
|
|
/** @{ */
|
|
template <class T, class U>
|
|
std::optional<T>
|
|
get(STObject const& st, TypedField<U> const& f)
|
|
{
|
|
std::optional<T> t;
|
|
STBase const* const b = st.peekAtPField(f);
|
|
if (!b)
|
|
return t;
|
|
auto const id = b->getSType();
|
|
if (id == STI_NOTPRESENT)
|
|
return t;
|
|
auto const u = dynamic_cast<U const*>(b);
|
|
// This should never happen
|
|
if (!u)
|
|
Throw<std::runtime_error>("Wrong field type");
|
|
STExchange<U, T>::get(t, *u);
|
|
return t;
|
|
}
|
|
|
|
template <class U>
|
|
std::optional<typename STExchange<U, typename U::value_type>::value_type>
|
|
get(STObject const& st, TypedField<U> const& f)
|
|
{
|
|
return get<typename U::value_type>(st, f);
|
|
}
|
|
/** @} */
|
|
|
|
/** Set a field value in an STObject. */
|
|
template <class U, class T>
|
|
void
|
|
set(STObject& st, TypedField<U> const& f, T&& t)
|
|
{
|
|
st.set(STExchange<U, typename std::decay<T>::type>::set(
|
|
f, std::forward<T>(t)));
|
|
}
|
|
|
|
/** Set a blob field using an init function. */
|
|
template <class Init>
|
|
void
|
|
set(STObject& st, TypedField<STBlob> const& f, std::size_t size, Init&& init)
|
|
{
|
|
st.set(std::make_unique<STBlob>(f, size, init));
|
|
}
|
|
|
|
/** Set a blob field from data. */
|
|
template <class = void>
|
|
void
|
|
set(STObject& st,
|
|
TypedField<STBlob> const& f,
|
|
void const* data,
|
|
std::size_t size)
|
|
{
|
|
st.set(std::make_unique<STBlob>(f, data, size));
|
|
}
|
|
|
|
/** Remove a field in an STObject. */
|
|
template <class U>
|
|
void
|
|
erase(STObject& st, TypedField<U> const& f)
|
|
{
|
|
st.makeFieldAbsent(f);
|
|
}
|
|
|
|
} // namespace ripple
|
|
|
|
#endif
|