Files
rippled/include/xrpl/protocol/STExchange.h
Bart 1d42c4f6de refactor: Remove unnecessary copyright notices already covered by LICENSE.md (#5929)
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.
2025-11-04 08:33:42 +00:00

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