Commit af129a9a authored by SND\ussrhero_cp's avatar SND\ussrhero_cp Committed by Mikhail I. Izmestev
Browse files

[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
parent 61bab003
......@@ -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,8 +130,33 @@ kdlib::TypeInfoPtr TypeInfoAdapter::getElementAttr(kdlib::TypeInfo &typeInfo, co
///////////////////////////////////////////////////////////////////////////////
python::list TypeInfoAdapter::getElementDir(kdlib::TypeInfo &typeInfo)
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;
python::list pylst;
......
......@@ -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 ):
def testBaseTypes( self ):
self.assertEqual("Int1B", pykd.typeInfo( "Int1B" ).name() )
self.assertEqual("Int2B", pykd.typeInfo( "Int2B" ).name() )
self.assertEqual("Int4B", pykd.typeInfo( "Int4B" ).name() )
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment