diff --git a/src/cpp/ripple/FieldNames.h b/src/cpp/ripple/FieldNames.h index 4919569e15..f199c1f95c 100644 --- a/src/cpp/ripple/FieldNames.h +++ b/src/cpp/ripple/FieldNames.h @@ -96,6 +96,7 @@ public: bool isKnown() const { return fieldType != STI_UNKNOWN; } bool isBinary() const { return fieldValue < 256; } bool isDiscardable() const { return fieldValue > 256; } + int getCode() const { return fieldCode; } bool isSigningField() const { return signingField; } void notSigningField() { signingField = false; } diff --git a/src/cpp/ripple/LedgerFormats.cpp b/src/cpp/ripple/LedgerFormats.cpp index c1c36bb7b8..fc6c70da33 100644 --- a/src/cpp/ripple/LedgerFormats.cpp +++ b/src/cpp/ripple/LedgerFormats.cpp @@ -11,7 +11,7 @@ std::map LedgerEntryFormat::byName; #define DECLARE_LEF(name, type) lef = new LedgerEntryFormat(#name, type); (*lef) LEF_BASE -static bool LEFInit() +void LEFInit() { LedgerEntryFormat* lef; @@ -111,12 +111,8 @@ static bool LEFInit() << SOElement(sfReserveBase, SOE_REQUIRED) << SOElement(sfReserveIncrement, SOE_REQUIRED) ; - - return true; } -bool LEFInitComplete = LEFInit(); - LedgerEntryFormat* LedgerEntryFormat::getLgrFormat(LedgerEntryType t) { std::map::iterator it = byType.find(static_cast(t)); diff --git a/src/cpp/ripple/LedgerFormats.h b/src/cpp/ripple/LedgerFormats.h index a491a58e3c..bfc692a669 100644 --- a/src/cpp/ripple/LedgerFormats.h +++ b/src/cpp/ripple/LedgerFormats.h @@ -58,7 +58,7 @@ class LedgerEntryFormat public: std::string t_name; LedgerEntryType t_type; - std::vector elements; + SOTemplate elements; static std::map byType; static std::map byName; @@ -70,7 +70,7 @@ public: } LedgerEntryFormat& operator<<(const SOElement& el) { - elements.push_back(new SOElement(el)); + elements.push_back(el); return *this; } diff --git a/src/cpp/ripple/SerializedObject.cpp b/src/cpp/ripple/SerializedObject.cpp index cff7a32724..2ab80d4147 100644 --- a/src/cpp/ripple/SerializedObject.cpp +++ b/src/cpp/ripple/SerializedObject.cpp @@ -130,14 +130,26 @@ std::auto_ptr STObject::makeDeserializedObject(SerializedTypeID } } -void STObject::set(const std::vector& type) +void SOTemplate::push_back(const SOElement &r) +{ + assert(mMap.find(r.e_field.getCode()) == mMap.end()); + mMap[r.e_field.getCode()] = mTypes.size(); + mTypes.push_back(new SOElement(r)); +} + +int SOTemplate::getIndex(SField::ref f) const +{ + std::map::const_iterator it = mMap.find(f.getCode()); + return (it == mMap.end()) ? -1 : it->second; +} + +void STObject::set(const SOTemplate& type) { mData.clear(); - mType.clear(); + mType = &type; - BOOST_FOREACH(SOElement::ref elem, type) + BOOST_FOREACH(const SOElement* elem, type.peek()) { - mType.push_back(elem); if (elem->flags != SOE_REQUIRED) giveObject(makeNonPresentObject(elem->e_field)); else @@ -145,15 +157,14 @@ void STObject::set(const std::vector& type) } } -bool STObject::setType(const std::vector &type) +bool STObject::setType(const SOTemplate &type) { - boost::ptr_vector newData(type.size()); + boost::ptr_vector newData(type.peek().size()); bool valid = true; - mType.clear(); - mType.reserve(type.size()); + mType = &type; - BOOST_FOREACH(SOElement::ref elem, type) + BOOST_FOREACH(const SOElement* elem, type.peek()) { bool match = false; for (boost::ptr_vector::iterator it = mData.begin(); it != mData.end(); ++it) @@ -180,8 +191,6 @@ bool STObject::setType(const std::vector &type) } newData.push_back(makeNonPresentObject(elem->e_field)); } - - mType.push_back(elem); } BOOST_FOREACH(const SerializedType& t, mData) @@ -201,7 +210,7 @@ bool STObject::setType(const std::vector &type) bool STObject::isValidForType() { boost::ptr_vector::iterator it = mData.begin(); - BOOST_FOREACH(SOElement::ref elem, mType) + BOOST_FOREACH(const SOElement* elem, mType->peek()) { if (it == mData.end()) return false; @@ -215,14 +224,9 @@ bool STObject::isValidForType() bool STObject::isFieldAllowed(SField::ref field) { - if (isFree()) + if (mType == NULL) return true; - BOOST_FOREACH(SOElement::ref elem, mType) - { // are any required elemnents missing - if (elem->e_field == field) - return true; - } - return false; + return mType->getIndex(field) != -1; } bool STObject::set(SerializerIterator& sit, int depth) @@ -361,6 +365,9 @@ uint256 STObject::getSigningHash(uint32 prefix) const int STObject::getFieldIndex(SField::ref field) const { + if (mType != NULL) + return mType->getIndex(field); + int i = 0; BOOST_FOREACH(const SerializedType& elem, mData) { @@ -1243,11 +1250,11 @@ BOOST_AUTO_TEST_CASE( FieldManipulation_test ) SField sfTestU32(STI_UINT32, 255, "TestU32"); SField sfTestObject(STI_OBJECT, 255, "TestObject"); - std::vector elements; - elements.push_back(new SOElement(sfFlags, SOE_REQUIRED)); - elements.push_back(new SOElement(sfTestVL, SOE_REQUIRED)); - elements.push_back(new SOElement(sfTestH256, SOE_OPTIONAL)); - elements.push_back(new SOElement(sfTestU32, SOE_REQUIRED)); + SOTemplate elements; + elements.push_back(SOElement(sfFlags, SOE_REQUIRED)); + elements.push_back(SOElement(sfTestVL, SOE_REQUIRED)); + elements.push_back(SOElement(sfTestH256, SOE_OPTIONAL)); + elements.push_back(SOElement(sfTestU32, SOE_REQUIRED)); STObject object1(elements, sfTestObject); STObject object2(object1); diff --git a/src/cpp/ripple/SerializedObject.h b/src/cpp/ripple/SerializedObject.h index 545ce91fbb..bd5e5b2c16 100644 --- a/src/cpp/ripple/SerializedObject.h +++ b/src/cpp/ripple/SerializedObject.h @@ -18,32 +18,44 @@ DEFINE_INSTANCE(SerializedArray); class SOElement { // An element in the description of a serialized object public: - typedef SOElement const * ref; // used to point to one element + SField::ref e_field; + const SOE_Flags flags; - SField::ref e_field; - const SOE_Flags flags; + SOElement(SField::ref fi, SOE_Flags fl) : e_field(fi), flags(fl) { ; } +}; - SOElement(SField::ref fi, SOE_Flags fl) : e_field(fi), flags(fl) { ; } +class SOTemplate +{ +protected: + std::vector mTypes; + std::map mMap; // field code -> index + +public: + SOTemplate() { ; } + const std::vector& peek() const { return mTypes; } + void push_back(const SOElement& r); + int getIndex(SField::ref) const; }; class STObject : public SerializedType, private IS_INSTANCE(SerializedObject) { protected: boost::ptr_vector mData; - std::vector mType; + const SOTemplate* mType; STObject* duplicate() const { return new STObject(*this); } - STObject(SField::ref name, boost::ptr_vector& data) : SerializedType(name) { mData.swap(data); } + STObject(SField::ref name, boost::ptr_vector& data) : SerializedType(name), mType(NULL) + { mData.swap(data); } public: - STObject() { ; } + STObject() : mType(NULL) { ; } - STObject(SField::ref name) : SerializedType(name) { ; } + STObject(SField::ref name) : SerializedType(name), mType(NULL) { ; } - STObject(const std::vector& type, SField::ref name) : SerializedType(name) + STObject(const SOTemplate& type, SField::ref name) : SerializedType(name) { set(type); } - STObject(const std::vector& type, SerializerIterator& sit, SField::ref name) : SerializedType(name) + STObject(const SOTemplate& type, SerializerIterator& sit, SField::ref name) : SerializedType(name) { set(sit); setType(type); } std::auto_ptr oClone() const { return std::auto_ptr(new STObject(*this)); } @@ -54,12 +66,12 @@ public: static std::auto_ptr deserialize(SerializerIterator& sit, SField::ref name); - bool setType(const std::vector& type); + bool setType(const SOTemplate& type); bool isValidForType(); bool isFieldAllowed(SField::ref); - bool isFree() const { return mType.empty(); } + bool isFree() const { return mType == NULL; } - void set(const std::vector&); + void set(const SOTemplate&); bool set(SerializerIterator& u, int depth = 0); virtual SerializedTypeID getSType() const { return STI_OBJECT; } diff --git a/src/cpp/ripple/SerializedValidation.cpp b/src/cpp/ripple/SerializedValidation.cpp index f50ed08947..f4031c0c7d 100644 --- a/src/cpp/ripple/SerializedValidation.cpp +++ b/src/cpp/ripple/SerializedValidation.cpp @@ -6,25 +6,22 @@ DECLARE_INSTANCE(SerializedValidation); -std::vector sValidationFormat; +SOTemplate sValidationFormat; -static bool SVFInit() +void SVFInit() { - sValidationFormat.push_back(new SOElement(sfFlags, SOE_REQUIRED)); - sValidationFormat.push_back(new SOElement(sfLedgerHash, SOE_REQUIRED)); - sValidationFormat.push_back(new SOElement(sfLedgerSequence, SOE_OPTIONAL)); - sValidationFormat.push_back(new SOElement(sfCloseTime, SOE_OPTIONAL)); - sValidationFormat.push_back(new SOElement(sfLoadFee, SOE_OPTIONAL)); - sValidationFormat.push_back(new SOElement(sfBaseFee, SOE_OPTIONAL)); - sValidationFormat.push_back(new SOElement(sfFeatures, SOE_OPTIONAL)); - sValidationFormat.push_back(new SOElement(sfSigningTime, SOE_REQUIRED)); - sValidationFormat.push_back(new SOElement(sfSigningPubKey, SOE_REQUIRED)); - sValidationFormat.push_back(new SOElement(sfSignature, SOE_OPTIONAL)); - return true; + sValidationFormat.push_back(SOElement(sfFlags, SOE_REQUIRED)); + sValidationFormat.push_back(SOElement(sfLedgerHash, SOE_REQUIRED)); + sValidationFormat.push_back(SOElement(sfLedgerSequence, SOE_OPTIONAL)); + sValidationFormat.push_back(SOElement(sfCloseTime, SOE_OPTIONAL)); + sValidationFormat.push_back(SOElement(sfLoadFee, SOE_OPTIONAL)); + sValidationFormat.push_back(SOElement(sfBaseFee, SOE_OPTIONAL)); + sValidationFormat.push_back(SOElement(sfFeatures, SOE_OPTIONAL)); + sValidationFormat.push_back(SOElement(sfSigningTime, SOE_REQUIRED)); + sValidationFormat.push_back(SOElement(sfSigningPubKey, SOE_REQUIRED)); + sValidationFormat.push_back(SOElement(sfSignature, SOE_OPTIONAL)); }; -bool SVFinitComplete = SVFInit(); - const uint32 SerializedValidation::sFullFlag = 0x1; SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSignature) diff --git a/src/cpp/ripple/TransactionFormats.cpp b/src/cpp/ripple/TransactionFormats.cpp index effb983698..66d3a01e0b 100644 --- a/src/cpp/ripple/TransactionFormats.cpp +++ b/src/cpp/ripple/TransactionFormats.cpp @@ -16,7 +16,7 @@ std::map TransactionFormat::byName; #define DECLARE_TF(name, type) tf = new TransactionFormat(#name, type); (*tf) TF_BASE -static bool TFInit() +void TFInit() { TransactionFormat* tf; @@ -84,12 +84,8 @@ static bool TFInit() << SOElement(sfReserveBase, SOE_REQUIRED) << SOElement(sfReserveIncrement, SOE_REQUIRED) ; - - return true; } -bool TFInitComplete = TFInit(); - TransactionFormat* TransactionFormat::getTxnFormat(TransactionType t) { std::map::iterator it = byType.find(static_cast(t)); diff --git a/src/cpp/ripple/TransactionFormats.h b/src/cpp/ripple/TransactionFormats.h index ceb5c9b7d8..7e69ce7416 100644 --- a/src/cpp/ripple/TransactionFormats.h +++ b/src/cpp/ripple/TransactionFormats.h @@ -31,7 +31,7 @@ class TransactionFormat public: std::string t_name; TransactionType t_type; - std::vector elements; + SOTemplate elements; static std::map byType; static std::map byName; @@ -43,7 +43,7 @@ public: } TransactionFormat& operator<<(const SOElement& el) { - elements.push_back(new SOElement(el)); + elements.push_back(el); return *this; } diff --git a/src/cpp/ripple/main.cpp b/src/cpp/ripple/main.cpp index 1444b1a915..6be4fd138d 100644 --- a/src/cpp/ripple/main.cpp +++ b/src/cpp/ripple/main.cpp @@ -16,6 +16,10 @@ namespace po = boost::program_options; extern bool AddSystemEntropy(); +extern void TFInit(); +extern void LEFInit(); +extern void SVFInit(); + using namespace std; using namespace boost::unit_test; @@ -188,6 +192,10 @@ int main(int argc, char* argv[]) InstanceType::multiThread(); + TFInit(); + LEFInit(); + SVFInit(); + if (vm.count("unittest")) { unit_test_main(init_unit_test, argc, argv);