mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add operator[] field accessors to STObject:
New array index operators allow for concise reading and writing of fields in the STObject, with associated unit test.
This commit is contained in:
committed by
Edward Hennis
parent
3e342e4b71
commit
2ec40cb6f1
@@ -20,6 +20,7 @@
|
||||
#ifndef RIPPLE_BASICS_BUFFER_H_INCLUDED
|
||||
#define RIPPLE_BASICS_BUFFER_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Slice.h>
|
||||
#include <beast/utility/noexcept.h>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
@@ -80,6 +81,13 @@ public:
|
||||
std::memcpy(p_.get(), data, size);
|
||||
}
|
||||
|
||||
/** Create a buffer from a copy of existing memory. */
|
||||
explicit
|
||||
Buffer (Slice const& slice)
|
||||
: Buffer(slice.data(), slice.size())
|
||||
{
|
||||
}
|
||||
|
||||
/** Returns the number of bytes in the buffer. */
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
@@ -93,6 +101,13 @@ public:
|
||||
return 0 == size_;
|
||||
}
|
||||
|
||||
operator Slice() const noexcept
|
||||
{
|
||||
if (! size_)
|
||||
return Slice{};
|
||||
return Slice{ p_.get(), size_ };
|
||||
}
|
||||
|
||||
/** Return a pointer to beginning of the storage.
|
||||
@note The return type is guaranteed to be a pointer
|
||||
to a single byte, to facilitate pointer arithmetic.
|
||||
|
||||
@@ -58,8 +58,6 @@ public:
|
||||
std::uint8_t const*>(data))
|
||||
, size_ (size)
|
||||
{
|
||||
assert(data_ != nullptr);
|
||||
assert(size_ > 0);
|
||||
}
|
||||
|
||||
/** Return `true` if the byte range is empty. */
|
||||
|
||||
@@ -97,6 +97,11 @@ public:
|
||||
return { buf_, size_ };
|
||||
}
|
||||
|
||||
operator Slice() const noexcept
|
||||
{
|
||||
return slice();
|
||||
}
|
||||
|
||||
bool
|
||||
verify (Slice const& message, Slice const& sig,
|
||||
bool mustBeFullyCanonical) const;
|
||||
|
||||
@@ -27,10 +27,26 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/*
|
||||
|
||||
Some fields have a different meaning for their
|
||||
default value versus not present.
|
||||
Example:
|
||||
QualityIn on a TrustLine
|
||||
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Forwards
|
||||
class STAccount;
|
||||
class STAmount;
|
||||
class STBlob;
|
||||
template <std::size_t>
|
||||
class STBitString;
|
||||
template <class>
|
||||
class STInteger;
|
||||
class STVector256;
|
||||
|
||||
enum SerializedTypeID
|
||||
{
|
||||
@@ -280,6 +296,45 @@ struct TypedField : SField
|
||||
}
|
||||
};
|
||||
|
||||
/** Indicate boost::optional field semantics. */
|
||||
template <class T>
|
||||
struct OptionaledField
|
||||
{
|
||||
TypedField<T> const* f;
|
||||
|
||||
explicit
|
||||
OptionaledField (TypedField<T> const& f_)
|
||||
: f (&f_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
OptionaledField<T>
|
||||
operator~(TypedField<T> const& f)
|
||||
{
|
||||
return OptionaledField<T>(f);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using SF_U8 = TypedField<STInteger<std::uint8_t>>;
|
||||
using SF_U16 = TypedField<STInteger<std::uint16_t>>;
|
||||
using SF_U32 = TypedField<STInteger<std::uint32_t>>;
|
||||
using SF_U64 = TypedField<STInteger<std::uint64_t>>;
|
||||
using SF_U128 = TypedField<STBitString<128>>;
|
||||
using SF_U160 = TypedField<STBitString<160>>;
|
||||
using SF_U256 = TypedField<STBitString<256>>;
|
||||
using SF_Account = TypedField<STAccount>;
|
||||
using SF_Amount = TypedField<STAmount>;
|
||||
using SF_Blob = TypedField<STBlob>;
|
||||
using SF_Vec256 = TypedField<STVector256>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
extern SField const sfInvalid;
|
||||
extern SField const sfGeneric;
|
||||
extern SField const sfLedgerEntry;
|
||||
@@ -288,139 +343,141 @@ extern SField const sfValidation;
|
||||
extern SField const sfMetadata;
|
||||
|
||||
// 8-bit integers
|
||||
extern SField const sfCloseResolution;
|
||||
extern SField const sfTemplateEntryType;
|
||||
extern SField const sfTransactionResult;
|
||||
extern SF_U8 const sfCloseResolution;
|
||||
extern SF_U8 const sfTemplateEntryType;
|
||||
extern SF_U8 const sfTransactionResult;
|
||||
|
||||
// 16-bit integers
|
||||
extern SField const sfLedgerEntryType;
|
||||
extern SField const sfTransactionType;
|
||||
extern SField const sfSignerWeight;
|
||||
extern SF_U16 const sfLedgerEntryType;
|
||||
extern SF_U16 const sfTransactionType;
|
||||
extern SF_U16 const sfSignerWeight;
|
||||
|
||||
// 32-bit integers (common)
|
||||
extern SField const sfFlags;
|
||||
extern SField const sfSourceTag;
|
||||
extern TypedField<STInteger<std::uint32_t>> const sfSequence;
|
||||
extern SField const sfPreviousTxnLgrSeq;
|
||||
extern SField const sfLedgerSequence;
|
||||
extern SField const sfCloseTime;
|
||||
extern SField const sfParentCloseTime;
|
||||
extern SField const sfSigningTime;
|
||||
extern SField const sfExpiration;
|
||||
extern SField const sfTransferRate;
|
||||
extern SField const sfWalletSize;
|
||||
extern SField const sfOwnerCount;
|
||||
extern SField const sfDestinationTag;
|
||||
extern SF_U32 const sfFlags;
|
||||
extern SF_U32 const sfSourceTag;
|
||||
extern SF_U32 const sfSequence;
|
||||
extern SF_U32 const sfPreviousTxnLgrSeq;
|
||||
extern SF_U32 const sfLedgerSequence;
|
||||
extern SF_U32 const sfCloseTime;
|
||||
extern SF_U32 const sfParentCloseTime;
|
||||
extern SF_U32 const sfSigningTime;
|
||||
extern SF_U32 const sfExpiration;
|
||||
extern SF_U32 const sfTransferRate;
|
||||
extern SF_U32 const sfWalletSize;
|
||||
extern SF_U32 const sfOwnerCount;
|
||||
extern SF_U32 const sfDestinationTag;
|
||||
|
||||
// 32-bit integers (uncommon)
|
||||
extern SField const sfHighQualityIn;
|
||||
extern SField const sfHighQualityOut;
|
||||
extern SField const sfLowQualityIn;
|
||||
extern SField const sfLowQualityOut;
|
||||
extern SField const sfQualityIn;
|
||||
extern SField const sfQualityOut;
|
||||
extern SField const sfStampEscrow;
|
||||
extern SField const sfBondAmount;
|
||||
extern SField const sfLoadFee;
|
||||
extern SField const sfOfferSequence;
|
||||
extern SField const sfFirstLedgerSequence; // Deprecated: do not use
|
||||
extern SField const sfLastLedgerSequence;
|
||||
extern SField const sfTransactionIndex;
|
||||
extern SField const sfOperationLimit;
|
||||
extern SField const sfReferenceFeeUnits;
|
||||
extern SField const sfReserveBase;
|
||||
extern SField const sfReserveIncrement;
|
||||
extern SField const sfSetFlag;
|
||||
extern SField const sfClearFlag;
|
||||
extern SField const sfSignerQuorum;
|
||||
extern SF_U32 const sfHighQualityIn;
|
||||
extern SF_U32 const sfHighQualityOut;
|
||||
extern SF_U32 const sfLowQualityIn;
|
||||
extern SF_U32 const sfLowQualityOut;
|
||||
extern SF_U32 const sfQualityIn;
|
||||
extern SF_U32 const sfQualityOut;
|
||||
extern SF_U32 const sfStampEscrow;
|
||||
extern SF_U32 const sfBondAmount;
|
||||
extern SF_U32 const sfLoadFee;
|
||||
extern SF_U32 const sfOfferSequence;
|
||||
extern SF_U32 const sfFirstLedgerSequence; // Deprecated: do not use
|
||||
extern SF_U32 const sfLastLedgerSequence;
|
||||
extern SF_U32 const sfTransactionIndex;
|
||||
extern SF_U32 const sfOperationLimit;
|
||||
extern SF_U32 const sfReferenceFeeUnits;
|
||||
extern SF_U32 const sfReserveBase;
|
||||
extern SF_U32 const sfReserveIncrement;
|
||||
extern SF_U32 const sfSetFlag;
|
||||
extern SF_U32 const sfClearFlag;
|
||||
extern SF_U32 const sfSignerQuorum;
|
||||
|
||||
// 64-bit integers
|
||||
extern SField const sfIndexNext;
|
||||
extern SField const sfIndexPrevious;
|
||||
extern SField const sfBookNode;
|
||||
extern SField const sfOwnerNode;
|
||||
extern SField const sfBaseFee;
|
||||
extern SField const sfExchangeRate;
|
||||
extern SField const sfLowNode;
|
||||
extern SField const sfHighNode;
|
||||
extern SF_U64 const sfIndexNext;
|
||||
extern SF_U64 const sfIndexPrevious;
|
||||
extern SF_U64 const sfBookNode;
|
||||
extern SF_U64 const sfOwnerNode;
|
||||
extern SF_U64 const sfBaseFee;
|
||||
extern SF_U64 const sfExchangeRate;
|
||||
extern SF_U64 const sfLowNode;
|
||||
extern SF_U64 const sfHighNode;
|
||||
|
||||
// 128-bit
|
||||
extern SField const sfEmailHash;
|
||||
|
||||
// 256-bit (common)
|
||||
extern SField const sfLedgerHash;
|
||||
extern SField const sfParentHash;
|
||||
extern SField const sfTransactionHash;
|
||||
extern SField const sfAccountHash;
|
||||
extern SField const sfPreviousTxnID;
|
||||
extern SField const sfLedgerIndex;
|
||||
extern SField const sfWalletLocator;
|
||||
extern SField const sfRootIndex;
|
||||
extern SField const sfAccountTxnID;
|
||||
|
||||
// 256-bit (uncommon)
|
||||
extern SField const sfBookDirectory;
|
||||
extern SField const sfInvoiceID;
|
||||
extern SField const sfNickname;
|
||||
extern SField const sfAmendment;
|
||||
extern SField const sfTicketID;
|
||||
extern SF_U128 const sfEmailHash;
|
||||
|
||||
// 160-bit (common)
|
||||
extern SField const sfTakerPaysCurrency;
|
||||
extern SField const sfTakerPaysIssuer;
|
||||
extern SField const sfTakerGetsCurrency;
|
||||
extern SField const sfTakerGetsIssuer;
|
||||
extern SF_U160 const sfTakerPaysCurrency;
|
||||
extern SF_U160 const sfTakerPaysIssuer;
|
||||
extern SF_U160 const sfTakerGetsCurrency;
|
||||
extern SF_U160 const sfTakerGetsIssuer;
|
||||
|
||||
// 256-bit (common)
|
||||
extern SF_U256 const sfLedgerHash;
|
||||
extern SF_U256 const sfParentHash;
|
||||
extern SF_U256 const sfTransactionHash;
|
||||
extern SF_U256 const sfAccountHash;
|
||||
extern SF_U256 const sfPreviousTxnID;
|
||||
extern SF_U256 const sfLedgerIndex;
|
||||
extern SF_U256 const sfWalletLocator;
|
||||
extern SF_U256 const sfRootIndex;
|
||||
extern SF_U256 const sfAccountTxnID;
|
||||
|
||||
// 256-bit (uncommon)
|
||||
extern SF_U256 const sfBookDirectory;
|
||||
extern SF_U256 const sfInvoiceID;
|
||||
extern SF_U256 const sfNickname;
|
||||
extern SF_U256 const sfAmendment;
|
||||
extern SF_U256 const sfTicketID;
|
||||
extern SF_U256 const sfDigest;
|
||||
|
||||
// currency amount (common)
|
||||
extern SField const sfAmount;
|
||||
extern SField const sfBalance;
|
||||
extern SField const sfLimitAmount;
|
||||
extern SField const sfTakerPays;
|
||||
extern SField const sfTakerGets;
|
||||
extern SField const sfLowLimit;
|
||||
extern SField const sfHighLimit;
|
||||
extern SField const sfFee;
|
||||
extern SField const sfSendMax;
|
||||
extern SField const sfDeliverMin;
|
||||
extern SF_Amount const sfAmount;
|
||||
extern SF_Amount const sfBalance;
|
||||
extern SF_Amount const sfLimitAmount;
|
||||
extern SF_Amount const sfTakerPays;
|
||||
extern SF_Amount const sfTakerGets;
|
||||
extern SF_Amount const sfLowLimit;
|
||||
extern SF_Amount const sfHighLimit;
|
||||
extern SF_Amount const sfFee;
|
||||
extern SF_Amount const sfSendMax;
|
||||
extern SF_Amount const sfDeliverMin;
|
||||
|
||||
// currency amount (uncommon)
|
||||
extern SField const sfMinimumOffer;
|
||||
extern SField const sfRippleEscrow;
|
||||
extern SField const sfDeliveredAmount;
|
||||
extern SF_Amount const sfMinimumOffer;
|
||||
extern SF_Amount const sfRippleEscrow;
|
||||
extern SF_Amount const sfDeliveredAmount;
|
||||
|
||||
// variable length (common)
|
||||
extern TypedField<STBlob> const sfPublicKey;
|
||||
extern SField const sfMessageKey;
|
||||
extern TypedField<STBlob> const sfSigningPubKey;
|
||||
extern SField const sfTxnSignature;
|
||||
extern TypedField<STBlob> const sfSignature;
|
||||
extern SField const sfDomain;
|
||||
extern SField const sfFundCode;
|
||||
extern SField const sfRemoveCode;
|
||||
extern SField const sfExpireCode;
|
||||
extern SField const sfCreateCode;
|
||||
extern SField const sfMemoType;
|
||||
extern SField const sfMemoData;
|
||||
extern SField const sfMemoFormat;
|
||||
extern SF_Blob const sfPublicKey;
|
||||
extern SF_Blob const sfMessageKey;
|
||||
extern SF_Blob const sfSigningPubKey;
|
||||
extern SF_Blob const sfTxnSignature;
|
||||
extern SF_Blob const sfSignature;
|
||||
extern SF_Blob const sfDomain;
|
||||
extern SF_Blob const sfFundCode;
|
||||
extern SF_Blob const sfRemoveCode;
|
||||
extern SF_Blob const sfExpireCode;
|
||||
extern SF_Blob const sfCreateCode;
|
||||
extern SF_Blob const sfMemoType;
|
||||
extern SF_Blob const sfMemoData;
|
||||
extern SF_Blob const sfMemoFormat;
|
||||
|
||||
// variable length (uncommon)
|
||||
extern SField const sfMultiSignature;
|
||||
extern SF_Blob const sfMultiSignature;
|
||||
extern SF_Blob const sfInnerSig;
|
||||
|
||||
// account
|
||||
extern SField const sfAccount;
|
||||
extern SField const sfOwner;
|
||||
extern SField const sfDestination;
|
||||
extern SField const sfIssuer;
|
||||
extern SField const sfTarget;
|
||||
extern SField const sfRegularKey;
|
||||
extern SF_Account const sfAccount;
|
||||
extern SF_Account const sfOwner;
|
||||
extern SF_Account const sfDestination;
|
||||
extern SF_Account const sfIssuer;
|
||||
extern SF_Account const sfTarget;
|
||||
extern SF_Account const sfRegularKey;
|
||||
|
||||
// path set
|
||||
extern SField const sfPaths;
|
||||
|
||||
// vector of 256-bit
|
||||
extern SField const sfIndexes;
|
||||
extern SField const sfHashes;
|
||||
extern SField const sfAmendments;
|
||||
extern SF_Vec256 const sfIndexes;
|
||||
extern SF_Vec256 const sfHashes;
|
||||
extern SF_Vec256 const sfAmendments;
|
||||
|
||||
// inner object
|
||||
// OBJECT/1 is reserved for end of object
|
||||
|
||||
@@ -71,6 +71,12 @@ public:
|
||||
*/
|
||||
SOTemplate () = default;
|
||||
|
||||
SOTemplate(SOTemplate&& other)
|
||||
: mTypes(std::move(other.mTypes))
|
||||
, mIndex(std::move(other.mIndex))
|
||||
{
|
||||
}
|
||||
|
||||
/* Provide for the enumeration of fields */
|
||||
iterator_range all () const
|
||||
{
|
||||
@@ -89,6 +95,12 @@ public:
|
||||
/** Retrieve the position of a named field. */
|
||||
int getIndex (SField const&) const;
|
||||
|
||||
SOE_Flags
|
||||
style(SField const& sf) const
|
||||
{
|
||||
return mTypes[mIndex[sf.getNum()]]->flags;
|
||||
}
|
||||
|
||||
private:
|
||||
list_type mTypes;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef RIPPLE_PROTOCOL_STACCOUNT_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STACCOUNT_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/AccountID.h>
|
||||
#include <ripple/protocol/RippleAddress.h>
|
||||
#include <ripple/protocol/STBlob.h>
|
||||
#include <string>
|
||||
@@ -30,6 +31,8 @@ class STAccount final
|
||||
: public STBlob
|
||||
{
|
||||
public:
|
||||
using value_type = AccountID;
|
||||
|
||||
STAccount (SField const& n, Buffer&& v)
|
||||
: STBlob (n, std::move(v))
|
||||
{
|
||||
@@ -63,8 +66,24 @@ public:
|
||||
{
|
||||
return STI_ACCOUNT;
|
||||
}
|
||||
|
||||
std::string getText () const override;
|
||||
|
||||
STAccount&
|
||||
operator= (value_type const& value)
|
||||
{
|
||||
setValueH160(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
value_type
|
||||
value() const noexcept
|
||||
{
|
||||
AccountID result;
|
||||
getValueH160(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Tag>
|
||||
void setValueH160 (base_uint<160, Tag> const& v)
|
||||
{
|
||||
|
||||
@@ -54,6 +54,8 @@ private:
|
||||
bool mIsNegative;
|
||||
|
||||
public:
|
||||
using value_type = STAmount;
|
||||
|
||||
static const int cMinOffset = -96;
|
||||
static const int cMaxOffset = 80;
|
||||
|
||||
@@ -166,6 +168,12 @@ public:
|
||||
void
|
||||
setJson (Json::Value&) const;
|
||||
|
||||
STAmount const&
|
||||
value() const noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Operators
|
||||
|
||||
@@ -29,7 +29,7 @@ class STBitString final
|
||||
: public STBase
|
||||
{
|
||||
public:
|
||||
using BitString = base_uint<Bits>;
|
||||
using value_type = base_uint<Bits>;
|
||||
|
||||
STBitString () = default;
|
||||
|
||||
@@ -37,24 +37,24 @@ public:
|
||||
: STBase (n)
|
||||
{ }
|
||||
|
||||
STBitString (const BitString& v)
|
||||
: bitString_ (v)
|
||||
STBitString (const value_type& v)
|
||||
: value_ (v)
|
||||
{ }
|
||||
|
||||
STBitString (SField const& n, const BitString& v)
|
||||
: STBase (n), bitString_ (v)
|
||||
STBitString (SField const& n, const value_type& v)
|
||||
: STBase (n), value_ (v)
|
||||
{ }
|
||||
|
||||
STBitString (SField const& n, const char* v)
|
||||
: STBase (n)
|
||||
{
|
||||
bitString_.SetHex (v);
|
||||
value_.SetHex (v);
|
||||
}
|
||||
|
||||
STBitString (SField const& n, std::string const& v)
|
||||
: STBase (n)
|
||||
{
|
||||
bitString_.SetHex (v);
|
||||
value_.SetHex (v);
|
||||
}
|
||||
|
||||
STBitString (SerialIter& sit, SField const& name)
|
||||
@@ -80,14 +80,14 @@ public:
|
||||
std::string
|
||||
getText () const override
|
||||
{
|
||||
return to_string (bitString_);
|
||||
return to_string (value_);
|
||||
}
|
||||
|
||||
bool
|
||||
isEquivalent (const STBase& t) const override
|
||||
{
|
||||
const STBitString* v = dynamic_cast<const STBitString*> (&t);
|
||||
return v && (bitString_ == v->bitString_);
|
||||
return v && (value_ == v->value_);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -95,34 +95,40 @@ public:
|
||||
{
|
||||
assert (fName->isBinary ());
|
||||
assert (fName->fieldType == getSType());
|
||||
s.addBitString<Bits> (bitString_);
|
||||
s.addBitString<Bits> (value_);
|
||||
}
|
||||
|
||||
const BitString&
|
||||
const value_type&
|
||||
getValue () const
|
||||
{
|
||||
return bitString_;
|
||||
return value_;
|
||||
}
|
||||
|
||||
template <typename Tag>
|
||||
void setValue (base_uint<Bits, Tag> const& v)
|
||||
{
|
||||
bitString_.copyFrom(v);
|
||||
value_.copyFrom(v);
|
||||
}
|
||||
|
||||
operator BitString () const
|
||||
value_type const&
|
||||
value() const
|
||||
{
|
||||
return bitString_;
|
||||
return value_;
|
||||
}
|
||||
|
||||
operator value_type () const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
bool
|
||||
isDefault () const override
|
||||
{
|
||||
return bitString_ == zero;
|
||||
return value_ == zero;
|
||||
}
|
||||
|
||||
private:
|
||||
BitString bitString_;
|
||||
value_type value_;
|
||||
};
|
||||
|
||||
using STHash128 = STBitString<128>;
|
||||
|
||||
@@ -121,6 +121,26 @@ public:
|
||||
return value_;
|
||||
}
|
||||
|
||||
STBlob&
|
||||
operator= (Slice const& slice)
|
||||
{
|
||||
value_ = Buffer(slice.data(), slice.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
value_type
|
||||
value() const noexcept
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
STBlob&
|
||||
operator= (Buffer&& buffer)
|
||||
{
|
||||
value_ = std::move(buffer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Buffer&
|
||||
peekValue ()
|
||||
{
|
||||
|
||||
@@ -77,6 +77,17 @@ public:
|
||||
return value_;
|
||||
}
|
||||
|
||||
STInteger& operator= (value_type const& v)
|
||||
{
|
||||
value_ = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
value_type value() const noexcept
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
void
|
||||
setValue (Integer v)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef RIPPLE_PROTOCOL_STOBJECT_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STOBJECT_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/STAmount.h>
|
||||
#include <ripple/protocol/STPathSet.h>
|
||||
@@ -27,6 +28,10 @@
|
||||
#include <ripple/protocol/SOTemplate.h>
|
||||
#include <ripple/protocol/impl/STVar.h>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <beast/streams/debug_ostream.h>
|
||||
@@ -38,11 +43,213 @@ namespace ripple {
|
||||
|
||||
class STArray;
|
||||
|
||||
/** Thrown on illegal access to non-present SField. */
|
||||
struct missing_field_error : std::logic_error
|
||||
{
|
||||
explicit
|
||||
missing_field_error (SField const& f)
|
||||
: logic_error(
|
||||
"missing field '" + f.getName() + "'")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** Thrown on a field template violation. */
|
||||
struct template_field_error : std::logic_error
|
||||
{
|
||||
explicit
|
||||
template_field_error (SField const& f)
|
||||
: logic_error(
|
||||
"template field error '" + f.getName() + "'")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class STObject
|
||||
: public STBase
|
||||
, public CountedObject <STObject>
|
||||
{
|
||||
private:
|
||||
// Proxy value for a STBase derived class
|
||||
template <class T>
|
||||
class Proxy
|
||||
{
|
||||
protected:
|
||||
using value_type =
|
||||
typename T::value_type;
|
||||
|
||||
STObject* st_;
|
||||
SOE_Flags style_;
|
||||
TypedField<T> const* f_;
|
||||
|
||||
Proxy (Proxy const&) = default;
|
||||
Proxy (STObject* st, TypedField<T> const* f);
|
||||
value_type value() const;
|
||||
T const* find() const;
|
||||
|
||||
template <class U>
|
||||
void assign (U&& u);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class ValueProxy : private Proxy<T>
|
||||
{
|
||||
private:
|
||||
using value_type =
|
||||
typename T::value_type;
|
||||
|
||||
public:
|
||||
ValueProxy& operator= (ValueProxy const&) = delete;
|
||||
|
||||
template <class U>
|
||||
std::enable_if_t<
|
||||
std::is_assignable<T, U>::value,
|
||||
ValueProxy&>
|
||||
operator= (U&& u);
|
||||
|
||||
operator value_type() const;
|
||||
|
||||
private:
|
||||
friend class STObject;
|
||||
|
||||
ValueProxy (STObject* st, TypedField<T> const* f);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class OptionalProxy : private Proxy<T>
|
||||
{
|
||||
private:
|
||||
using value_type =
|
||||
typename T::value_type;
|
||||
|
||||
using optional_type = boost::optional<
|
||||
typename std::decay<value_type>::type>;
|
||||
|
||||
public:
|
||||
OptionalProxy& operator= (OptionalProxy const&) = delete;
|
||||
|
||||
/** Returns `true` if the field is set.
|
||||
|
||||
Fields with SOE_DEFAULT and set to the
|
||||
default value will return `true`
|
||||
*/
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
/** Return the contained value
|
||||
|
||||
Throws:
|
||||
|
||||
missing_field_error if !engaged()
|
||||
*/
|
||||
value_type operator*() const;
|
||||
|
||||
operator optional_type() const;
|
||||
|
||||
/** Explicit conversion to boost::optional */
|
||||
optional_type
|
||||
operator~() const;
|
||||
|
||||
friend bool operator==(
|
||||
OptionalProxy const& lhs,
|
||||
boost::none_t) noexcept
|
||||
{
|
||||
return ! lhs.engaged();
|
||||
}
|
||||
|
||||
friend bool operator==(
|
||||
boost::none_t,
|
||||
OptionalProxy const& rhs) noexcept
|
||||
{
|
||||
return rhs == boost::none;
|
||||
}
|
||||
|
||||
friend bool operator==(
|
||||
OptionalProxy const& lhs,
|
||||
optional_type const& rhs) noexcept
|
||||
{
|
||||
if (! lhs.engaged())
|
||||
return ! rhs;
|
||||
if (! rhs)
|
||||
return false;
|
||||
return *lhs == *rhs;
|
||||
}
|
||||
|
||||
friend bool operator==(
|
||||
optional_type const& lhs,
|
||||
OptionalProxy const& rhs) noexcept
|
||||
{
|
||||
return rhs == lhs;
|
||||
}
|
||||
|
||||
friend bool operator==(
|
||||
OptionalProxy const& lhs,
|
||||
OptionalProxy const& rhs) noexcept
|
||||
{
|
||||
if (lhs.engaged() != lhs.engaged())
|
||||
return false;
|
||||
return ! lhs.engaged() || *lhs == *rhs;
|
||||
}
|
||||
|
||||
friend bool operator!=(
|
||||
OptionalProxy const& lhs,
|
||||
boost::none_t) noexcept
|
||||
{
|
||||
return ! (lhs == boost::none);
|
||||
}
|
||||
|
||||
friend bool operator!=(boost::none_t,
|
||||
OptionalProxy const& rhs) noexcept
|
||||
{
|
||||
return ! (rhs == boost::none);
|
||||
}
|
||||
|
||||
friend bool operator!=(
|
||||
OptionalProxy const& lhs,
|
||||
optional_type const& rhs) noexcept
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
friend bool operator!=(
|
||||
optional_type const& lhs,
|
||||
OptionalProxy const& rhs) noexcept
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
friend bool operator!=(
|
||||
OptionalProxy const& lhs,
|
||||
OptionalProxy const& rhs) noexcept
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
OptionalProxy& operator= (boost::none_t const&);
|
||||
OptionalProxy& operator= (optional_type&& v);
|
||||
OptionalProxy& operator= (optional_type const& v);
|
||||
|
||||
template <class U>
|
||||
std::enable_if_t<
|
||||
std::is_assignable<T, U>::value,
|
||||
OptionalProxy&>
|
||||
operator= (U&& u);
|
||||
|
||||
private:
|
||||
friend class STObject;
|
||||
|
||||
OptionalProxy (STObject* st,
|
||||
TypedField<T> const* f);
|
||||
|
||||
bool engaged() const noexcept;
|
||||
|
||||
void disengage();
|
||||
|
||||
optional_type
|
||||
optional_value() const;
|
||||
};
|
||||
|
||||
struct Transform
|
||||
{
|
||||
using argument_type = detail::STVar;
|
||||
@@ -275,6 +482,45 @@ public:
|
||||
const STArray& getFieldArray (SField const& field) const;
|
||||
const STObject& getFieldObject (SField const& field) const;
|
||||
|
||||
/** Return the value of a field.
|
||||
|
||||
Throws:
|
||||
|
||||
missing_field_error if the field is
|
||||
not present.
|
||||
*/
|
||||
template<class T>
|
||||
typename T::value_type
|
||||
operator[](TypedField<T> const& f) const;
|
||||
|
||||
/** Return the value of a field as boost::optional
|
||||
|
||||
@return boost::none if the field is not present.
|
||||
*/
|
||||
template<class T>
|
||||
boost::optional<std::decay_t<typename T::value_type>>
|
||||
operator[](OptionaledField<T> const& of) const;
|
||||
|
||||
/** Return a modifiable field value.
|
||||
|
||||
Throws:
|
||||
|
||||
missing_field_error if the field is
|
||||
not present.
|
||||
*/
|
||||
template<class T>
|
||||
ValueProxy<T>
|
||||
operator[](TypedField<T> const& f);
|
||||
|
||||
/** Return a modifiable field value as boost::optional
|
||||
|
||||
The return value equals boost::none if the
|
||||
field is not present.
|
||||
*/
|
||||
template<class T>
|
||||
OptionalProxy<T>
|
||||
operator[](OptionaledField<T> const& of);
|
||||
|
||||
/** Set a field.
|
||||
if the field already exists, it is replaced.
|
||||
*/
|
||||
@@ -468,6 +714,277 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
STObject::Proxy<T>::Proxy (STObject* st, TypedField<T> const* f)
|
||||
: st_ (st)
|
||||
, f_ (f)
|
||||
{
|
||||
if (st_->mType)
|
||||
{
|
||||
// STObject has associated template
|
||||
if (! st_->peekAtPField(*f_))
|
||||
THROW(template_field_error, *f);
|
||||
style_ = st_->mType->style(*f_);
|
||||
}
|
||||
else
|
||||
{
|
||||
style_ = SOE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto
|
||||
STObject::Proxy<T>::value() const ->
|
||||
value_type
|
||||
{
|
||||
auto const t = find();
|
||||
if (t)
|
||||
return t->value();
|
||||
if (style_ != SOE_DEFAULT)
|
||||
THROW(missing_field_error, *f_);
|
||||
return value_type{};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
T const*
|
||||
STObject::Proxy<T>::find() const
|
||||
{
|
||||
return dynamic_cast<T const*>(
|
||||
st_->peekAtPField(*f_));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class U>
|
||||
void
|
||||
STObject::Proxy<T>::assign(U&& u)
|
||||
{
|
||||
if (style_ == SOE_DEFAULT &&
|
||||
u == value_type{})
|
||||
{
|
||||
st_->makeFieldAbsent(*f_);
|
||||
return;
|
||||
}
|
||||
T* t;
|
||||
if (style_ == SOE_INVALID)
|
||||
t = dynamic_cast<T*>(
|
||||
st_->getPField(*f_, true));
|
||||
else
|
||||
t = dynamic_cast<T*>(
|
||||
st_->makeFieldPresent(*f_));
|
||||
assert(t);
|
||||
*t = std::forward<U>(u);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
template <class U>
|
||||
std::enable_if_t<
|
||||
std::is_assignable<T, U>::value,
|
||||
STObject::ValueProxy<T>&>
|
||||
STObject::ValueProxy<T>::operator= (U&& u)
|
||||
{
|
||||
this->assign(std::forward<U>(u));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
STObject::ValueProxy<T>::operator value_type() const
|
||||
{
|
||||
return this->value();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
STObject::ValueProxy<T>::ValueProxy(
|
||||
STObject* st, TypedField<T> const* f)
|
||||
: Proxy<T>(st, f)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
STObject::OptionalProxy<T>::operator bool() const noexcept
|
||||
{
|
||||
return engaged();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto
|
||||
STObject::OptionalProxy<T>::operator*() const ->
|
||||
value_type
|
||||
{
|
||||
return this->value();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
STObject::OptionalProxy<T>::operator
|
||||
typename STObject::OptionalProxy<T>::optional_type() const
|
||||
{
|
||||
return optional_value();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename STObject::OptionalProxy<T>::optional_type
|
||||
STObject::OptionalProxy<T>::operator~() const
|
||||
{
|
||||
return optional_value();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto
|
||||
STObject::OptionalProxy<T>::operator=(boost::none_t const&) ->
|
||||
OptionalProxy&
|
||||
{
|
||||
disengage();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto
|
||||
STObject::OptionalProxy<T>::operator=(optional_type&& v) ->
|
||||
OptionalProxy&
|
||||
{
|
||||
if (v)
|
||||
this->assign(std::move(*v));
|
||||
else
|
||||
disengage();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto
|
||||
STObject::OptionalProxy<T>::operator=(optional_type const& v) ->
|
||||
OptionalProxy&
|
||||
{
|
||||
if (v)
|
||||
this->assign(*v);
|
||||
else
|
||||
disengage();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class U>
|
||||
std::enable_if_t<
|
||||
std::is_assignable<T, U>::value,
|
||||
STObject::OptionalProxy<T>&>
|
||||
STObject::OptionalProxy<T>::operator=(U&& u)
|
||||
{
|
||||
this->assign(std::forward<U>(u));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
STObject::OptionalProxy<T>::OptionalProxy(
|
||||
STObject* st, TypedField<T> const* f)
|
||||
: Proxy<T>(st, f)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool
|
||||
STObject::OptionalProxy<T>::engaged() const noexcept
|
||||
{
|
||||
return this->style_ == SOE_DEFAULT
|
||||
|| this->find() != nullptr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
STObject::OptionalProxy<T>::disengage()
|
||||
{
|
||||
if (this->style_ == SOE_REQUIRED ||
|
||||
this->style_ == SOE_DEFAULT)
|
||||
THROW(template_field_error, *this->f_);
|
||||
if (this->style_ == SOE_INVALID)
|
||||
this->st_->delField(*this->f_);
|
||||
else
|
||||
this->st_->makeFieldAbsent(*this->f_);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto
|
||||
STObject::OptionalProxy<T>::optional_value() const ->
|
||||
optional_type
|
||||
{
|
||||
if (! engaged())
|
||||
return boost::none;
|
||||
return this->value();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class T>
|
||||
typename T::value_type
|
||||
STObject::operator[](TypedField<T> const& f) const
|
||||
{
|
||||
auto const b = peekAtPField(f);
|
||||
if (! b)
|
||||
// This is a free object (no constraints)
|
||||
// with no template
|
||||
THROW(missing_field_error, f);
|
||||
auto const u =
|
||||
dynamic_cast<T const*>(b);
|
||||
if (! u)
|
||||
{
|
||||
assert(mType);
|
||||
assert(b->getSType() == STI_NOTPRESENT);
|
||||
if(mType->style(f) == SOE_OPTIONAL)
|
||||
THROW(missing_field_error, f);
|
||||
assert(mType->style(f) == SOE_DEFAULT);
|
||||
// Handle the case where value_type is a
|
||||
// const reference, otherwise we return
|
||||
// the address of a temporary.
|
||||
static std::decay_t<
|
||||
typename T::value_type> const dv{};
|
||||
return dv;
|
||||
}
|
||||
return u->value();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
boost::optional<std::decay_t<typename T::value_type>>
|
||||
STObject::operator[](OptionaledField<T> const& of) const
|
||||
{
|
||||
auto const b = peekAtPField(*of.f);
|
||||
if (! b)
|
||||
return boost::none;
|
||||
auto const u =
|
||||
dynamic_cast<T const*>(b);
|
||||
if (! u)
|
||||
{
|
||||
assert(mType);
|
||||
assert(b->getSType() == STI_NOTPRESENT);
|
||||
if(mType->style(*of.f) == SOE_OPTIONAL)
|
||||
return boost::none;
|
||||
assert(mType->style(*of.f) == SOE_DEFAULT);
|
||||
return typename T::value_type{};
|
||||
}
|
||||
return u->value();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
auto
|
||||
STObject::operator[](TypedField<T> const& f) ->
|
||||
ValueProxy<T>
|
||||
{
|
||||
return ValueProxy<T>(this, &f);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
auto
|
||||
STObject::operator[](OptionaledField<T> const& of) ->
|
||||
OptionalProxy<T>
|
||||
{
|
||||
return OptionalProxy<T>(this, of.f);
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,6 +31,8 @@ class STVector256
|
||||
: public STBase
|
||||
{
|
||||
public:
|
||||
using value_type = std::vector<uint256> const&;
|
||||
|
||||
STVector256 () = default;
|
||||
|
||||
explicit STVector256 (SField const& n)
|
||||
@@ -80,6 +82,20 @@ public:
|
||||
return mValue.empty ();
|
||||
}
|
||||
|
||||
STVector256&
|
||||
operator= (std::vector<uint256> const& v)
|
||||
{
|
||||
mValue = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
STVector256&
|
||||
operator= (std::vector<uint256>&& v)
|
||||
{
|
||||
mValue = std::move(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
setValue (const STVector256& v)
|
||||
{
|
||||
@@ -93,15 +109,14 @@ public:
|
||||
return mValue;
|
||||
}
|
||||
|
||||
// std::vector<uint256> interface:
|
||||
std::vector<uint256>::size_type
|
||||
std::size_t
|
||||
size () const
|
||||
{
|
||||
return mValue.size ();
|
||||
}
|
||||
|
||||
void
|
||||
resize (std::vector<uint256>::size_type n)
|
||||
resize (std::size_t n)
|
||||
{
|
||||
return mValue.resize (n);
|
||||
}
|
||||
@@ -124,6 +139,12 @@ public:
|
||||
return mValue[n];
|
||||
}
|
||||
|
||||
std::vector<uint256> const&
|
||||
value() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
void
|
||||
push_back (uint256 const& v)
|
||||
{
|
||||
|
||||
@@ -76,139 +76,141 @@ SField const sfHash = make::one(&sfHash, STI_HASH256, 257, "ha
|
||||
SField const sfIndex = make::one(&sfIndex, STI_HASH256, 258, "index");
|
||||
|
||||
// 8-bit integers
|
||||
SField const sfCloseResolution = make::one(&sfCloseResolution, STI_UINT8, 1, "CloseResolution");
|
||||
SField const sfTemplateEntryType = make::one(&sfTemplateEntryType, STI_UINT8, 2, "TemplateEntryType");
|
||||
SField const sfTransactionResult = make::one(&sfTransactionResult, STI_UINT8, 3, "TransactionResult");
|
||||
SF_U8 const sfCloseResolution = make::one<SF_U8::type>(&sfCloseResolution, STI_UINT8, 1, "CloseResolution");
|
||||
SF_U8 const sfTemplateEntryType = make::one<SF_U8::type>(&sfTemplateEntryType, STI_UINT8, 2, "TemplateEntryType");
|
||||
SF_U8 const sfTransactionResult = make::one<SF_U8::type>(&sfTransactionResult, STI_UINT8, 3, "TransactionResult");
|
||||
|
||||
// 16-bit integers
|
||||
SField const sfLedgerEntryType = make::one(&sfLedgerEntryType, STI_UINT16, 1, "LedgerEntryType", SField::sMD_Never);
|
||||
SField const sfTransactionType = make::one(&sfTransactionType, STI_UINT16, 2, "TransactionType");
|
||||
SField const sfSignerWeight = make::one(&sfSignerWeight, STI_UINT16, 3, "SignerWeight");
|
||||
SF_U16 const sfLedgerEntryType = make::one<SF_U16::type>(&sfLedgerEntryType, STI_UINT16, 1, "LedgerEntryType", SField::sMD_Never);
|
||||
SF_U16 const sfTransactionType = make::one<SF_U16::type>(&sfTransactionType, STI_UINT16, 2, "TransactionType");
|
||||
SF_U16 const sfSignerWeight = make::one<SF_U16::type>(&sfSignerWeight, STI_UINT16, 3, "SignerWeight");
|
||||
|
||||
// 32-bit integers (common)
|
||||
SField const sfFlags = make::one(&sfFlags, STI_UINT32, 2, "Flags");
|
||||
SField const sfSourceTag = make::one(&sfSourceTag, STI_UINT32, 3, "SourceTag");
|
||||
TypedField<STInteger<std::uint32_t>> const sfSequence = make::one<STInteger<std::uint32_t>>(&sfSequence, STI_UINT32, 4, "Sequence");
|
||||
SField const sfPreviousTxnLgrSeq = make::one(&sfPreviousTxnLgrSeq, STI_UINT32, 5, "PreviousTxnLgrSeq", SField::sMD_DeleteFinal);
|
||||
SField const sfLedgerSequence = make::one(&sfLedgerSequence, STI_UINT32, 6, "LedgerSequence");
|
||||
SField const sfCloseTime = make::one(&sfCloseTime, STI_UINT32, 7, "CloseTime");
|
||||
SField const sfParentCloseTime = make::one(&sfParentCloseTime, STI_UINT32, 8, "ParentCloseTime");
|
||||
SField const sfSigningTime = make::one(&sfSigningTime, STI_UINT32, 9, "SigningTime");
|
||||
SField const sfExpiration = make::one(&sfExpiration, STI_UINT32, 10, "Expiration");
|
||||
SField const sfTransferRate = make::one(&sfTransferRate, STI_UINT32, 11, "TransferRate");
|
||||
SField const sfWalletSize = make::one(&sfWalletSize, STI_UINT32, 12, "WalletSize");
|
||||
SField const sfOwnerCount = make::one(&sfOwnerCount, STI_UINT32, 13, "OwnerCount");
|
||||
SField const sfDestinationTag = make::one(&sfDestinationTag, STI_UINT32, 14, "DestinationTag");
|
||||
SF_U32 const sfFlags = make::one<SF_U32::type>(&sfFlags, STI_UINT32, 2, "Flags");
|
||||
SF_U32 const sfSourceTag = make::one<SF_U32::type>(&sfSourceTag, STI_UINT32, 3, "SourceTag");
|
||||
SF_U32 const sfSequence = make::one<SF_U32::type>(&sfSequence, STI_UINT32, 4, "Sequence");
|
||||
SF_U32 const sfPreviousTxnLgrSeq = make::one<SF_U32::type>(&sfPreviousTxnLgrSeq, STI_UINT32, 5, "PreviousTxnLgrSeq", SField::sMD_DeleteFinal);
|
||||
SF_U32 const sfLedgerSequence = make::one<SF_U32::type>(&sfLedgerSequence, STI_UINT32, 6, "LedgerSequence");
|
||||
SF_U32 const sfCloseTime = make::one<SF_U32::type>(&sfCloseTime, STI_UINT32, 7, "CloseTime");
|
||||
SF_U32 const sfParentCloseTime = make::one<SF_U32::type>(&sfParentCloseTime, STI_UINT32, 8, "ParentCloseTime");
|
||||
SF_U32 const sfSigningTime = make::one<SF_U32::type>(&sfSigningTime, STI_UINT32, 9, "SigningTime");
|
||||
SF_U32 const sfExpiration = make::one<SF_U32::type>(&sfExpiration, STI_UINT32, 10, "Expiration");
|
||||
SF_U32 const sfTransferRate = make::one<SF_U32::type>(&sfTransferRate, STI_UINT32, 11, "TransferRate");
|
||||
SF_U32 const sfWalletSize = make::one<SF_U32::type>(&sfWalletSize, STI_UINT32, 12, "WalletSize");
|
||||
SF_U32 const sfOwnerCount = make::one<SF_U32::type>(&sfOwnerCount, STI_UINT32, 13, "OwnerCount");
|
||||
SF_U32 const sfDestinationTag = make::one<SF_U32::type>(&sfDestinationTag, STI_UINT32, 14, "DestinationTag");
|
||||
|
||||
// 32-bit integers (uncommon)
|
||||
SField const sfHighQualityIn = make::one(&sfHighQualityIn, STI_UINT32, 16, "HighQualityIn");
|
||||
SField const sfHighQualityOut = make::one(&sfHighQualityOut, STI_UINT32, 17, "HighQualityOut");
|
||||
SField const sfLowQualityIn = make::one(&sfLowQualityIn, STI_UINT32, 18, "LowQualityIn");
|
||||
SField const sfLowQualityOut = make::one(&sfLowQualityOut, STI_UINT32, 19, "LowQualityOut");
|
||||
SField const sfQualityIn = make::one(&sfQualityIn, STI_UINT32, 20, "QualityIn");
|
||||
SField const sfQualityOut = make::one(&sfQualityOut, STI_UINT32, 21, "QualityOut");
|
||||
SField const sfStampEscrow = make::one(&sfStampEscrow, STI_UINT32, 22, "StampEscrow");
|
||||
SField const sfBondAmount = make::one(&sfBondAmount, STI_UINT32, 23, "BondAmount");
|
||||
SField const sfLoadFee = make::one(&sfLoadFee, STI_UINT32, 24, "LoadFee");
|
||||
SField const sfOfferSequence = make::one(&sfOfferSequence, STI_UINT32, 25, "OfferSequence");
|
||||
SField const sfFirstLedgerSequence = make::one(&sfFirstLedgerSequence, STI_UINT32, 26, "FirstLedgerSequence"); // Deprecated: do not use
|
||||
SField const sfLastLedgerSequence = make::one(&sfLastLedgerSequence, STI_UINT32, 27, "LastLedgerSequence");
|
||||
SField const sfTransactionIndex = make::one(&sfTransactionIndex, STI_UINT32, 28, "TransactionIndex");
|
||||
SField const sfOperationLimit = make::one(&sfOperationLimit, STI_UINT32, 29, "OperationLimit");
|
||||
SField const sfReferenceFeeUnits = make::one(&sfReferenceFeeUnits, STI_UINT32, 30, "ReferenceFeeUnits");
|
||||
SField const sfReserveBase = make::one(&sfReserveBase, STI_UINT32, 31, "ReserveBase");
|
||||
SField const sfReserveIncrement = make::one(&sfReserveIncrement, STI_UINT32, 32, "ReserveIncrement");
|
||||
SField const sfSetFlag = make::one(&sfSetFlag, STI_UINT32, 33, "SetFlag");
|
||||
SField const sfClearFlag = make::one(&sfClearFlag, STI_UINT32, 34, "ClearFlag");
|
||||
SField const sfSignerQuorum = make::one(&sfSignerQuorum, STI_UINT32, 35, "SignerQuorum");
|
||||
SF_U32 const sfHighQualityIn = make::one<SF_U32::type>(&sfHighQualityIn, STI_UINT32, 16, "HighQualityIn");
|
||||
SF_U32 const sfHighQualityOut = make::one<SF_U32::type>(&sfHighQualityOut, STI_UINT32, 17, "HighQualityOut");
|
||||
SF_U32 const sfLowQualityIn = make::one<SF_U32::type>(&sfLowQualityIn, STI_UINT32, 18, "LowQualityIn");
|
||||
SF_U32 const sfLowQualityOut = make::one<SF_U32::type>(&sfLowQualityOut, STI_UINT32, 19, "LowQualityOut");
|
||||
SF_U32 const sfQualityIn = make::one<SF_U32::type>(&sfQualityIn, STI_UINT32, 20, "QualityIn");
|
||||
SF_U32 const sfQualityOut = make::one<SF_U32::type>(&sfQualityOut, STI_UINT32, 21, "QualityOut");
|
||||
SF_U32 const sfStampEscrow = make::one<SF_U32::type>(&sfStampEscrow, STI_UINT32, 22, "StampEscrow");
|
||||
SF_U32 const sfBondAmount = make::one<SF_U32::type>(&sfBondAmount, STI_UINT32, 23, "BondAmount");
|
||||
SF_U32 const sfLoadFee = make::one<SF_U32::type>(&sfLoadFee, STI_UINT32, 24, "LoadFee");
|
||||
SF_U32 const sfOfferSequence = make::one<SF_U32::type>(&sfOfferSequence, STI_UINT32, 25, "OfferSequence");
|
||||
SF_U32 const sfFirstLedgerSequence = make::one<SF_U32::type>(&sfFirstLedgerSequence, STI_UINT32, 26, "FirstLedgerSequence"); // Deprecated: do not use
|
||||
SF_U32 const sfLastLedgerSequence = make::one<SF_U32::type>(&sfLastLedgerSequence, STI_UINT32, 27, "LastLedgerSequence");
|
||||
SF_U32 const sfTransactionIndex = make::one<SF_U32::type>(&sfTransactionIndex, STI_UINT32, 28, "TransactionIndex");
|
||||
SF_U32 const sfOperationLimit = make::one<SF_U32::type>(&sfOperationLimit, STI_UINT32, 29, "OperationLimit");
|
||||
SF_U32 const sfReferenceFeeUnits = make::one<SF_U32::type>(&sfReferenceFeeUnits, STI_UINT32, 30, "ReferenceFeeUnits");
|
||||
SF_U32 const sfReserveBase = make::one<SF_U32::type>(&sfReserveBase, STI_UINT32, 31, "ReserveBase");
|
||||
SF_U32 const sfReserveIncrement = make::one<SF_U32::type>(&sfReserveIncrement, STI_UINT32, 32, "ReserveIncrement");
|
||||
SF_U32 const sfSetFlag = make::one<SF_U32::type>(&sfSetFlag, STI_UINT32, 33, "SetFlag");
|
||||
SF_U32 const sfClearFlag = make::one<SF_U32::type>(&sfClearFlag, STI_UINT32, 34, "ClearFlag");
|
||||
SF_U32 const sfSignerQuorum = make::one<SF_U32::type>(&sfSignerQuorum, STI_UINT32, 35, "SignerQuorum");
|
||||
|
||||
// 64-bit integers
|
||||
SField const sfIndexNext = make::one(&sfIndexNext, STI_UINT64, 1, "IndexNext");
|
||||
SField const sfIndexPrevious = make::one(&sfIndexPrevious, STI_UINT64, 2, "IndexPrevious");
|
||||
SField const sfBookNode = make::one(&sfBookNode, STI_UINT64, 3, "BookNode");
|
||||
SField const sfOwnerNode = make::one(&sfOwnerNode, STI_UINT64, 4, "OwnerNode");
|
||||
SField const sfBaseFee = make::one(&sfBaseFee, STI_UINT64, 5, "BaseFee");
|
||||
SField const sfExchangeRate = make::one(&sfExchangeRate, STI_UINT64, 6, "ExchangeRate");
|
||||
SField const sfLowNode = make::one(&sfLowNode, STI_UINT64, 7, "LowNode");
|
||||
SField const sfHighNode = make::one(&sfHighNode, STI_UINT64, 8, "HighNode");
|
||||
SF_U64 const sfIndexNext = make::one<SF_U64::type>(&sfIndexNext, STI_UINT64, 1, "IndexNext");
|
||||
SF_U64 const sfIndexPrevious = make::one<SF_U64::type>(&sfIndexPrevious, STI_UINT64, 2, "IndexPrevious");
|
||||
SF_U64 const sfBookNode = make::one<SF_U64::type>(&sfBookNode, STI_UINT64, 3, "BookNode");
|
||||
SF_U64 const sfOwnerNode = make::one<SF_U64::type>(&sfOwnerNode, STI_UINT64, 4, "OwnerNode");
|
||||
SF_U64 const sfBaseFee = make::one<SF_U64::type>(&sfBaseFee, STI_UINT64, 5, "BaseFee");
|
||||
SF_U64 const sfExchangeRate = make::one<SF_U64::type>(&sfExchangeRate, STI_UINT64, 6, "ExchangeRate");
|
||||
SF_U64 const sfLowNode = make::one<SF_U64::type>(&sfLowNode, STI_UINT64, 7, "LowNode");
|
||||
SF_U64 const sfHighNode = make::one<SF_U64::type>(&sfHighNode, STI_UINT64, 8, "HighNode");
|
||||
|
||||
// 128-bit
|
||||
SField const sfEmailHash = make::one(&sfEmailHash, STI_HASH128, 1, "EmailHash");
|
||||
|
||||
// 256-bit (common)
|
||||
SField const sfLedgerHash = make::one(&sfLedgerHash, STI_HASH256, 1, "LedgerHash");
|
||||
SField const sfParentHash = make::one(&sfParentHash, STI_HASH256, 2, "ParentHash");
|
||||
SField const sfTransactionHash = make::one(&sfTransactionHash, STI_HASH256, 3, "TransactionHash");
|
||||
SField const sfAccountHash = make::one(&sfAccountHash, STI_HASH256, 4, "AccountHash");
|
||||
SField const sfPreviousTxnID = make::one(&sfPreviousTxnID, STI_HASH256, 5, "PreviousTxnID", SField::sMD_DeleteFinal);
|
||||
SField const sfLedgerIndex = make::one(&sfLedgerIndex, STI_HASH256, 6, "LedgerIndex");
|
||||
SField const sfWalletLocator = make::one(&sfWalletLocator, STI_HASH256, 7, "WalletLocator");
|
||||
SField const sfRootIndex = make::one(&sfRootIndex, STI_HASH256, 8, "RootIndex", SField::sMD_Always);
|
||||
SField const sfAccountTxnID = make::one(&sfAccountTxnID, STI_HASH256, 9, "AccountTxnID");
|
||||
|
||||
// 256-bit (uncommon)
|
||||
SField const sfBookDirectory = make::one(&sfBookDirectory, STI_HASH256, 16, "BookDirectory");
|
||||
SField const sfInvoiceID = make::one(&sfInvoiceID, STI_HASH256, 17, "InvoiceID");
|
||||
SField const sfNickname = make::one(&sfNickname, STI_HASH256, 18, "Nickname");
|
||||
SField const sfAmendment = make::one(&sfAmendment, STI_HASH256, 19, "Amendment");
|
||||
SField const sfTicketID = make::one(&sfTicketID, STI_HASH256, 20, "TicketID");
|
||||
SF_U128 const sfEmailHash = make::one<SF_U128::type>(&sfEmailHash, STI_HASH128, 1, "EmailHash");
|
||||
|
||||
// 160-bit (common)
|
||||
SField const sfTakerPaysCurrency = make::one(&sfTakerPaysCurrency, STI_HASH160, 1, "TakerPaysCurrency");
|
||||
SField const sfTakerPaysIssuer = make::one(&sfTakerPaysIssuer, STI_HASH160, 2, "TakerPaysIssuer");
|
||||
SField const sfTakerGetsCurrency = make::one(&sfTakerGetsCurrency, STI_HASH160, 3, "TakerGetsCurrency");
|
||||
SField const sfTakerGetsIssuer = make::one(&sfTakerGetsIssuer, STI_HASH160, 4, "TakerGetsIssuer");
|
||||
SF_U160 const sfTakerPaysCurrency = make::one<SF_U160::type>(&sfTakerPaysCurrency, STI_HASH160, 1, "TakerPaysCurrency");
|
||||
SF_U160 const sfTakerPaysIssuer = make::one<SF_U160::type>(&sfTakerPaysIssuer, STI_HASH160, 2, "TakerPaysIssuer");
|
||||
SF_U160 const sfTakerGetsCurrency = make::one<SF_U160::type>(&sfTakerGetsCurrency, STI_HASH160, 3, "TakerGetsCurrency");
|
||||
SF_U160 const sfTakerGetsIssuer = make::one<SF_U160::type>(&sfTakerGetsIssuer, STI_HASH160, 4, "TakerGetsIssuer");
|
||||
|
||||
// 256-bit (common)
|
||||
SF_U256 const sfLedgerHash = make::one<SF_U256::type>(&sfLedgerHash, STI_HASH256, 1, "LedgerHash");
|
||||
SF_U256 const sfParentHash = make::one<SF_U256::type>(&sfParentHash, STI_HASH256, 2, "ParentHash");
|
||||
SF_U256 const sfTransactionHash = make::one<SF_U256::type>(&sfTransactionHash, STI_HASH256, 3, "TransactionHash");
|
||||
SF_U256 const sfAccountHash = make::one<SF_U256::type>(&sfAccountHash, STI_HASH256, 4, "AccountHash");
|
||||
SF_U256 const sfPreviousTxnID = make::one<SF_U256::type>(&sfPreviousTxnID, STI_HASH256, 5, "PreviousTxnID", SField::sMD_DeleteFinal);
|
||||
SF_U256 const sfLedgerIndex = make::one<SF_U256::type>(&sfLedgerIndex, STI_HASH256, 6, "LedgerIndex");
|
||||
SF_U256 const sfWalletLocator = make::one<SF_U256::type>(&sfWalletLocator, STI_HASH256, 7, "WalletLocator");
|
||||
SF_U256 const sfRootIndex = make::one<SF_U256::type>(&sfRootIndex, STI_HASH256, 8, "RootIndex", SField::sMD_Always);
|
||||
SF_U256 const sfAccountTxnID = make::one<SF_U256::type>(&sfAccountTxnID, STI_HASH256, 9, "AccountTxnID");
|
||||
|
||||
// 256-bit (uncommon)
|
||||
SF_U256 const sfBookDirectory = make::one<SF_U256::type>(&sfBookDirectory, STI_HASH256, 16, "BookDirectory");
|
||||
SF_U256 const sfInvoiceID = make::one<SF_U256::type>(&sfInvoiceID, STI_HASH256, 17, "InvoiceID");
|
||||
SF_U256 const sfNickname = make::one<SF_U256::type>(&sfNickname, STI_HASH256, 18, "Nickname");
|
||||
SF_U256 const sfAmendment = make::one<SF_U256::type>(&sfAmendment, STI_HASH256, 19, "Amendment");
|
||||
SF_U256 const sfTicketID = make::one<SF_U256::type>(&sfTicketID, STI_HASH256, 20, "TicketID");
|
||||
SF_U256 const sfDigest = make::one<SF_U256::type>(&sfDigest, STI_HASH256, 21, "Digest");
|
||||
|
||||
// currency amount (common)
|
||||
SField const sfAmount = make::one(&sfAmount, STI_AMOUNT, 1, "Amount");
|
||||
SField const sfBalance = make::one(&sfBalance, STI_AMOUNT, 2, "Balance");
|
||||
SField const sfLimitAmount = make::one(&sfLimitAmount, STI_AMOUNT, 3, "LimitAmount");
|
||||
SField const sfTakerPays = make::one(&sfTakerPays, STI_AMOUNT, 4, "TakerPays");
|
||||
SField const sfTakerGets = make::one(&sfTakerGets, STI_AMOUNT, 5, "TakerGets");
|
||||
SField const sfLowLimit = make::one(&sfLowLimit, STI_AMOUNT, 6, "LowLimit");
|
||||
SField const sfHighLimit = make::one(&sfHighLimit, STI_AMOUNT, 7, "HighLimit");
|
||||
SField const sfFee = make::one(&sfFee, STI_AMOUNT, 8, "Fee");
|
||||
SField const sfSendMax = make::one(&sfSendMax, STI_AMOUNT, 9, "SendMax");
|
||||
SField const sfDeliverMin = make::one(&sfDeliverMin, STI_AMOUNT, 10, "DeliverMin");
|
||||
SF_Amount const sfAmount = make::one<SF_Amount::type>(&sfAmount, STI_AMOUNT, 1, "Amount");
|
||||
SF_Amount const sfBalance = make::one<SF_Amount::type>(&sfBalance, STI_AMOUNT, 2, "Balance");
|
||||
SF_Amount const sfLimitAmount = make::one<SF_Amount::type>(&sfLimitAmount, STI_AMOUNT, 3, "LimitAmount");
|
||||
SF_Amount const sfTakerPays = make::one<SF_Amount::type>(&sfTakerPays, STI_AMOUNT, 4, "TakerPays");
|
||||
SF_Amount const sfTakerGets = make::one<SF_Amount::type>(&sfTakerGets, STI_AMOUNT, 5, "TakerGets");
|
||||
SF_Amount const sfLowLimit = make::one<SF_Amount::type>(&sfLowLimit, STI_AMOUNT, 6, "LowLimit");
|
||||
SF_Amount const sfHighLimit = make::one<SF_Amount::type>(&sfHighLimit, STI_AMOUNT, 7, "HighLimit");
|
||||
SF_Amount const sfFee = make::one<SF_Amount::type>(&sfFee, STI_AMOUNT, 8, "Fee");
|
||||
SF_Amount const sfSendMax = make::one<SF_Amount::type>(&sfSendMax, STI_AMOUNT, 9, "SendMax");
|
||||
SF_Amount const sfDeliverMin = make::one<SF_Amount::type>(&sfDeliverMin, STI_AMOUNT, 10, "DeliverMin");
|
||||
|
||||
// currency amount (uncommon)
|
||||
SField const sfMinimumOffer = make::one(&sfMinimumOffer, STI_AMOUNT, 16, "MinimumOffer");
|
||||
SField const sfRippleEscrow = make::one(&sfRippleEscrow, STI_AMOUNT, 17, "RippleEscrow");
|
||||
SField const sfDeliveredAmount = make::one(&sfDeliveredAmount, STI_AMOUNT, 18, "DeliveredAmount");
|
||||
SF_Amount const sfMinimumOffer = make::one<SF_Amount::type>(&sfMinimumOffer, STI_AMOUNT, 16, "MinimumOffer");
|
||||
SF_Amount const sfRippleEscrow = make::one<SF_Amount::type>(&sfRippleEscrow, STI_AMOUNT, 17, "RippleEscrow");
|
||||
SF_Amount const sfDeliveredAmount = make::one<SF_Amount::type>(&sfDeliveredAmount, STI_AMOUNT, 18, "DeliveredAmount");
|
||||
|
||||
// variable length (common)
|
||||
TypedField<STBlob> const sfPublicKey = make::one<STBlob>(&sfPublicKey, STI_VL, 1, "PublicKey");
|
||||
TypedField<STBlob> const sfSigningPubKey = make::one<STBlob>(&sfSigningPubKey, STI_VL, 3, "SigningPubKey");
|
||||
TypedField<STBlob> const sfSignature = make::one<STBlob>(&sfSignature, STI_VL, 6, "Signature", SField::sMD_Default, SField::notSigning);
|
||||
SField const sfMessageKey = make::one(&sfMessageKey, STI_VL, 2, "MessageKey");
|
||||
SField const sfTxnSignature = make::one(&sfTxnSignature, STI_VL, 4, "TxnSignature", SField::sMD_Default, SField::notSigning);
|
||||
SField const sfDomain = make::one(&sfDomain, STI_VL, 7, "Domain");
|
||||
SField const sfFundCode = make::one(&sfFundCode, STI_VL, 8, "FundCode");
|
||||
SField const sfRemoveCode = make::one(&sfRemoveCode, STI_VL, 9, "RemoveCode");
|
||||
SField const sfExpireCode = make::one(&sfExpireCode, STI_VL, 10, "ExpireCode");
|
||||
SField const sfCreateCode = make::one(&sfCreateCode, STI_VL, 11, "CreateCode");
|
||||
SField const sfMemoType = make::one(&sfMemoType, STI_VL, 12, "MemoType");
|
||||
SField const sfMemoData = make::one(&sfMemoData, STI_VL, 13, "MemoData");
|
||||
SField const sfMemoFormat = make::one(&sfMemoFormat, STI_VL, 14, "MemoFormat");
|
||||
SF_Blob const sfPublicKey = make::one<SF_Blob::type>(&sfPublicKey, STI_VL, 1, "PublicKey");
|
||||
SF_Blob const sfSigningPubKey = make::one<SF_Blob::type>(&sfSigningPubKey, STI_VL, 3, "SigningPubKey");
|
||||
SF_Blob const sfSignature = make::one<SF_Blob::type>(&sfSignature, STI_VL, 6, "Signature", SField::sMD_Default, SField::notSigning);
|
||||
SF_Blob const sfMessageKey = make::one<SF_Blob::type>(&sfMessageKey, STI_VL, 2, "MessageKey");
|
||||
SF_Blob const sfTxnSignature = make::one<SF_Blob::type>(&sfTxnSignature, STI_VL, 4, "TxnSignature", SField::sMD_Default, SField::notSigning);
|
||||
SF_Blob const sfDomain = make::one<SF_Blob::type>(&sfDomain, STI_VL, 7, "Domain");
|
||||
SF_Blob const sfFundCode = make::one<SF_Blob::type>(&sfFundCode, STI_VL, 8, "FundCode");
|
||||
SF_Blob const sfRemoveCode = make::one<SF_Blob::type>(&sfRemoveCode, STI_VL, 9, "RemoveCode");
|
||||
SF_Blob const sfExpireCode = make::one<SF_Blob::type>(&sfExpireCode, STI_VL, 10, "ExpireCode");
|
||||
SF_Blob const sfCreateCode = make::one<SF_Blob::type>(&sfCreateCode, STI_VL, 11, "CreateCode");
|
||||
SF_Blob const sfMemoType = make::one<SF_Blob::type>(&sfMemoType, STI_VL, 12, "MemoType");
|
||||
SF_Blob const sfMemoData = make::one<SF_Blob::type>(&sfMemoData, STI_VL, 13, "MemoData");
|
||||
SF_Blob const sfMemoFormat = make::one<SF_Blob::type>(&sfMemoFormat, STI_VL, 14, "MemoFormat");
|
||||
|
||||
// variable length (uncommon)
|
||||
SField const sfMultiSignature = make::one(&sfMultiSignature, STI_VL, 16, "MultiSignature");
|
||||
SF_Blob const sfMultiSignature = make::one<SF_Blob::type>(&sfMultiSignature, STI_VL, 16, "MultiSignature");
|
||||
SF_Blob const sfInnerSig = make::one<SF_Blob::type>(&sfInnerSig, STI_VL, 17, "InnerSig");
|
||||
|
||||
// account
|
||||
SField const sfAccount = make::one(&sfAccount, STI_ACCOUNT, 1, "Account");
|
||||
SField const sfOwner = make::one(&sfOwner, STI_ACCOUNT, 2, "Owner");
|
||||
SField const sfDestination = make::one(&sfDestination, STI_ACCOUNT, 3, "Destination");
|
||||
SField const sfIssuer = make::one(&sfIssuer, STI_ACCOUNT, 4, "Issuer");
|
||||
SField const sfTarget = make::one(&sfTarget, STI_ACCOUNT, 7, "Target");
|
||||
SField const sfRegularKey = make::one(&sfRegularKey, STI_ACCOUNT, 8, "RegularKey");
|
||||
SF_Account const sfAccount = make::one<SF_Account::type>(&sfAccount, STI_ACCOUNT, 1, "Account");
|
||||
SF_Account const sfOwner = make::one<SF_Account::type>(&sfOwner, STI_ACCOUNT, 2, "Owner");
|
||||
SF_Account const sfDestination = make::one<SF_Account::type>(&sfDestination, STI_ACCOUNT, 3, "Destination");
|
||||
SF_Account const sfIssuer = make::one<SF_Account::type>(&sfIssuer, STI_ACCOUNT, 4, "Issuer");
|
||||
SF_Account const sfTarget = make::one<SF_Account::type>(&sfTarget, STI_ACCOUNT, 7, "Target");
|
||||
SF_Account const sfRegularKey = make::one<SF_Account::type>(&sfRegularKey, STI_ACCOUNT, 8, "RegularKey");
|
||||
|
||||
// path set
|
||||
SField const sfPaths = make::one(&sfPaths, STI_PATHSET, 1, "Paths");
|
||||
|
||||
// vector of 256-bit
|
||||
SField const sfIndexes = make::one(&sfIndexes, STI_VECTOR256, 1, "Indexes", SField::sMD_Never);
|
||||
SField const sfHashes = make::one(&sfHashes, STI_VECTOR256, 2, "Hashes");
|
||||
SField const sfAmendments = make::one(&sfAmendments, STI_VECTOR256, 3, "Amendments");
|
||||
SF_Vec256 const sfIndexes = make::one<SF_Vec256::type>(&sfIndexes, STI_VECTOR256, 1, "Indexes", SField::sMD_Never);
|
||||
SF_Vec256 const sfHashes = make::one<SF_Vec256::type>(&sfHashes, STI_VECTOR256, 2, "Hashes");
|
||||
SF_Vec256 const sfAmendments = make::one<SF_Vec256::type>(&sfAmendments, STI_VECTOR256, 3, "Amendments");
|
||||
|
||||
// inner object
|
||||
// OBJECT/1 is reserved for end of object
|
||||
|
||||
@@ -19,28 +19,19 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/STAccount.h>
|
||||
#include <ripple/protocol/STArray.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
#include <ripple/protocol/STParsedJSON.h>
|
||||
#include <ripple/protocol/SecretKey.h>
|
||||
#include <ripple/protocol/st.h>
|
||||
#include <ripple/json/json_reader.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class SerializedObject_test : public beast::unit_test::suite
|
||||
class STObject_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void run()
|
||||
{
|
||||
testSerialization();
|
||||
testParseJSONArray();
|
||||
testParseJSONArrayWithInvalidChildrenObjects();
|
||||
}
|
||||
|
||||
bool parseJSONString (std::string const& json, Json::Value& to)
|
||||
{
|
||||
Json::Reader reader;
|
||||
@@ -192,8 +183,307 @@ public:
|
||||
unexpected (object3.getFieldVL (sfTestVL) != j, "STObject error");
|
||||
}
|
||||
}
|
||||
|
||||
// Exercise field accessors
|
||||
void
|
||||
testFields()
|
||||
{
|
||||
testcase ("fields");
|
||||
|
||||
auto const& sf1 = sfSequence;
|
||||
auto const& sf2 = sfExpiration;
|
||||
auto const& sf3 = sfQualityIn;
|
||||
auto const& sf4 = sfSignature;
|
||||
auto const& sf5 = sfPublicKey;
|
||||
|
||||
// read free object
|
||||
|
||||
{
|
||||
auto const st = [&]()
|
||||
{
|
||||
STObject st(sfGeneric);
|
||||
st.setFieldU32(sf1, 1);
|
||||
st.setFieldU32(sf2, 2);
|
||||
return st;
|
||||
}();
|
||||
|
||||
expect(st[sf1] == 1);
|
||||
expect(st[sf2] == 2);
|
||||
except<missing_field_error>([&]()
|
||||
{ st[sf3]; });
|
||||
expect(*st[~sf1] == 1);
|
||||
expect(*st[~sf2] == 2);
|
||||
expect(st[~sf3] == boost::none);
|
||||
expect(!! st[~sf1]);
|
||||
expect(!! st[~sf2]);
|
||||
expect(! st[~sf3]);
|
||||
expect(st[sf1] != st[sf2]);
|
||||
expect(st[~sf1] != st[~sf2]);
|
||||
}
|
||||
|
||||
// read templated object
|
||||
|
||||
auto const sot = [&]()
|
||||
{
|
||||
SOTemplate sot;
|
||||
sot.push_back(SOElement(sf1, SOE_REQUIRED));
|
||||
sot.push_back(SOElement(sf2, SOE_OPTIONAL));
|
||||
sot.push_back(SOElement(sf3, SOE_DEFAULT));
|
||||
sot.push_back(SOElement(sf4, SOE_OPTIONAL));
|
||||
sot.push_back(SOElement(sf5, SOE_DEFAULT));
|
||||
return sot;
|
||||
}();
|
||||
|
||||
{
|
||||
auto const st = [&]()
|
||||
{
|
||||
STObject st(sot, sfGeneric);
|
||||
st.setFieldU32(sf1, 1);
|
||||
st.setFieldU32(sf2, 2);
|
||||
return st;
|
||||
}();
|
||||
|
||||
expect(st[sf1] == 1);
|
||||
expect(st[sf2] == 2);
|
||||
expect(st[sf3] == 0);
|
||||
expect(*st[~sf1] == 1);
|
||||
expect(*st[~sf2] == 2);
|
||||
expect(*st[~sf3] == 0);
|
||||
expect(!! st[~sf1]);
|
||||
expect(!! st[~sf2]);
|
||||
expect(!! st[~sf3]);
|
||||
}
|
||||
|
||||
// write free object
|
||||
|
||||
{
|
||||
STObject st(sfGeneric);
|
||||
unexcept([&]() { st[sf1]; });
|
||||
except([&](){ return st[sf1] == 0; });
|
||||
expect(st[~sf1] == boost::none);
|
||||
expect(st[~sf1] == boost::optional<std::uint32_t>{});
|
||||
expect(st[~sf1] != boost::optional<std::uint32_t>(1));
|
||||
expect(! st[~sf1]);
|
||||
st[sf1] = 2;
|
||||
expect(st[sf1] == 2);
|
||||
expect(st[~sf1] != boost::none);
|
||||
expect(st[~sf1] == boost::optional<std::uint32_t>(2));
|
||||
expect(!! st[~sf1]);
|
||||
st[sf1] = 1;
|
||||
expect(st[sf1] == 1);
|
||||
expect(!! st[sf1]);
|
||||
expect(!! st[~sf1]);
|
||||
st[sf1] = 0;
|
||||
expect(! st[sf1]);
|
||||
expect(!! st[~sf1]);
|
||||
st[~sf1] = boost::none;
|
||||
expect(! st[~sf1]);
|
||||
expect(st[~sf1] == boost::none);
|
||||
expect(st[~sf1] == boost::optional<std::uint32_t>{});
|
||||
st[~sf1] = boost::none;
|
||||
expect(! st[~sf1]);
|
||||
except([&]() { return st[sf1] == 0; });
|
||||
except([&]() { return *st[~sf1]; });
|
||||
st[sf1] = 1;
|
||||
expect(st[sf1] == 1);
|
||||
expect(!! st[sf1]);
|
||||
expect(!! st[~sf1]);
|
||||
st[sf1] = 3;
|
||||
st[sf2] = st[sf1];
|
||||
expect(st[sf1] == 3);
|
||||
expect(st[sf2] == 3);
|
||||
expect(st[sf2] == st[sf1]);
|
||||
st[sf1] = 4;
|
||||
st[sf2] = st[sf1];
|
||||
expect(st[sf1] == 4);
|
||||
expect(st[sf2] == 4);
|
||||
expect(st[sf2] == st[sf1]);
|
||||
}
|
||||
|
||||
// Write templated object
|
||||
|
||||
{
|
||||
STObject st(sot, sfGeneric);
|
||||
expect(!! st[~sf1]);
|
||||
expect(st[~sf1] != boost::none);
|
||||
expect(st[sf1] == 0);
|
||||
expect(*st[~sf1] == 0);
|
||||
expect(! st[~sf2]);
|
||||
expect(st[~sf2] == boost::none);
|
||||
except([&]() { return st[sf2] == 0; });
|
||||
expect(!! st[~sf3]);
|
||||
expect(st[~sf3] != boost::none);
|
||||
expect(st[sf3] == 0);
|
||||
except([&]() { st[~sf1] = boost::none; });
|
||||
st[sf1] = 1;
|
||||
expect(st[sf1] == 1);
|
||||
expect(*st[~sf1] == 1);
|
||||
expect(!! st[~sf1]);
|
||||
st[sf1] = 0;
|
||||
expect(st[sf1] == 0);
|
||||
expect(*st[~sf1] == 0);
|
||||
expect(!! st[~sf1]);
|
||||
st[sf2] = 2;
|
||||
expect(st[sf2] == 2);
|
||||
expect(*st[~sf2] == 2);
|
||||
expect(!! st[~sf2]);
|
||||
st[~sf2] = boost::none;
|
||||
except([&]() { return *st[~sf2]; });
|
||||
expect(! st[~sf2]);
|
||||
st[sf3] = 3;
|
||||
expect(st[sf3] == 3);
|
||||
expect(*st[~sf3] == 3);
|
||||
expect(!! st[~sf3]);
|
||||
st[sf3] = 2;
|
||||
expect(st[sf3] == 2);
|
||||
expect(*st[~sf3] == 2);
|
||||
expect(!! st[~sf3]);
|
||||
st[sf3] = 0;
|
||||
expect(st[sf3] == 0);
|
||||
expect(*st[~sf3] == 0);
|
||||
expect(!! st[~sf3]);
|
||||
except([&]() { st[~sf3] = boost::none; });
|
||||
expect(st[sf3] == 0);
|
||||
expect(*st[~sf3] == 0);
|
||||
expect(!! st[~sf3]);
|
||||
}
|
||||
|
||||
// coercion operator to boost::optional
|
||||
|
||||
{
|
||||
STObject st(sfGeneric);
|
||||
auto const v = ~st[~sf1];
|
||||
static_assert(std::is_same<
|
||||
std::decay_t<decltype(v)>,
|
||||
boost::optional<std::uint32_t>>::value, "");
|
||||
}
|
||||
|
||||
// UDT scalar fields
|
||||
|
||||
{
|
||||
STObject st(sfGeneric);
|
||||
st[sfAmount] = STAmount{};
|
||||
st[sfAccount] = AccountID{};
|
||||
st[sfDigest] = uint256{};
|
||||
[&](STAmount){}(st[sfAmount]);
|
||||
[&](AccountID){}(st[sfAccount]);
|
||||
[&](uint256){}(st[sfDigest]);
|
||||
}
|
||||
|
||||
// STBlob and slice
|
||||
|
||||
{
|
||||
{
|
||||
STObject st(sfGeneric);
|
||||
Buffer b(1);
|
||||
expect(! b.empty());
|
||||
st[sf4] = std::move(b);
|
||||
expect(b.empty());
|
||||
expect(Slice(st[sf4]).size() == 1);
|
||||
st[~sf4] = boost::none;
|
||||
expect(! ~st[~sf4]);
|
||||
b = Buffer{2};
|
||||
st[sf4] = Slice(b);
|
||||
expect(b.size() == 2);
|
||||
expect(Slice(st[sf4]).size() == 2);
|
||||
st[sf5] = st[sf4];
|
||||
expect(Slice(st[sf4]).size() == 2);
|
||||
expect(Slice(st[sf5]).size() == 2);
|
||||
}
|
||||
{
|
||||
STObject st(sot, sfGeneric);
|
||||
expect(st[sf5] == Slice{});
|
||||
expect(!! st[~sf5]);
|
||||
expect(!! ~st[~sf5]);
|
||||
Buffer b(1);
|
||||
st[sf5] = std::move(b);
|
||||
expect(b.empty());
|
||||
expect(Slice(st[sf5]).size() == 1);
|
||||
st[~sf4] = boost::none;
|
||||
expect(! ~st[~sf4]);
|
||||
}
|
||||
}
|
||||
|
||||
// UDT blobs
|
||||
|
||||
{
|
||||
STObject st(sfGeneric);
|
||||
expect(! st[~sf5]);
|
||||
auto const kp = generateKeyPair(
|
||||
KeyType::secp256k1,
|
||||
generateSeed("masterpassphrase"));
|
||||
st[sf5] = kp.first;
|
||||
expect(st[sf5] != PublicKey{});
|
||||
st[~sf5] = boost::none;
|
||||
#if 0
|
||||
pk = st[sf5];
|
||||
expect(pk.size() == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// By reference fields
|
||||
|
||||
{
|
||||
auto const& sf = sfIndexes;
|
||||
STObject st(sfGeneric);
|
||||
std::vector<uint256> v;
|
||||
v.emplace_back(1);
|
||||
st[sf] = v;
|
||||
st[sf] = std::move(v);
|
||||
auto const& cst = st;
|
||||
expect(cst[sf].size() == 1);
|
||||
expect(cst[~sf]->size() == 1);
|
||||
static_assert(std::is_same<decltype(cst[sfIndexes]),
|
||||
std::vector<uint256> const&>::value, "");
|
||||
}
|
||||
|
||||
// Default by reference field
|
||||
|
||||
{
|
||||
auto const& sf1 = sfIndexes;
|
||||
auto const& sf2 = sfHashes;
|
||||
auto const& sf3 = sfAmendments;
|
||||
auto const sot = [&]()
|
||||
{
|
||||
SOTemplate sot;
|
||||
sot.push_back(SOElement(sf1, SOE_REQUIRED));
|
||||
sot.push_back(SOElement(sf2, SOE_OPTIONAL));
|
||||
sot.push_back(SOElement(sf3, SOE_DEFAULT));
|
||||
return sot;
|
||||
}();
|
||||
STObject st(sot, sfGeneric);
|
||||
auto const& cst(st);
|
||||
expect(cst[sf1].size() == 0);
|
||||
expect(! cst[~sf2]);
|
||||
expect(cst[sf3].size() == 0);
|
||||
std::vector<uint256> v;
|
||||
v.emplace_back(1);
|
||||
st[sf1] = v;
|
||||
expect(cst[sf1].size() == 1);
|
||||
expect(cst[sf1][0] == uint256{1});
|
||||
st[sf2] = v;
|
||||
expect(cst[sf2].size() == 1);
|
||||
expect(cst[sf2][0] == uint256{1});
|
||||
st[~sf2] = boost::none;
|
||||
expect(! st[~sf2]);
|
||||
st[sf3] = v;
|
||||
expect(cst[sf3].size() == 1);
|
||||
expect(cst[sf3][0] == uint256{1});
|
||||
st[sf3] = std::vector<uint256>{};
|
||||
expect(cst[sf3].size() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
testFields();
|
||||
testSerialization();
|
||||
testParseJSONArray();
|
||||
testParseJSONArrayWithInvalidChildrenObjects();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(SerializedObject,ripple_data,ripple);
|
||||
BEAST_DEFINE_TESTSUITE(STObject,protocol,ripple);
|
||||
|
||||
} // ripple
|
||||
|
||||
Reference in New Issue
Block a user