[0.2.x] ~ check recursive type building

git-svn-id: https://pykd.svn.codeplex.com/svn@79577 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\EreTIk_cp 2012-09-14 16:46:35 +00:00 committed by Mikhail I. Izmestev
parent 13b1676d6f
commit bd94e142d1
3 changed files with 91 additions and 37 deletions

View File

@ -8,25 +8,7 @@ namespace pykd {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr CustomStruct::create(const std::string &name, ULONG alignReq /*= 0*/) void CustomTypeBase::throwIfFiledExist(const std::string &fieldName)
{
return TypeInfoPtr( new CustomStruct(name, alignReq) );
}
////////////////////////////////////////////////////////////////////////////////
ULONG CustomStruct::getSize()
{
if (UdtFieldColl::empty())
return 0;
UdtUtils::Field &field = UdtFieldColl::last();
return field.m_offset + field.m_type->getSize();
}
////////////////////////////////////////////////////////////////////////////////
void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
{ {
bool fieldExist = false; bool fieldExist = false;
try try
@ -40,10 +22,71 @@ void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldTy
} }
if (fieldExist) if (fieldExist)
throw TypeException(getName(), "duplicate field name: " + fieldName); throw TypeException(getName(), "duplicate field name: " + fieldName);
}
////////////////////////////////////////////////////////////////////////////////
void CustomTypeBase::throwIfTypeRecursive(TypeInfoPtr type)
{
if (type->is(this))
throw TypeException(getName(), "wrong type of field");
return throwIfTypeRecursiveImpl(type);
}
////////////////////////////////////////////////////////////////////////////////
void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
{
if (type->isEnum())
return;
try
{
const ULONG fields = type->getFieldCount();
for (ULONG i = 0; i < fields; ++i)
{
TypeInfoPtr fileldType = type->getFieldByIndex(i);
if (fileldType->is(this))
throw TypeException(getName(), "wrong type of field");
throwIfTypeRecursiveImpl(fileldType);
}
}
catch (const TypeException &except)
{
DBG_UNREFERENCED_PARAMETER(except);
}
}
////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr CustomStruct::create(const std::string &name, ULONG alignReq /*= 0*/)
{
return TypeInfoPtr( new CustomStruct(name, alignReq) );
}
////////////////////////////////////////////////////////////////////////////////
ULONG CustomStruct::getSize()
{
if (Base::empty())
return 0;
UdtUtils::Field &field = Base::last();
return field.m_offset + field.m_type->getSize();
}
////////////////////////////////////////////////////////////////////////////////
void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
{
Base::throwIfFiledExist(fieldName);
Base::throwIfTypeRecursive(fieldType);
ULONG offset = getSize(); ULONG offset = getSize();
offset += offset % (m_align ? m_align : fieldType->getAlignReq()); offset += offset % (m_align ? m_align : fieldType->getAlignReq());
UdtFieldColl::push_back( Base::push_back(
UdtUtils::Field(offset, fieldName, fieldType) UdtUtils::Field(offset, fieldName, fieldType)
); );
} }
@ -73,20 +116,10 @@ ULONG CustomUnion::getSize()
void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType) void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
{ {
bool fieldExist = false; Base::throwIfFiledExist(fieldName);
try Base::throwIfTypeRecursive(fieldType);
{
lookupField(fieldName);
fieldExist = true;
}
catch (const TypeException &except)
{
DBG_UNREFERENCED_PARAMETER(except);
}
if (fieldExist)
throw TypeException(getName(), "duplicate field name: " + fieldName);
UdtFieldColl::push_back( Base::push_back(
UdtUtils::Field(0, fieldName, fieldType) UdtUtils::Field(0, fieldName, fieldType)
); );
} }

View File

@ -12,14 +12,30 @@ namespace pykd {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CustomStruct : public UdtFieldColl class CustomTypeBase : public UdtFieldColl
{ {
typedef UdtFieldColl Base;
protected:
CustomTypeBase(const std::string &name) : UdtFieldColl(name) {}
void throwIfFiledExist(const std::string &fieldName);
void throwIfTypeRecursive(TypeInfoPtr type);
private:
void throwIfTypeRecursiveImpl(TypeInfoPtr type);
};
////////////////////////////////////////////////////////////////////////////////
class CustomStruct : public CustomTypeBase
{
typedef CustomTypeBase Base;
public: public:
static TypeInfoPtr create(const std::string &name, ULONG align = 0); static TypeInfoPtr create(const std::string &name, ULONG align = 0);
protected: protected:
CustomStruct(const std::string &name, ULONG align) CustomStruct(const std::string &name, ULONG align)
: UdtFieldColl(name), m_name(name), m_align(align) : Base(name), m_name(name), m_align(align)
{ {
} }
@ -42,13 +58,14 @@ private:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CustomUnion : public UdtFieldColl class CustomUnion : public CustomTypeBase
{ {
typedef CustomTypeBase Base;
public: public:
static TypeInfoPtr create(const std::string &name); static TypeInfoPtr create(const std::string &name);
protected: protected:
CustomUnion(const std::string &name) : UdtFieldColl(name) {} CustomUnion(const std::string &name) : Base(name) {}
virtual ULONG getSize() override; virtual ULONG getSize() override;

View File

@ -211,6 +211,10 @@ public:
return m_virtualBaseType; return m_virtualBaseType;
} }
bool is(TypeInfo *rhs) const {
return this == rhs;
}
protected: protected:
std::string getComplexName(); std::string getComplexName();