mirror of
https://github.com/XRPLF/rippled.git
synced 2026-03-16 01:32:23 +00:00
224 lines
5.8 KiB
C++
224 lines
5.8 KiB
C++
#include <xrpl/basics/contract.h>
|
|
#include <xrpl/beast/utility/instrumentation.h>
|
|
#include <xrpl/protocol/SField.h>
|
|
#include <xrpl/protocol/STAccount.h>
|
|
#include <xrpl/protocol/STAmount.h>
|
|
#include <xrpl/protocol/STArray.h>
|
|
#include <xrpl/protocol/STBase.h>
|
|
#include <xrpl/protocol/STBitString.h>
|
|
#include <xrpl/protocol/STBlob.h>
|
|
#include <xrpl/protocol/STCurrency.h>
|
|
#include <xrpl/protocol/STInteger.h>
|
|
#include <xrpl/protocol/STIssue.h>
|
|
#include <xrpl/protocol/STNumber.h>
|
|
#include <xrpl/protocol/STObject.h>
|
|
#include <xrpl/protocol/STPathSet.h>
|
|
#include <xrpl/protocol/STVector256.h>
|
|
#include <xrpl/protocol/STXChainBridge.h>
|
|
#include <xrpl/protocol/Serializer.h>
|
|
#include <xrpl/protocol/detail/STVar.h>
|
|
|
|
#include <stdexcept>
|
|
#include <tuple>
|
|
#include <type_traits>
|
|
|
|
namespace xrpl {
|
|
namespace detail {
|
|
|
|
defaultObject_t defaultObject;
|
|
nonPresentObject_t nonPresentObject;
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
STVar::~STVar()
|
|
{
|
|
destroy();
|
|
}
|
|
|
|
STVar::STVar(STVar const& other)
|
|
{
|
|
if (other.p_ != nullptr)
|
|
p_ = other.p_->copy(max_size, &d_);
|
|
}
|
|
|
|
STVar::STVar(STVar&& other)
|
|
{
|
|
if (other.on_heap())
|
|
{
|
|
p_ = other.p_;
|
|
other.p_ = nullptr;
|
|
}
|
|
else
|
|
{
|
|
p_ = other.p_->move(max_size, &d_);
|
|
}
|
|
}
|
|
|
|
STVar&
|
|
STVar::operator=(STVar const& rhs)
|
|
{
|
|
if (&rhs != this)
|
|
{
|
|
destroy();
|
|
if (rhs.p_)
|
|
p_ = rhs.p_->copy(max_size, &d_);
|
|
else
|
|
p_ = nullptr;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
STVar&
|
|
STVar::operator=(STVar&& rhs)
|
|
{
|
|
if (&rhs != this)
|
|
{
|
|
destroy();
|
|
if (rhs.on_heap())
|
|
{
|
|
p_ = rhs.p_;
|
|
rhs.p_ = nullptr;
|
|
}
|
|
else
|
|
{
|
|
p_ = rhs.p_->move(max_size, &d_);
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
STVar::STVar(defaultObject_t, SField const& name) : STVar(name.fieldType, name)
|
|
{
|
|
}
|
|
|
|
STVar::STVar(nonPresentObject_t, SField const& name) : STVar(STI_NOTPRESENT, name)
|
|
{
|
|
}
|
|
|
|
STVar::STVar(SerialIter& sit, SField const& name, int depth)
|
|
{
|
|
if (depth > 10)
|
|
Throw<std::runtime_error>("Maximum nesting depth of STVar exceeded");
|
|
constructST(name.fieldType, depth, sit, name);
|
|
}
|
|
|
|
STVar::STVar(SerializedTypeID id, SField const& name)
|
|
{
|
|
XRPL_ASSERT(
|
|
(id == STI_NOTPRESENT) || (id == name.fieldType),
|
|
"xrpl::detail::STVar::STVar(SerializedTypeID) : valid type input");
|
|
constructST(id, 0, name);
|
|
}
|
|
|
|
void
|
|
STVar::destroy()
|
|
{
|
|
if (on_heap())
|
|
delete p_;
|
|
else
|
|
p_->~STBase();
|
|
|
|
p_ = nullptr;
|
|
}
|
|
|
|
template <typename... Args>
|
|
requires ValidConstructSTArgs<Args...>
|
|
void
|
|
STVar::constructST(SerializedTypeID id, int depth, Args&&... args)
|
|
{
|
|
auto constructWithDepth = [&]<typename T>() {
|
|
if constexpr (std::is_same_v<std::tuple<std::remove_cvref_t<Args>...>, std::tuple<SField>>)
|
|
{
|
|
construct<T>(std::forward<Args>(args)...);
|
|
}
|
|
else if constexpr (
|
|
std::
|
|
is_same_v<std::tuple<std::remove_cvref_t<Args>...>, std::tuple<SerialIter, SField>>)
|
|
{
|
|
construct<T>(std::forward<Args>(args)..., depth);
|
|
}
|
|
else
|
|
{
|
|
constexpr bool alwaysFalse = !std::is_same_v<std::tuple<Args...>, std::tuple<Args...>>;
|
|
static_assert(alwaysFalse, "Invalid STVar constructor arguments");
|
|
}
|
|
};
|
|
|
|
switch (id)
|
|
{
|
|
case STI_NOTPRESENT: {
|
|
// Last argument is always SField
|
|
SField const& field = std::get<sizeof...(args) - 1>(std::forward_as_tuple(args...));
|
|
construct<STBase>(field);
|
|
return;
|
|
}
|
|
case STI_UINT8:
|
|
construct<STUInt8>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_UINT16:
|
|
construct<STUInt16>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_UINT32:
|
|
construct<STUInt32>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_UINT64:
|
|
construct<STUInt64>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_AMOUNT:
|
|
construct<STAmount>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_NUMBER:
|
|
construct<STNumber>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_UINT128:
|
|
construct<STUInt128>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_UINT160:
|
|
construct<STUInt160>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_UINT192:
|
|
construct<STUInt192>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_UINT256:
|
|
construct<STUInt256>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_INT32:
|
|
construct<STInt32>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_VECTOR256:
|
|
construct<STVector256>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_VL:
|
|
construct<STBlob>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_ACCOUNT:
|
|
construct<STAccount>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_PATHSET:
|
|
construct<STPathSet>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_OBJECT:
|
|
constructWithDepth.template operator()<STObject>();
|
|
return;
|
|
case STI_ARRAY:
|
|
constructWithDepth.template operator()<STArray>();
|
|
return;
|
|
case STI_ISSUE:
|
|
construct<STIssue>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_XCHAIN_BRIDGE:
|
|
construct<STXChainBridge>(std::forward<Args>(args)...);
|
|
return;
|
|
case STI_CURRENCY:
|
|
construct<STCurrency>(std::forward<Args>(args)...);
|
|
return;
|
|
default:
|
|
Throw<std::runtime_error>("Unknown object type");
|
|
}
|
|
}
|
|
|
|
} // namespace detail
|
|
} // namespace xrpl
|