diff --git a/src/SerializedObject.cpp b/src/SerializedObject.cpp index 8615bb0df3..fb30248f64 100644 --- a/src/SerializedObject.cpp +++ b/src/SerializedObject.cpp @@ -374,11 +374,15 @@ const SerializedType* STObject::peekAtPField(SField::ref field) const return peekAtPIndex(index); } -SerializedType* STObject::getPField(SField::ref field) +SerializedType* STObject::getPField(SField::ref field, bool createOkay) { int index = getFieldIndex(field); if (index == -1) + { + if (createOkay && isFree()) + return getPIndex(giveObject(makeDefaultObject(field))); return NULL; + } return getPIndex(index); } @@ -392,7 +396,7 @@ bool STObject::isFieldPresent(SField::ref field) const bool STObject::setFlag(uint32 f) { - STUInt32* t = dynamic_cast(getPField(sfFlags)); + STUInt32* t = dynamic_cast(getPField(sfFlags, true)); if (!t) return false; t->setValue(t->getValue() | f); @@ -420,7 +424,11 @@ SerializedType* STObject::makeFieldPresent(SField::ref field) { int index = getFieldIndex(field); if (index == -1) - throw std::runtime_error("Field not found"); + { + if (!isFree()) + throw std::runtime_error("Field not found"); + return getPIndex(giveObject(makeNonPresentObject(field))); + } SerializedType* f = getPIndex(index); if (f->getSType() != STI_NOTPRESENT) @@ -626,7 +634,7 @@ STVector256 STObject::getFieldV256(SField::ref field) const void STObject::setFieldU8(SField::ref field, unsigned char v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STUInt8* cf = dynamic_cast(rf); @@ -636,7 +644,7 @@ void STObject::setFieldU8(SField::ref field, unsigned char v) void STObject::setFieldU16(SField::ref field, uint16 v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STUInt16* cf = dynamic_cast(rf); @@ -646,7 +654,7 @@ void STObject::setFieldU16(SField::ref field, uint16 v) void STObject::setFieldU32(SField::ref field, uint32 v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STUInt32* cf = dynamic_cast(rf); @@ -656,7 +664,7 @@ void STObject::setFieldU32(SField::ref field, uint32 v) void STObject::setFieldU64(SField::ref field, uint64 v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STUInt64* cf = dynamic_cast(rf); @@ -666,7 +674,7 @@ void STObject::setFieldU64(SField::ref field, uint64 v) void STObject::setFieldH128(SField::ref field, const uint128& v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STHash128* cf = dynamic_cast(rf); @@ -676,7 +684,7 @@ void STObject::setFieldH128(SField::ref field, const uint128& v) void STObject::setFieldH160(SField::ref field, const uint160& v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STHash160* cf = dynamic_cast(rf); @@ -686,7 +694,7 @@ void STObject::setFieldH160(SField::ref field, const uint160& v) void STObject::setFieldH256(SField::ref field, const uint256& v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STHash256* cf = dynamic_cast(rf); @@ -696,7 +704,7 @@ void STObject::setFieldH256(SField::ref field, const uint256& v) void STObject::setFieldV256(SField::ref field, const STVector256& v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STVector256* cf = dynamic_cast(rf); @@ -706,7 +714,7 @@ void STObject::setFieldV256(SField::ref field, const STVector256& v) void STObject::setFieldAccount(SField::ref field, const uint160& v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STAccount* cf = dynamic_cast(rf); @@ -716,7 +724,7 @@ void STObject::setFieldAccount(SField::ref field, const uint160& v) void STObject::setFieldVL(SField::ref field, const std::vector& v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STVariableLength* cf = dynamic_cast(rf); @@ -726,7 +734,7 @@ void STObject::setFieldVL(SField::ref field, const std::vector& v void STObject::setFieldAmount(SField::ref field, const STAmount &v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STAmount* cf = dynamic_cast(rf); @@ -736,7 +744,7 @@ void STObject::setFieldAmount(SField::ref field, const STAmount &v) void STObject::setFieldPathSet(SField::ref field, const STPathSet &v) { - SerializedType* rf = getPField(field); + SerializedType* rf = getPField(field, true); if (!rf) throw std::runtime_error("Field not found"); if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); STPathSet* cf = dynamic_cast(rf); diff --git a/src/SerializedObject.h b/src/SerializedObject.h index 2e28fc958b..7ecd539eb3 100644 --- a/src/SerializedObject.h +++ b/src/SerializedObject.h @@ -51,6 +51,7 @@ public: bool setType(const std::vector& type); bool isValidForType(); bool isFieldAllowed(SField::ref); + bool isFree() const { return mType.empty(); } void set(const std::vector&); bool set(SerializerIterator& u, int depth = 0); @@ -95,7 +96,7 @@ public: const SerializedType& peekAtField(SField::ref field) const; SerializedType& getField(SField::ref field); const SerializedType* peekAtPField(SField::ref field) const; - SerializedType* getPField(SField::ref field); + SerializedType* getPField(SField::ref field, bool createOkay = false); // these throw if the field type doesn't match, or return default values if the // field is optional but not present