mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.3.x] added : typeInfo.__getitem__ (Get a field's type by the field's name )
[0.3.x] added : typedVar.__getitem__ (Get a field's value by the field's name ) [0.3.x] added : typedVar.__settitem__ (Set a value to a field by name ) git-svn-id: https://pykd.svn.codeplex.com/svn@91261 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
61bab00356
commit
af129a9a00
@ -25,6 +25,14 @@ public:
|
||||
{}
|
||||
};
|
||||
|
||||
class KeyException : public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
KeyException(const char* desc) : std::exception(desc)
|
||||
{}
|
||||
};
|
||||
|
||||
class StopIteration : public std::exception
|
||||
{
|
||||
public:
|
||||
@ -124,6 +132,11 @@ inline void pykdExceptionTranslate(const std::exception &e)
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeid(e).hash_code() == typeid(KeyException).hash_code())
|
||||
{
|
||||
PyErr_SetString(PyExc_KeyError, e.what());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void registerExceptions()
|
||||
@ -139,6 +152,7 @@ inline void registerExceptions()
|
||||
python::register_exception_translator<OverflowException>( &pykdExceptionTranslate );
|
||||
python::register_exception_translator<AttributeException>(&pykdExceptionTranslate);
|
||||
python::register_exception_translator<StopIteration>(&pykdExceptionTranslate);
|
||||
python::register_exception_translator<KeyException>(&pykdExceptionTranslate);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -937,6 +937,7 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def( "__getattr__", TypeInfoAdapter::getElementAttr )
|
||||
.def( "__len__", TypeInfoAdapter::getElementCount )
|
||||
.def( "__getitem__", TypeInfoAdapter::getElementByIndex )
|
||||
.def( "__getitem__", TypeInfoAdapter::getElementByKey )
|
||||
.def( "__dir__", TypeInfoAdapter::getElementDir )
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
.def("__bool__", TypeInfoAdapter::isZero )
|
||||
@ -1002,6 +1003,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def("__len__", TypedVarAdapter::getElementCount )
|
||||
.def("__getitem__", TypedVarAdapter::getElementByIndex )
|
||||
.def("__setitem__", TypedVarAdapter::setElementByIndex )
|
||||
.def( "__getitem__", TypedVarAdapter::getFieldByKey )
|
||||
.def( "__setitem__", TypedVarAdapter::setFieldByKey )
|
||||
.def("__dir__", TypedVarAdapter::getElementsDir)
|
||||
.def("__call__", python::raw_function(pykd::callFunctionByVar, 0) )
|
||||
.def("__iter__", TypedVarAdapter::getArrayIter, python::return_value_policy<python::manage_new_object>())
|
||||
|
@ -258,5 +258,53 @@ void TypedVarAdapter::setFieldAttr(kdlib::TypedVar& typedVar, const std::wstring
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
kdlib::TypedVarPtr TypedVarAdapter::getFieldByKey(kdlib::TypedVar& typedVar, const std::wstring &name)
|
||||
{
|
||||
{
|
||||
|
||||
AutoRestorePyState pystate;
|
||||
|
||||
try
|
||||
{
|
||||
return typedVar.getElement( name );
|
||||
}
|
||||
catch (kdlib::TypeException&)
|
||||
{}
|
||||
|
||||
try
|
||||
{
|
||||
return typedVar.getMethod( name );
|
||||
}
|
||||
catch (kdlib::TypeException&)
|
||||
{}
|
||||
}
|
||||
|
||||
std::wstringstream sstr;
|
||||
sstr << L"typed var has no field " << L'\'' << name << L'\'';
|
||||
throw KeyException(std::string(_bstr_t(sstr.str().c_str())).c_str());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TypedVarAdapter::setFieldByKey(kdlib::TypedVar& typedVar, const std::wstring &name, python::object& object)
|
||||
{
|
||||
kdlib::TypedValue value = NumVariantAdaptor::convertToVariant(object);
|
||||
|
||||
try
|
||||
{
|
||||
AutoRestorePyState pystate;
|
||||
typedVar.setElement(name, value);
|
||||
return;
|
||||
}
|
||||
catch (kdlib::TypeException&)
|
||||
{}
|
||||
|
||||
std::wstringstream sstr;
|
||||
sstr << L"typed var has no field " << L'\'' << name << L'\'';
|
||||
throw KeyException(std::string(_bstr_t(sstr.str().c_str())).c_str());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace pykd
|
||||
|
||||
|
@ -146,6 +146,10 @@ struct TypedVarAdapter {
|
||||
|
||||
static void setFieldAttr(kdlib::TypedVar& typedVar, const std::wstring &name, python::object& object);
|
||||
|
||||
static kdlib::TypedVarPtr getFieldByKey(kdlib::TypedVar& typedVar, const std::wstring &name);
|
||||
|
||||
static void setFieldByKey(kdlib::TypedVar& typedVar, const std::wstring &name, python::object& object);
|
||||
|
||||
static size_t getElementCount( kdlib::TypedVar& typedVar )
|
||||
{
|
||||
AutoRestorePyState pystate;
|
||||
|
@ -130,6 +130,31 @@ kdlib::TypeInfoPtr TypeInfoAdapter::getElementAttr(kdlib::TypeInfo &typeInfo, co
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
kdlib::TypeInfoPtr TypeInfoAdapter::getElementByKey(kdlib::TypeInfo &typeInfo, const std::wstring &name)
|
||||
{
|
||||
{
|
||||
AutoRestorePyState pystate;
|
||||
|
||||
try {
|
||||
return typeInfo.getElement(name);
|
||||
}
|
||||
catch (kdlib::TypeException&)
|
||||
{}
|
||||
|
||||
try {
|
||||
return typeInfo.getMethod(name);
|
||||
}
|
||||
catch (kdlib::TypeException&)
|
||||
{}
|
||||
}
|
||||
|
||||
std::wstringstream sstr;
|
||||
sstr << L'\'' << typeInfo.getName() << L'\'' << L" type has no field " << L'\'' << name << L'\'';
|
||||
throw KeyException(std::string(_bstr_t(sstr.str().c_str())).c_str());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::list TypeInfoAdapter::getElementDir(kdlib::TypeInfo &typeInfo)
|
||||
{
|
||||
std::list<std::wstring> lst;
|
||||
|
@ -146,6 +146,8 @@ struct TypeInfoAdapter : public kdlib::TypeInfo {
|
||||
|
||||
static kdlib::TypeInfoPtr getElementAttr(kdlib::TypeInfo &typeInfo, const std::wstring &name);
|
||||
|
||||
static kdlib::TypeInfoPtr getElementByKey(kdlib::TypeInfo &typeInfo, const std::wstring &name);
|
||||
|
||||
static kdlib::TypeInfoPtr getElementByIndex( kdlib::TypeInfo &typeInfo, size_t index )
|
||||
{
|
||||
AutoRestorePyState pystate;
|
||||
|
@ -86,6 +86,9 @@ class TypedVarTest( unittest.TestCase ):
|
||||
self.assertEqual( 500, tv1.m_field1 )
|
||||
self.assertEqual( True, tv1.m_field2 )
|
||||
self.assertEqual( 1, tv1.m_field3 )
|
||||
self.assertEqual( 1, tv1["m_field3"] )
|
||||
self.assertRaises( AttributeError, lambda t: t.not_exists, tv1) # non-exsisting field
|
||||
self.assertRaises( KeyError, lambda t: t["not_exists"], tv1) # non-exsisting field
|
||||
|
||||
def testPtrField(self):
|
||||
tv = target.module.typedVar( "g_structTest" )
|
||||
|
@ -36,16 +36,18 @@ class TypeInfoTest( unittest.TestCase ):
|
||||
self.assertEqual( "Int4B(*[4])[2][3]", target.module.type("arrIntMatrixPtrs").name() )
|
||||
self.assertEqual( "Int4B(*)[2][3]", target.module.type("ptrIntMatrix").name() )
|
||||
|
||||
|
||||
def testGetField( self ):
|
||||
""" get field of the complex type """
|
||||
ti1 = target.module.type( "structTest" )
|
||||
self.assertTrue( "UInt4B", ti1.m_field0.name() )
|
||||
self.assertTrue( "UInt4B", ti1["m_field0"].name() )
|
||||
self.assertTrue( hasattr( ti1, "m_field0" ) )
|
||||
try: hasattr(ti1, "m_field4" ) # non-exsisting field
|
||||
except pykd.BaseException: pass
|
||||
self.assertFalse( hasattr( ti1, "not_exists" ) )
|
||||
self.assertRaises( AttributeError, lambda t: t.not_exists, ti1) # non-exsisting field
|
||||
self.assertRaises( KeyError, lambda t: t["not_exists"], ti1) # non-exsisting field
|
||||
|
||||
|
||||
def testBaseTypes( self ):
|
||||
|
||||
self.assertEqual("Int1B", pykd.typeInfo( "Int1B" ).name() )
|
||||
self.assertEqual("Int2B", pykd.typeInfo( "Int2B" ).name() )
|
||||
self.assertEqual("Int4B", pykd.typeInfo( "Int4B" ).name() )
|
||||
|
Loading…
Reference in New Issue
Block a user