mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Code improvements:
A way to avoid duplicate field indexes that Arthur came up with. Abstract out code to create individual fields. Field index operations. Flag operations. Optional field operations.
This commit is contained in:
@@ -1,53 +1,100 @@
|
||||
|
||||
#include "SerializedObject.h"
|
||||
|
||||
STObject::STObject(SOElement* elem, const char *name) : SerializedType(name)
|
||||
SerializedType* STObject::makeDefaultObject(SerializedTypeID id, const char *name)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case STI_UINT16:
|
||||
return new STUInt16(name);
|
||||
|
||||
case STI_UINT32:
|
||||
return new STUInt32(name);
|
||||
|
||||
case STI_UINT64:
|
||||
return new STUInt64(name);
|
||||
|
||||
case STI_HASH160:
|
||||
return new STHash160(name);
|
||||
|
||||
case STI_HASH256:
|
||||
return new STHash256(name);
|
||||
|
||||
case STI_VL:
|
||||
return new STVariableLength(name);
|
||||
|
||||
case STI_TL:
|
||||
return new STTaggedList(name);
|
||||
|
||||
#if 0
|
||||
case STI_ACCOUNT: // CHECKME: Should an account be variable length?
|
||||
return new STVariableLength(name);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SerializedType* STObject::makeDeserializedObject(SerializedTypeID id, const char *name, SerializerIterator& sit)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case STI_UINT16:
|
||||
return STUInt16::construct(sit, name);
|
||||
|
||||
case STI_UINT32:
|
||||
return STUInt32::construct(sit, name);
|
||||
|
||||
case STI_UINT64:
|
||||
return STUInt64::construct(sit, name);
|
||||
|
||||
case STI_HASH160:
|
||||
return STHash160::construct(sit, name);
|
||||
|
||||
case STI_HASH256:
|
||||
return STHash256::construct(sit, name);
|
||||
|
||||
case STI_VL:
|
||||
return STVariableLength::construct(sit, name);
|
||||
|
||||
case STI_TL:
|
||||
return STTaggedList::construct(sit, name);
|
||||
|
||||
#if 0
|
||||
case STI_ACCOUNT: // CHECKME: Should an account be variable length?
|
||||
return STVariableLength::construct(sit, name);
|
||||
|
||||
#endif
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
STObject::STObject(SOElement* elem, const char *name) : SerializedType(name), mFlagIdx(-1)
|
||||
{
|
||||
while(elem->e_id!=STI_DONE)
|
||||
{
|
||||
type.push_back(elem);
|
||||
if(elem->e_type==SOE_FLAGS) mFlagIdx=mType.size();
|
||||
mType.push_back(elem);
|
||||
if( (elem->e_type==SOE_IFFLAG) || (elem->e_type==SOE_IFNFLAG) )
|
||||
giveObject(new STObject(elem->e_name));
|
||||
else switch(elem->e_id)
|
||||
else
|
||||
{
|
||||
case STI_UINT16:
|
||||
giveObject(new STUInt16(elem->e_name));
|
||||
break;
|
||||
case STI_UINT32:
|
||||
giveObject(new STUInt32(elem->e_name));
|
||||
break;
|
||||
case STI_UINT64:
|
||||
giveObject(new STUInt64(elem->e_name));
|
||||
break;
|
||||
case STI_HASH160:
|
||||
giveObject(new STHash160(elem->e_name));
|
||||
break;
|
||||
case STI_HASH256:
|
||||
giveObject(new STHash256(elem->e_name));
|
||||
break;
|
||||
case STI_VL:
|
||||
giveObject(new STVariableLength(elem->e_name));
|
||||
break;
|
||||
case STI_TL:
|
||||
giveObject(new STTaggedList(elem->e_name));
|
||||
break;
|
||||
#if 0
|
||||
case STI_ACCOUNT: // CHECKME: Should an account be variable length?
|
||||
giveObject(new STVariableLength(elem->e_name));
|
||||
break;
|
||||
#endif
|
||||
default: throw(std::runtime_error("invalid transaction element"));
|
||||
SerializedType* t=makeDefaultObject(elem->e_id, elem->e_name);
|
||||
if(!t) throw(std::runtime_error("invalid transaction element"));
|
||||
giveObject(t);
|
||||
}
|
||||
elem++;
|
||||
}
|
||||
}
|
||||
|
||||
STObject::STObject(SOElement* elem, SerializerIterator& sit, const char *name) : SerializedType(name)
|
||||
STObject::STObject(SOElement* elem, SerializerIterator& sit, const char *name) : SerializedType(name), mFlagIdx(-1)
|
||||
{
|
||||
int flags=-1;
|
||||
while(elem->e_id!=STI_DONE)
|
||||
{
|
||||
type.push_back(elem);
|
||||
mType.push_back(elem);
|
||||
bool done=false;
|
||||
if(elem->e_type==SOE_IFFLAG)
|
||||
{
|
||||
@@ -63,41 +110,14 @@ STObject::STObject(SOElement* elem, SerializerIterator& sit, const char *name) :
|
||||
{
|
||||
assert(elem->e_id==STI_UINT16);
|
||||
flags=sit.get16();
|
||||
giveObject(new STUInt16(elem->e_name, flags));
|
||||
mFlagIdx=giveObject(new STUInt16(elem->e_name, flags));
|
||||
done=true;
|
||||
}
|
||||
if(!done)
|
||||
{
|
||||
switch(elem->e_id)
|
||||
{
|
||||
case STI_UINT16:
|
||||
giveObject(STUInt16::construct(sit, elem->e_name));
|
||||
break;
|
||||
case STI_UINT32:
|
||||
giveObject(STUInt32::construct(sit, elem->e_name));
|
||||
break;
|
||||
case STI_UINT64:
|
||||
giveObject(STUInt64::construct(sit, elem->e_name));
|
||||
break;
|
||||
case STI_HASH160:
|
||||
giveObject(STHash160::construct(sit, elem->e_name));
|
||||
break;
|
||||
case STI_HASH256:
|
||||
giveObject(STHash256::construct(sit, elem->e_name));
|
||||
break;
|
||||
case STI_VL:
|
||||
giveObject(STVariableLength::construct(sit, elem->e_name));
|
||||
break;
|
||||
case STI_TL:
|
||||
giveObject(STTaggedList::construct(sit, elem->e_name));
|
||||
break;
|
||||
#if 0
|
||||
case STI_ACCOUNT: // CHECKME: Should an account be variable length?
|
||||
giveObject(STVariableLength::construct(sit, elem->e_name));
|
||||
break;
|
||||
#endif
|
||||
default: throw(std::runtime_error("invalid transaction element"));
|
||||
}
|
||||
SerializedType* t=makeDeserializedObject(elem->e_id, elem->e_name, sit);
|
||||
if(!t) throw(std::runtime_error("invalid transaction element"));
|
||||
giveObject(t);
|
||||
}
|
||||
elem++;
|
||||
}
|
||||
@@ -112,7 +132,7 @@ std::string STObject::getFullText() const
|
||||
ret+=" = {";
|
||||
}
|
||||
else ret="{";
|
||||
for(boost::ptr_vector<SerializedType>::const_iterator it=data.begin(), end=data.end(); it!=end; ++it)
|
||||
for(boost::ptr_vector<SerializedType>::const_iterator it=mData.begin(), end=mData.end(); it!=end; ++it)
|
||||
ret+=it->getFullText();
|
||||
ret+="}";
|
||||
return ret;
|
||||
@@ -121,14 +141,14 @@ std::string STObject::getFullText() const
|
||||
int STObject::getLength() const
|
||||
{
|
||||
int ret=0;
|
||||
for(boost::ptr_vector<SerializedType>::const_iterator it=data.begin(), end=data.end(); it!=end; ++it)
|
||||
for(boost::ptr_vector<SerializedType>::const_iterator it=mData.begin(), end=mData.end(); it!=end; ++it)
|
||||
ret+=it->getLength();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void STObject::add(Serializer& s) const
|
||||
{
|
||||
for(boost::ptr_vector<SerializedType>::const_iterator it=data.begin(), end=data.end(); it!=end; ++it)
|
||||
for(boost::ptr_vector<SerializedType>::const_iterator it=mData.begin(), end=mData.end(); it!=end; ++it)
|
||||
it->add(s);
|
||||
}
|
||||
|
||||
@@ -136,7 +156,7 @@ std::string STObject::getText() const
|
||||
{
|
||||
std::string ret="{";
|
||||
bool first=false;
|
||||
for(boost::ptr_vector<SerializedType>::const_iterator it=data.begin(), end=data.end(); it!=end; ++it)
|
||||
for(boost::ptr_vector<SerializedType>::const_iterator it=mData.begin(), end=mData.end(); it!=end; ++it)
|
||||
{
|
||||
if(!first)
|
||||
{
|
||||
@@ -148,3 +168,90 @@ std::string STObject::getText() const
|
||||
ret+="}";
|
||||
return ret;
|
||||
}
|
||||
|
||||
int STObject::getFieldIndex(SOE_Field field) const
|
||||
{
|
||||
int i=0;
|
||||
for(std::vector<SOElement*>::const_iterator it=mType.begin(), end=mType.end(); it!=end; ++it, ++i)
|
||||
if((*it)->e_field==field) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const SerializedType& STObject::peekAtField(SOE_Field field) const
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) throw std::runtime_error("Field not found");
|
||||
return peekAtIndex(index);
|
||||
}
|
||||
|
||||
SerializedType& STObject::getField(SOE_Field field)
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) throw std::runtime_error("Field not found");
|
||||
return getIndex(index);
|
||||
}
|
||||
|
||||
const SerializedType* STObject::peekAtPField(SOE_Field field)
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) return NULL;
|
||||
return peekAtPIndex(index);
|
||||
}
|
||||
|
||||
SerializedType* STObject::getPField(SOE_Field field)
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) return NULL;
|
||||
return getPIndex(index);
|
||||
}
|
||||
|
||||
bool STObject::isFieldPresent(SOE_Field field) const
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) return false;
|
||||
return peekAtIndex(field).getType()==STI_OBJECT;
|
||||
}
|
||||
|
||||
bool STObject::setFlag(int f)
|
||||
{
|
||||
if(mFlagIdx<0) return false;
|
||||
STUInt16* t=dynamic_cast<STUInt16*>(getPIndex(mFlagIdx));
|
||||
assert(t);
|
||||
t->setValue(t->getValue() | f);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool STObject::clearFlag(int f)
|
||||
{
|
||||
if(mFlagIdx<0) return false;
|
||||
STUInt16* t=dynamic_cast<STUInt16*>(getPIndex(mFlagIdx));
|
||||
assert(t);
|
||||
t->setValue(t->getValue() & ~f);
|
||||
return true;
|
||||
}
|
||||
|
||||
int STObject::getFlag(void) const
|
||||
{
|
||||
if(mFlagIdx<0) return 0;
|
||||
const STUInt16* t=dynamic_cast<const STUInt16*>(peekAtPIndex(mFlagIdx));
|
||||
assert(t);
|
||||
return t->getValue();
|
||||
}
|
||||
|
||||
void STObject::makeFieldPresent(SOE_Field field)
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) throw std::runtime_error("Field not found");
|
||||
if(peekAtIndex(field).getType()!=STI_OBJECT) return;
|
||||
mData.replace(index, makeDefaultObject(mType[index]->e_id, mType[index]->e_name));
|
||||
setFlag(mType[index]->e_flags);
|
||||
}
|
||||
|
||||
void STObject::makeFieldAbsent(SOE_Field field)
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) throw std::runtime_error("Field not found");
|
||||
if(peekAtIndex(field).getType()==STI_OBJECT) return;
|
||||
mData.replace(index, new STObject(mType[index]->e_name));
|
||||
clearFlag(mType[index]->e_flags);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,22 @@ enum SOE_Type
|
||||
SOE_NEVER=-1, SOE_REQUIRED=0, SOE_FLAGS, SOE_IFFLAG=1, SOE_IFNFLAG=2
|
||||
};
|
||||
|
||||
enum SOE_Field
|
||||
{
|
||||
sfInvalid=-1,
|
||||
sfGeneric=0,
|
||||
|
||||
// common fields
|
||||
sfFlags, sfSequence, sfExtensions, sfTargetLedger, sfSourceTag, sfIdentifier,
|
||||
sfDestination, sfTarget, sfAmount, sfCurrency,
|
||||
sfAmountIn, sfAmountOut, sfCurrencyIn, sfCurrencyOut,
|
||||
sfInvoiceID,
|
||||
sfExpireLedger
|
||||
};
|
||||
|
||||
struct SOElement
|
||||
{ // An element in the description of a serialized object
|
||||
SOE_Field e_field;
|
||||
const char *e_name;
|
||||
SerializedTypeID e_id;
|
||||
SOE_Type e_type;
|
||||
@@ -23,11 +37,15 @@ struct SOElement
|
||||
class STObject : public SerializedType
|
||||
{
|
||||
protected:
|
||||
boost::ptr_vector<SerializedType> data;
|
||||
std::vector<SOElement*> type;
|
||||
int mFlagIdx; // the offset to the flags object, -1 if none
|
||||
boost::ptr_vector<SerializedType> mData;
|
||||
std::vector<SOElement*> mType;
|
||||
|
||||
static SerializedType* makeDefaultObject(SerializedTypeID id, const char *name);
|
||||
static SerializedType* makeDeserializedObject(SerializedTypeID id, const char *name, SerializerIterator&);
|
||||
|
||||
public:
|
||||
STObject(const char *n=NULL) : SerializedType(n) { ; }
|
||||
STObject(const char *n=NULL) : SerializedType(n), mFlagIdx(-1) { ; }
|
||||
STObject(SOElement *t, const char *n=NULL);
|
||||
STObject(SOElement *t, SerializerIterator& u, const char *n=NULL);
|
||||
virtual ~STObject() { ; }
|
||||
@@ -40,16 +58,33 @@ public:
|
||||
std::string getFullText() const;
|
||||
std::string getText() const;
|
||||
|
||||
void addObject(const SerializedType& t) { data.push_back(t.duplicate()); }
|
||||
void giveObject(SerializedType* t) { data.push_back(t); }
|
||||
const boost::ptr_vector<SerializedType>& peekData() const { return data; }
|
||||
boost::ptr_vector<SerializedType>& peekData() { return data; }
|
||||
int addObject(const SerializedType& t) { mData.push_back(t.duplicate()); return mData.size()-1; }
|
||||
int giveObject(SerializedType* t) { mData.push_back(t); return mData.size()-1; }
|
||||
const boost::ptr_vector<SerializedType>& peekData() const { return mData; }
|
||||
boost::ptr_vector<SerializedType>& peekData() { return mData; }
|
||||
|
||||
int getCount() const { return data.size(); }
|
||||
const SerializedType& peekAt(int offset) const { return data[offset]; }
|
||||
SerializedType& getAt(int offset) { return data[offset]; }
|
||||
const SerializedType* peekAtP(int offset) const { return &(data[offset]); }
|
||||
SerializedType* getAtP(int offset) { return &(data[offset]); }
|
||||
int getCount() const { return mData.size(); }
|
||||
|
||||
bool setFlag(int);
|
||||
bool clearFlag(int);
|
||||
int getFlag() const;
|
||||
|
||||
const SerializedType& peekAtIndex(int offset) const { return mData[offset]; }
|
||||
SerializedType& getIndex(int offset) { return mData[offset]; }
|
||||
const SerializedType* peekAtPIndex(int offset) const { return &(mData[offset]); }
|
||||
SerializedType* getPIndex(int offset) { return &(mData[offset]); }
|
||||
|
||||
int getFieldIndex(SOE_Field field) const;
|
||||
|
||||
const SerializedType& peekAtField(SOE_Field field) const;
|
||||
SerializedType& getField(SOE_Field field);
|
||||
const SerializedType* peekAtPField(SOE_Field field);
|
||||
SerializedType* getPField(SOE_Field field);
|
||||
const SOElement* getFieldType(SOE_Field field) const;
|
||||
|
||||
bool isFieldPresent(SOE_Field field) const;
|
||||
void makeFieldPresent(SOE_Field field);
|
||||
void makeFieldAbsent(SOE_Field field);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -103,28 +103,64 @@ void SerializedTransaction::setSignature(const std::vector<unsigned char>& sig)
|
||||
|
||||
uint32 SerializedTransaction::getVersion() const
|
||||
{
|
||||
const STUInt32* v=dynamic_cast<const STUInt32*>(mMiddleTxn.peekAtP(0));
|
||||
const STUInt32* v=dynamic_cast<const STUInt32*>(mMiddleTxn.peekAtPIndex(0));
|
||||
if(!v) throw(std::runtime_error("corrupt transaction"));
|
||||
return v->getValue();
|
||||
}
|
||||
|
||||
void SerializedTransaction::setVersion(uint32 ver)
|
||||
{
|
||||
STUInt32* v=dynamic_cast<STUInt32*>(mMiddleTxn.getAtP(0));
|
||||
STUInt32* v=dynamic_cast<STUInt32*>(mMiddleTxn.getPIndex(0));
|
||||
if(!v) throw(std::runtime_error("corrupt transaction"));
|
||||
v->setValue(ver);
|
||||
}
|
||||
|
||||
uint64 SerializedTransaction::getTransactionFee() const
|
||||
{
|
||||
const STUInt64* v=dynamic_cast<const STUInt64*>(mMiddleTxn.peekAtP(3));
|
||||
const STUInt64* v=dynamic_cast<const STUInt64*>(mMiddleTxn.peekAtPIndex(3));
|
||||
if(!v) throw(std::runtime_error("corrupt transaction"));
|
||||
return v->getValue();
|
||||
}
|
||||
|
||||
void SerializedTransaction::setTransactionFee(uint64 fee)
|
||||
{
|
||||
STUInt64* v=dynamic_cast<STUInt64*>(mMiddleTxn.getAtP(3));
|
||||
STUInt64* v=dynamic_cast<STUInt64*>(mMiddleTxn.getPIndex(3));
|
||||
if(!v) throw(std::runtime_error("corrupt transaction"));
|
||||
v->setValue(fee);
|
||||
}
|
||||
|
||||
int SerializedTransaction::getITFieldIndex(SOE_Field field) const
|
||||
{
|
||||
return mInnerTxn.getFieldIndex(field);
|
||||
}
|
||||
|
||||
int SerializedTransaction::getITFieldCount() const
|
||||
{
|
||||
return mInnerTxn.getCount();
|
||||
}
|
||||
|
||||
bool SerializedTransaction::getITFieldPresent(SOE_Field field) const
|
||||
{
|
||||
return mInnerTxn.isFieldPresent(field);
|
||||
}
|
||||
|
||||
const SerializedType& SerializedTransaction::peekITField(SOE_Field field)
|
||||
{
|
||||
return mInnerTxn.peekAtField(field);
|
||||
}
|
||||
|
||||
SerializedType& SerializedTransaction::getITField(SOE_Field field)
|
||||
{
|
||||
return mInnerTxn.getField(field);
|
||||
}
|
||||
|
||||
void SerializedTransaction::makeITFieldPresent(SOE_Field field)
|
||||
{
|
||||
return mInnerTxn.makeFieldPresent(field);
|
||||
}
|
||||
|
||||
void SerializedTransaction::makeITFieldAbsent(SOE_Field field)
|
||||
{
|
||||
return mInnerTxn.makeFieldAbsent(field);
|
||||
}
|
||||
|
||||
@@ -49,12 +49,15 @@ public:
|
||||
void setSequence(uint32);
|
||||
|
||||
// inner transaction field functions
|
||||
int getITFieldIndex(const char *) const;
|
||||
int getITFieldIndex(SOE_Field field) const;
|
||||
int getITFieldCount() const;
|
||||
bool getITFieldPresent(int index) const;
|
||||
const SerializedType& peekITField(int index);
|
||||
SerializedType& getITField(int index);
|
||||
void makeITFieldPresent(int index);
|
||||
const SerializedType& peekITField(SOE_Field field);
|
||||
SerializedType& getITField(SOE_Field field);
|
||||
|
||||
// optional field functions
|
||||
bool getITFieldPresent(SOE_Field field) const;
|
||||
void makeITFieldPresent(SOE_Field field);
|
||||
void makeITFieldAbsent(SOE_Field field);
|
||||
|
||||
// whole transaction functions
|
||||
int getTransaction(Serializer& s, bool include_length) const;
|
||||
|
||||
@@ -1,49 +1,51 @@
|
||||
|
||||
#include "TransactionFormats.h"
|
||||
|
||||
#define S_FIELD(x) sf##x, #x
|
||||
|
||||
TransactionFormat InnerTxnFormats[]=
|
||||
{
|
||||
{ "MakePayment", ttMAKE_PAYMENT, {
|
||||
{ "Flags", STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ "Sequence", STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ "Destination", STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ "Amount", STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ "Currency", STI_HASH160, SOE_IFFLAG, 1 },
|
||||
{ "SourceTag", STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ "TargetLedger", STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ "InvoiceID", STI_HASH256, SOE_IFFLAG, 8 },
|
||||
{ "Extensions", STI_TL, SOE_IFFLAG, 32768 },
|
||||
{ NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
{ S_FIELD(Flags), STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Destination), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Amount), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Currency), STI_HASH160, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(TargetLedger), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(InvoiceID), STI_HASH256, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 32768 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Invoice", ttINVOICE, {
|
||||
{ "Flags", STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ "Sequence", STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ "Target", STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ "Amount", STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ "Currency", STI_HASH160, SOE_IFFLAG, 1 },
|
||||
{ "SourceTag", STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ "Destination", STI_ACCOUNT, SOE_IFFLAG, 4 },
|
||||
{ "TargetLedger", STI_UINT32, SOE_IFFLAG, 8 },
|
||||
{ "Identifier", STI_VL, SOE_IFFLAG, 16 },
|
||||
{ "Extensions", STI_TL, SOE_IFFLAG, 32768 },
|
||||
{ NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
{ S_FIELD(Flags), STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Target), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Amount), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Currency), STI_HASH160, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(Destination), STI_ACCOUNT, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(TargetLedger), STI_UINT32, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(Identifier), STI_VL, SOE_IFFLAG, 16 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 32768 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Offer", ttEXCHANGE_OFFER, {
|
||||
{ "Flags", STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ "Sequence", STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ "AmountIn", STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ "CurrencyIn", STI_HASH160, SOE_IFFLAG, 2 },
|
||||
{ "AmountOut", STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ "CurrencyOut", STI_HASH160, SOE_IFFLAG, 4 },
|
||||
{ "SourceTag", STI_UINT32, SOE_IFFLAG, 8 },
|
||||
{ "Destination", STI_ACCOUNT, SOE_IFFLAG, 16 },
|
||||
{ "TargetLedger", STI_UINT32, SOE_IFFLAG, 32 },
|
||||
{ "ExpireLedger", STI_UINT32, SOE_IFFLAG, 64 },
|
||||
{ "Identifier", STI_VL, SOE_IFFLAG, 128 },
|
||||
{ "Extensions", STI_TL, SOE_IFFLAG, 32768 },
|
||||
{ NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
{ S_FIELD(Flags), STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(AmountIn), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(CurrencyIn), STI_HASH160, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(AmountOut), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(CurrencyOut), STI_HASH160, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(Destination), STI_ACCOUNT, SOE_IFFLAG, 16 },
|
||||
{ S_FIELD(TargetLedger), STI_UINT32, SOE_IFFLAG, 32 },
|
||||
{ S_FIELD(ExpireLedger), STI_UINT32, SOE_IFFLAG, 64 },
|
||||
{ S_FIELD(Identifier), STI_VL, SOE_IFFLAG, 128 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 32768 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ NULL, ttINVALID }
|
||||
{ NULL, ttINVALID }
|
||||
};
|
||||
|
||||
TransactionFormat* getFormat(TransactionType t)
|
||||
|
||||
Reference in New Issue
Block a user