#ifndef XRPL_PROTOCOL_STEXCHANGE_H_INCLUDED #define XRPL_PROTOCOL_STEXCHANGE_H_INCLUDED #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ripple { /** Convert between serialized type U and C++ type T. */ template struct STExchange; template struct STExchange, T> { explicit STExchange() = default; using value_type = U; static void get(std::optional& t, STInteger const& u) { t = u.value(); } static std::unique_ptr> set(SField const& f, T const& t) { return std::make_unique>(f, t); } }; template <> struct STExchange { explicit STExchange() = default; using value_type = Slice; static void get(std::optional& t, STBlob const& u) { t.emplace(u.data(), u.size()); } static std::unique_ptr set(TypedField const& f, Slice const& t) { return std::make_unique(f, t.data(), t.size()); } }; template <> struct STExchange { explicit STExchange() = default; using value_type = Buffer; static void get(std::optional& t, STBlob const& u) { t.emplace(u.data(), u.size()); } static std::unique_ptr set(TypedField const& f, Buffer const& t) { return std::make_unique(f, t.data(), t.size()); } static std::unique_ptr set(TypedField const& f, Buffer&& t) { return std::make_unique(f, std::move(t)); } }; //------------------------------------------------------------------------------ /** Return the value of a field in an STObject as a given type. */ /** @{ */ template std::optional get(STObject const& st, TypedField const& f) { std::optional 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(b); // This should never happen if (!u) Throw("Wrong field type"); STExchange::get(t, *u); return t; } template std::optional::value_type> get(STObject const& st, TypedField const& f) { return get(st, f); } /** @} */ /** Set a field value in an STObject. */ template void set(STObject& st, TypedField const& f, T&& t) { st.set(STExchange::type>::set( f, std::forward(t))); } /** Set a blob field using an init function. */ template void set(STObject& st, TypedField const& f, std::size_t size, Init&& init) { st.set(std::make_unique(f, size, init)); } /** Set a blob field from data. */ template void set(STObject& st, TypedField const& f, void const* data, std::size_t size) { st.set(std::make_unique(f, data, size)); } /** Remove a field in an STObject. */ template void erase(STObject& st, TypedField const& f) { st.makeFieldAbsent(f); } } // namespace ripple #endif