pykd/pykd/customtypes.cpp
SND\EreTIk_cp bd94e142d1 [0.2.x] ~ check recursive type building
git-svn-id: https://pykd.svn.codeplex.com/svn@79577 9b283d60-5439-405e-af05-b73fd8c4d996
2017-11-08 17:42:50 +04:00

139 lines
3.7 KiB
C++

#include "stdafx.h"
#include "customtypes.h"
////////////////////////////////////////////////////////////////////////////////
namespace pykd {
////////////////////////////////////////////////////////////////////////////////
void CustomTypeBase::throwIfFiledExist(const std::string &fieldName)
{
bool fieldExist = false;
try
{
lookupField(fieldName);
fieldExist = true;
}
catch (const TypeException &except)
{
DBG_UNREFERENCED_PARAMETER(except);
}
if (fieldExist)
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();
offset += offset % (m_align ? m_align : fieldType->getAlignReq());
Base::push_back(
UdtUtils::Field(offset, fieldName, fieldType)
);
}
////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr CustomUnion::create(const std::string &name)
{
return TypeInfoPtr( new CustomUnion(name) );
}
////////////////////////////////////////////////////////////////////////////////
ULONG CustomUnion::getSize()
{
ULONG size = 0;
for (ULONG i = 0; i < getFieldCount(); ++i)
{
ULONG fieldSize = lookupField(i).m_type->getSize();
if (fieldSize > size)
size = fieldSize;
}
return size;
}
////////////////////////////////////////////////////////////////////////////////
void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
{
Base::throwIfFiledExist(fieldName);
Base::throwIfTypeRecursive(fieldType);
Base::push_back(
UdtUtils::Field(0, fieldName, fieldType)
);
}
////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr PtrToVoid()
{
return TypeInfoPtr( new PointerTypeInfo(ptrSize()) );
}
////////////////////////////////////////////////////////////////////////////////
} // namespace pykd
////////////////////////////////////////////////////////////////////////////////