1#include <xrpl/protocol/STObject.h>
3#include <xrpl/basics/Blob.h>
4#include <xrpl/basics/Log.h>
5#include <xrpl/basics/Slice.h>
6#include <xrpl/basics/base_uint.h>
7#include <xrpl/basics/contract.h>
8#include <xrpl/beast/utility/instrumentation.h>
9#include <xrpl/json/json_value.h>
10#include <xrpl/protocol/AccountID.h>
11#include <xrpl/protocol/Feature.h>
12#include <xrpl/protocol/HashPrefix.h>
13#include <xrpl/protocol/InnerObjectFormats.h>
14#include <xrpl/protocol/Rules.h>
15#include <xrpl/protocol/SField.h>
16#include <xrpl/protocol/SOTemplate.h>
17#include <xrpl/protocol/STAccount.h>
18#include <xrpl/protocol/STAmount.h>
19#include <xrpl/protocol/STArray.h>
20#include <xrpl/protocol/STBase.h>
21#include <xrpl/protocol/STBitString.h>
22#include <xrpl/protocol/STBlob.h>
23#include <xrpl/protocol/STCurrency.h>
24#include <xrpl/protocol/STInteger.h>
25#include <xrpl/protocol/STIssue.h>
26#include <xrpl/protocol/STNumber.h>
27#include <xrpl/protocol/STPathSet.h>
28#include <xrpl/protocol/STVector256.h>
29#include <xrpl/protocol/Serializer.h>
30#include <xrpl/protocol/detail/STVar.h>
84 bool const isAMMObj = name == sfAuctionSlot || name == sfVoteEntry;
85 if (!rules || (rules->enabled(fixInnerObjTemplate) && isAMMObj) ||
86 (rules->enabled(fixInnerObjTemplate2) && !isAMMObj))
104 return emplace(n, buf, std::move(*
this));
130 v_ = std::move(other.v_);
141 for (
auto const& elem : type)
157 auto throwFieldErr = [](
std::string const& field,
char const* description) {
159 ss <<
"Field '" << field <<
"' " << description;
161 JLOG(
debugLog().error()) <<
"STObject::applyTemplate failed: " << text;
167 v.reserve(type.
size());
168 for (
auto const& e : type)
172 if (iter !=
v_.end())
174 if ((e.style() ==
SoeDefault) && iter->get().isDefault())
176 throwFieldErr(e.sField().fieldName,
"may not be explicitly set to default.");
178 v.emplace_back(std::move(*iter));
185 throwFieldErr(e.sField().fieldName,
"is required but missing.");
190 for (
auto const& e :
v_)
193 if (!e->getFName().isDiscardable())
195 throwFieldErr(e->getFName().getName(),
"found in disallowed location.");
207 if (elements !=
nullptr)
215 bool reachedEndOfObject =
false;
230 if (type == STI_OBJECT && field == 1)
232 reachedEndOfObject =
true;
236 if (type == STI_ARRAY && field == 1)
238 JLOG(
debugLog().error()) <<
"Encountered object with embedded end-of-array marker";
247 <<
"Unknown field: field_type=" << type <<
", field_name=" << field;
252 v_.emplace_back(sit, fn, depth + 1);
255 if (
auto const obj =
dynamic_cast<STObject*
>(&(
v_.back().get())))
256 obj->applyTemplateFromSField(fn);
267 if (dup != sf.cend())
270 return reachedEndOfObject;
300 for (
auto const& elem :
v_)
302 if (elem->getSType() != STI_NOTPRESENT)
313 ret += elem->getFullText();
326 for (
auto const& elem :
v_)
334 ret += elem->getText();
352 return (st1.getSType() == st2.getSType()) && st1.isEquivalent(st2);
385 if (
type_ !=
nullptr)
386 return type_->getIndex(field);
389 for (
auto const& elem :
v_)
391 if (elem->getFName() == field)
423 return v_[index]->getFName();
444 if (createOkay &&
isFree())
532 if (f->
getSType() != STI_NOTPRESENT)
569 v_.erase(
v_.begin() + index);
673 ret.applyTemplateFromSField(field);
710 v_[i] = std::move(v);
716 v_.emplace_back(std::move(v));
839 for (
auto const& elem :
v_)
841 if (elem->getSType() != STI_NOTPRESENT)
842 ret[elem->getFName().getJsonName()] = elem->getJson(options);
853 for (
auto const& t1 :
v_)
855 if ((t1->getSType() != STI_NOTPRESENT) && t1->getFName().isBinary())
859 for (
auto const& t2 : obj.
v_)
861 if (t1->getFName() == t2->getFName())
878 for (
auto const& t2 : obj.
v_)
880 if ((t2->getSType() != STI_NOTPRESENT) && t2->getFName().isBinary())
895 for (
STBase const*
const field : fields)
902 (sType != STI_OBJECT) || (field->getFName().fieldType == STI_OBJECT),
903 "xrpl::STObject::add : valid field type");
904 field->addFieldID(s);
906 if (sType == STI_ARRAY || sType == STI_OBJECT)
921 if ((base.
getSType() != STI_NOTPRESENT) &&
T adjacent_find(T... args)
Like std::vector<char> but better.
static SField const & getField(int fieldCode)
bool shouldInclude(bool withSigningField) const
std::string const & getName() const
Defines the fields and their attributes within a STObject.
std::size_t size() const
The number of entries in this template.
A type which can be exported to a well known binary format.
SField const & getFName() const
static STBase * emplace(std::size_t n, void *buf, T &&val)
virtual bool isEquivalent(STBase const &t) const
virtual SerializedTypeID getSType() const
void setFName(SField const &n)
A STBase is a field.
std::uint8_t const * data() const
value_type value() const noexcept
void setFieldU8(SField const &field, unsigned char)
SField const & getFieldSType(int index) const
uint192 getFieldH192(SField const &field) const
STBase const * peekAtPIndex(int offset) const
void setFieldH192(SField const &field, uint192 const &)
STCurrency const & getFieldCurrency(SField const &field) const
Blob getFieldVL(SField const &field) const
void setFieldIssue(SField const &field, STIssue const &)
uint128 getFieldH128(SField const &field) const
bool operator==(STObject const &o) const
bool isEquivalent(STBase const &t) const override
void setFieldNumber(SField const &field, STNumber const &)
void setFieldV256(SField const &field, STVector256 const &v)
void setFieldU64(SField const &field, std::uint64_t)
unsigned char getFieldU8(SField const &field) const
std::uint32_t getFieldU32(SField const &field) const
STBase const & peekAtIndex(int offset) const
V const & getFieldByConstRef(SField const &field, V const &empty) const
STNumber const & getFieldNumber(SField const &field) const
void setFieldVL(SField const &field, Blob const &)
void applyTemplate(SOTemplate const &type)
int getFieldIndex(SField const &field) const
uint256 getHash(HashPrefix prefix) const
void setFieldI32(SField const &field, std::int32_t)
std::string getFullText() const override
void setFieldU32(SField const &field, std::uint32_t)
STArray & peekFieldArray(SField const &field)
std::string getText() const override
std::size_t emplaceBack(Args &&... args)
STArray const & getFieldArray(SField const &field) const
void setFieldArray(SField const &field, STArray const &v)
V getFieldByValue(SField const &field) const
STObject & peekFieldObject(SField const &field)
SOEStyle getStyle(SField const &field) const
STBase & getField(SField const &field)
void setFieldAmount(SField const &field, STAmount const &)
json::Value getJson(JsonOptions=JsonOptions::Values::None) const override
void add(Serializer &s) const override
bool isFlag(std::uint32_t) const
bool isFieldPresent(SField const &field) const
STObject & operator=(STObject const &)=default
STObject(STObject const &)=default
SerializedTypeID getSType() const override
void setFieldU16(SField const &field, std::uint16_t)
uint256 getFieldH256(SField const &field) const
static STObject makeInnerObject(SField const &name)
std::int32_t getFieldI32(SField const &field) const
STBase const & peekAtField(SField const &field) const
void set(SOTemplate const &)
uint256 getSigningHash(HashPrefix prefix) const
bool clearFlag(std::uint32_t)
void setFieldCurrency(SField const &field, STCurrency const &)
std::uint64_t getFieldU64(SField const &field) const
void setFieldPathSet(SField const &field, STPathSet const &)
STBase * move(std::size_t n, void *buf) override
static std::vector< STBase const * > getSortedFields(STObject const &objToSort, WhichFields whichFields)
STBase * getPField(SField const &field, bool createOkay=false)
STBase * makeFieldPresent(SField const &field)
STBase const * peekAtPField(SField const &field) const
void applyTemplateFromSField(SField const &)
bool setFlag(std::uint32_t)
void setFieldObject(SField const &field, STObject const &v)
void setFieldH128(SField const &field, uint128 const &)
STObject getFieldObject(SField const &field) const
T & peekField(SField const &field)
void setFieldUsingSetValue(SField const &field, V value)
void setAccountID(SField const &field, AccountID const &)
void setFieldUsingAssignment(SField const &field, T const &value)
bool delField(SField const &field)
STBase & getIndex(int offset)
uint160 getFieldH160(SField const &field) const
AccountID getAccountID(SField const &field) const
STBase * getPIndex(int offset)
STVector256 const & getFieldV256(SField const &field) const
STPathSet const & getFieldPathSet(SField const &field) const
bool isDefault() const override
void makeFieldAbsent(SField const &field)
bool hasMatchingEntry(STBase const &) const
void setFieldH256(SField const &field, uint256 const &)
std::uint16_t getFieldU16(SField const &field) const
STAmount const & getFieldAmount(SField const &field) const
std::uint32_t getFlags() const
STBase * copy(std::size_t n, void *buf) const override
bool empty() const noexcept
void getFieldID(int &type, int &name)
int addFieldID(int type, int name)
uint256 getSHA512Half() const
An immutable linear range of bytes.
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
std::size_t size() const noexcept
Returns the number of bytes in the storage.
@ Object
object value (collection of name/value pairs).
DefaultObjectT gDefaultObject
NonPresentObjectT gNonPresentObject
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool set(T &target, std::string const &name, Section const §ion)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
void throwFieldNotFound(SField const &field)
beast::Journal debugLog()
Returns a debug journal.
SOEStyle
Kind of element in each entry of an SOTemplate.
bool matches(char const *string, char const *regex)
Return true if the string loosely matches the regex.
std::optional< Rules > const & getCurrentTransactionRules()
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
HashPrefix
Prefix for hashing functions.
std::vector< unsigned char > Blob
Storage for linear binary data.
STInteger< std::uint32_t > STUInt32
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Note, should be treated as flags that can be | and &.