Bugfixes from unit test.

This commit is contained in:
JoelKatz
2012-04-25 21:47:20 -07:00
parent 44423a4c6d
commit ccd2f9a76f

View File

@@ -79,10 +79,9 @@ STObject::STObject(SOElement* elem, const char *name) : SerializedType(name), mF
{ {
while (elem->e_id != STI_DONE) while (elem->e_id != STI_DONE)
{ {
if (elem->e_type == SOE_FLAGS) if (elem->e_type == SOE_FLAGS) mFlagIdx = mType.size();
mFlagIdx = mType.size();
mType.push_back(elem); mType.push_back(elem);
if ( (elem->e_type == SOE_IFFLAG) || (elem->e_type == SOE_IFNFLAG) ) if (elem->e_type == SOE_IFFLAG)
giveObject(new STObject(elem->e_name)); giveObject(new STObject(elem->e_name));
else else
{ {
@@ -90,7 +89,7 @@ STObject::STObject(SOElement* elem, const char *name) : SerializedType(name), mF
if (!t) throw std::runtime_error("invalid transaction element"); if (!t) throw std::runtime_error("invalid transaction element");
giveObject(t); giveObject(t);
} }
elem++; ++elem;
} }
} }
@@ -118,7 +117,7 @@ STObject::STObject(SOElement* elem, SerializerIterator& sit, const char *name) :
mFlagIdx = giveObject(new STUInt32(elem->e_name, flags)); mFlagIdx = giveObject(new STUInt32(elem->e_name, flags));
done = true; done = true;
} }
if(!done) if (!done)
{ {
SerializedType* t = makeDeserializedObject(elem->e_id, elem->e_name, sit); SerializedType* t = makeDeserializedObject(elem->e_id, elem->e_name, sit);
if (!t) throw std::runtime_error("invalid transaction element"); if (!t) throw std::runtime_error("invalid transaction element");
@@ -187,14 +186,14 @@ bool STObject::isEquivalent(const SerializedType& t) const
++it1; ++it1;
++it2; ++it2;
} }
return (it1==end1) && (it2==end2); return (it1 == end1) && (it2 == end2);
} }
int STObject::getFieldIndex(SOE_Field field) const int STObject::getFieldIndex(SOE_Field field) const
{ {
int i = 0; int i = 0;
for (std::vector<SOElement*>::const_iterator it = mType.begin(), end = mType.end(); it != end; ++it, ++i) for (std::vector<SOElement*>::const_iterator it = mType.begin(), end = mType.end(); it != end; ++it, ++i)
if( (*it)->e_field == field) return i; if ((*it)->e_field == field) return i;
return -1; return -1;
} }
@@ -230,12 +229,12 @@ bool STObject::isFieldPresent(SOE_Field field) const
{ {
int index = getFieldIndex(field); int index = getFieldIndex(field);
if (index == -1) return false; if (index == -1) return false;
return peekAtIndex(field).getSType() == STI_OBJECT; return peekAtIndex(index).getSType() != STI_OBJECT;
} }
bool STObject::setFlag(uint32 f) bool STObject::setFlag(uint32 f)
{ {
if (mFlagIdx<0) return false; if (mFlagIdx < 0) return false;
STUInt32* t = dynamic_cast<STUInt32*>(getPIndex(mFlagIdx)); STUInt32* t = dynamic_cast<STUInt32*>(getPIndex(mFlagIdx));
assert(t); assert(t);
t->setValue(t->getValue() | f); t->setValue(t->getValue() | f);
@@ -244,7 +243,7 @@ bool STObject::setFlag(uint32 f)
bool STObject::clearFlag(uint32 f) bool STObject::clearFlag(uint32 f)
{ {
if (mFlagIdx<0) return false; if (mFlagIdx < 0) return false;
STUInt32* t = dynamic_cast<STUInt32*>(getPIndex(mFlagIdx)); STUInt32* t = dynamic_cast<STUInt32*>(getPIndex(mFlagIdx));
assert(t); assert(t);
t->setValue(t->getValue() & ~f); t->setValue(t->getValue() & ~f);
@@ -253,28 +252,47 @@ bool STObject::clearFlag(uint32 f)
uint32 STObject::getFlags(void) const uint32 STObject::getFlags(void) const
{ {
if (mFlagIdx<0) return 0; if (mFlagIdx < 0) return 0;
const STUInt32* t = dynamic_cast<const STUInt32*>(peekAtPIndex(mFlagIdx)); const STUInt32* t = dynamic_cast<const STUInt32*>(peekAtPIndex(mFlagIdx));
assert(t); assert(t);
return t->getValue(); return t->getValue();
} }
void STObject::makeFieldPresent(SOE_Field field) SerializedType* STObject::makeFieldPresent(SOE_Field field)
{ {
SerializedType* ret = NULL;
int index = getFieldIndex(field); int index = getFieldIndex(field);
if (index == -1) throw std::runtime_error("Field not found"); if (index == -1) throw std::runtime_error("Field not found");
if (peekAtIndex(field).getSType() != STI_OBJECT) return; if ((mType[index]->e_type != SOE_IFFLAG) && (mType[index]->e_type != SOE_IFNFLAG))
mData.replace(index, makeDefaultObject(mType[index]->e_id, mType[index]->e_name)); throw std::runtime_error("field is not optional");
setFlag(mType[index]->e_flags);
ret = getPIndex(index);
if (ret->getSType() != STI_OBJECT) return ret;
ret = makeDefaultObject(mType[index]->e_id, mType[index]->e_name);
mData.replace(index, ret);
if (mType[index]->e_type == SOE_IFFLAG)
setFlag(mType[index]->e_flags);
else if (mType[index]->e_type == SOE_IFNFLAG)
clearFlag(mType[index]->e_flags);
return ret;
} }
void STObject::makeFieldAbsent(SOE_Field field) void STObject::makeFieldAbsent(SOE_Field field)
{ {
int index = getFieldIndex(field); int index = getFieldIndex(field);
if (index == -1) throw std::runtime_error("Field not found"); if (index == -1) throw std::runtime_error("Field not found");
if (peekAtIndex(field).getSType() == STI_OBJECT) return; if ((mType[index]->e_type != SOE_IFFLAG) && (mType[index]->e_type != SOE_IFNFLAG))
throw std::runtime_error("field is not optional");
if (peekAtIndex(index).getSType() == STI_OBJECT) return;
mData.replace(index, new STObject(mType[index]->e_name)); mData.replace(index, new STObject(mType[index]->e_name));
clearFlag(mType[index]->e_flags);
if (mType[index]->e_type == SOE_IFFLAG)
clearFlag(mType[index]->e_flags);
else if (mType[index]->e_type == SOE_IFNFLAG)
setFlag(mType[index]->e_flags);
} }
std::string STObject::getFieldString(SOE_Field field) const std::string STObject::getFieldString(SOE_Field field) const
@@ -387,13 +405,7 @@ void STObject::setValueFieldU8(SOE_Field field, unsigned char v)
{ {
SerializedType* rf = getPField(field); SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found"); if (!rf) throw std::runtime_error("Field not found");
SerializedTypeID id = rf->getSType(); if (rf->getSType() == STI_OBJECT) rf = makeFieldPresent(field);
if (id == STI_OBJECT)
{
makeFieldPresent(field);
rf = getPField(field);
id = rf->getSType();
}
STUInt8* cf = dynamic_cast<STUInt8*>(rf); STUInt8* cf = dynamic_cast<STUInt8*>(rf);
if (!cf) throw std::runtime_error("Wrong field type"); if (!cf) throw std::runtime_error("Wrong field type");
cf->setValue(v); cf->setValue(v);
@@ -403,13 +415,7 @@ void STObject::setValueFieldU16(SOE_Field field, uint16 v)
{ {
SerializedType* rf = getPField(field); SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found"); if (!rf) throw std::runtime_error("Field not found");
SerializedTypeID id = rf->getSType(); if (rf->getSType() == STI_OBJECT) rf = makeFieldPresent(field);
if (id == STI_OBJECT)
{
makeFieldPresent(field);
rf = getPField(field);
id = rf->getSType();
}
STUInt16* cf = dynamic_cast<STUInt16*>(rf); STUInt16* cf = dynamic_cast<STUInt16*>(rf);
if (!cf) throw std::runtime_error("Wrong field type"); if (!cf) throw std::runtime_error("Wrong field type");
cf->setValue(v); cf->setValue(v);
@@ -419,13 +425,7 @@ void STObject::setValueFieldU32(SOE_Field field, uint32 v)
{ {
SerializedType* rf = getPField(field); SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found"); if (!rf) throw std::runtime_error("Field not found");
SerializedTypeID id = rf->getSType(); if (rf->getSType() == STI_OBJECT) rf = makeFieldPresent(field);
if (id == STI_OBJECT)
{
makeFieldPresent(field);
rf = getPField(field);
id = rf->getSType();
}
STUInt32* cf = dynamic_cast<STUInt32*>(rf); STUInt32* cf = dynamic_cast<STUInt32*>(rf);
if (!cf) throw std::runtime_error("Wrong field type"); if (!cf) throw std::runtime_error("Wrong field type");
cf->setValue(v); cf->setValue(v);
@@ -435,13 +435,7 @@ void STObject::setValueFieldU64(SOE_Field field, uint64 v)
{ {
SerializedType* rf = getPField(field); SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found"); if (!rf) throw std::runtime_error("Field not found");
SerializedTypeID id = rf->getSType(); if (rf->getSType() == STI_OBJECT) rf = makeFieldPresent(field);
if (id == STI_OBJECT)
{
makeFieldPresent(field);
rf = getPField(field);
id = rf->getSType();
}
STUInt64* cf = dynamic_cast<STUInt64*>(rf); STUInt64* cf = dynamic_cast<STUInt64*>(rf);
if (!cf) throw std::runtime_error("Wrong field type"); if (!cf) throw std::runtime_error("Wrong field type");
cf->setValue(v); cf->setValue(v);
@@ -451,13 +445,7 @@ void STObject::setValueFieldH160(SOE_Field field, const uint160& v)
{ {
SerializedType* rf = getPField(field); SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found"); if (!rf) throw std::runtime_error("Field not found");
SerializedTypeID id = rf->getSType(); if (rf->getSType() == STI_OBJECT) rf = makeFieldPresent(field);
if (id == STI_OBJECT)
{
makeFieldPresent(field);
rf = getPField(field);
id = rf->getSType();
}
STHash160* cf = dynamic_cast<STHash160*>(rf); STHash160* cf = dynamic_cast<STHash160*>(rf);
if (!cf) throw std::runtime_error("Wrong field type"); if (!cf) throw std::runtime_error("Wrong field type");
cf->setValue(v); cf->setValue(v);
@@ -467,13 +455,7 @@ void STObject::setValueFieldAccount(SOE_Field field, const uint160& v)
{ {
SerializedType* rf = getPField(field); SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found"); if (!rf) throw std::runtime_error("Field not found");
SerializedTypeID id = rf->getSType(); if (rf->getSType() == STI_OBJECT) rf = makeFieldPresent(field);
if (id == STI_OBJECT)
{
makeFieldPresent(field);
rf = getPField(field);
id = rf->getSType();
}
STAccount* cf = dynamic_cast<STAccount*>(rf); STAccount* cf = dynamic_cast<STAccount*>(rf);
if (!cf) throw std::runtime_error("Wrong field type"); if (!cf) throw std::runtime_error("Wrong field type");
cf->setValueH160(v); cf->setValueH160(v);
@@ -483,13 +465,7 @@ void STObject::setValueFieldVL(SOE_Field field, const std::vector<unsigned char>
{ {
SerializedType* rf = getPField(field); SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found"); if (!rf) throw std::runtime_error("Field not found");
SerializedTypeID id = rf->getSType(); if (rf->getSType() == STI_OBJECT) rf = makeFieldPresent(field);
if (id == STI_OBJECT)
{
makeFieldPresent(field);
rf=getPField(field);
id=rf->getSType();
}
STVariableLength* cf = dynamic_cast<STVariableLength*>(rf); STVariableLength* cf = dynamic_cast<STVariableLength*>(rf);
if (!cf) throw std::runtime_error("Wrong field type"); if (!cf) throw std::runtime_error("Wrong field type");
cf->setValue(v); cf->setValue(v);
@@ -499,13 +475,7 @@ void STObject::setValueFieldTL(SOE_Field field, const std::vector<TaggedListItem
{ {
SerializedType* rf = getPField(field); SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found"); if (!rf) throw std::runtime_error("Field not found");
SerializedTypeID id = rf->getSType(); if (rf->getSType() == STI_OBJECT) rf = makeFieldPresent(field);
if (id == STI_OBJECT)
{
makeFieldPresent(field);
rf=getPField(field);
id=rf->getSType();
}
STTaggedList* cf = dynamic_cast<STTaggedList*>(rf); STTaggedList* cf = dynamic_cast<STTaggedList*>(rf);
if (!cf) throw std::runtime_error("Wrong field type"); if (!cf) throw std::runtime_error("Wrong field type");
cf->setValue(v); cf->setValue(v);
@@ -527,3 +497,36 @@ Json::Value STObject::getJson(int options) const
} }
return ret; return ret;
} }
static SOElement testSOElements[2][16] =
{ // field, name, id, type, flags
{
{ sfFlags, "Flags", STI_UINT32, SOE_FLAGS, 0 },
{ sfTest1, "Test1", STI_VL, SOE_REQUIRED, 0 },
{ sfTest2, "Test2", STI_HASH256, SOE_IFFLAG, 1 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 }
}
};
void STObject::unitTest()
{
STObject object1(testSOElements[0], "TestElement1");
STObject object2(object1);
if (object1.getSerializer() != object2.getSerializer()) throw std::runtime_error("STObject error");
if (object1.isFieldPresent(sfTest2) || !object1.isFieldPresent(sfTest1))
throw std::runtime_error("STObject error");
object1.makeFieldPresent(sfTest2);
if (!object1.isFieldPresent(sfTest2)) throw std::runtime_error("STObject Error");
if ((object1.getFlags() != 1) || (object2.getFlags() != 0)) throw std::runtime_error("STObject error");
if (object1.getValueFieldH256(sfTest2) != uint256()) throw std::runtime_error("STObject error");
if (object1.getSerializer() == object2.getSerializer()) throw std::runtime_error("STObject error");
object1.makeFieldAbsent(sfTest2);
if (object1.getFlags() != 0) throw std::runtime_error("STObject error");
if (object1.getSerializer() != object2.getSerializer()) throw std::runtime_error("STObject error");
}
// vim:ts=4