[0.3.x] fixed : issue #14120 (failed to iterate over array)

git-svn-id: https://pykd.svn.codeplex.com/svn@91247 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\ussrhero_cp 2017-07-20 22:06:59 +00:00 committed by Mikhail I. Izmestev
parent 75993e9971
commit 86e7779289
4 changed files with 60 additions and 0 deletions

View File

@ -25,6 +25,13 @@ public:
{} {}
}; };
class StopIteration : public std::exception
{
public:
StopIteration(const char* desc) : std::exception(desc)
{}
};
template< class TExcept > template< class TExcept >
struct exceptPyType{ struct exceptPyType{
@ -111,6 +118,12 @@ inline void pykdExceptionTranslate(const std::exception &e)
return; return;
} }
if (typeid(e).hash_code() == typeid(StopIteration).hash_code())
{
PyErr_SetString(PyExc_StopIteration, e.what());
return;
}
} }
inline void registerExceptions() inline void registerExceptions()
@ -125,6 +138,7 @@ inline void registerExceptions()
python::register_exception_translator<kdlib::DbgException>( &dbgExceptionTranslate ); python::register_exception_translator<kdlib::DbgException>( &dbgExceptionTranslate );
python::register_exception_translator<OverflowException>( &pykdExceptionTranslate ); python::register_exception_translator<OverflowException>( &pykdExceptionTranslate );
python::register_exception_translator<AttributeException>(&pykdExceptionTranslate); python::register_exception_translator<AttributeException>(&pykdExceptionTranslate);
python::register_exception_translator<StopIteration>(&pykdExceptionTranslate);
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////

View File

@ -928,6 +928,11 @@ BOOST_PYTHON_MODULE( pykd )
#endif #endif
; ;
python::class_<TypedVarIterator>("typedVarIterator", "iterator for typedVar array", python::no_init)
.def("__iter__", &TypedVarIterator::self)
.def("next", &TypedVarIterator::next)
;
python::class_<kdlib::TypedVar, kdlib::TypedVarPtr, python::bases<kdlib::NumBehavior>, boost::noncopyable >("typedVar", python::class_<kdlib::TypedVar, kdlib::TypedVarPtr, python::bases<kdlib::NumBehavior>, boost::noncopyable >("typedVar",
"Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance", python::no_init ) "Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance", python::no_init )
.def("__init__", python::make_constructor(pykd::getTypedVarByName) ) .def("__init__", python::make_constructor(pykd::getTypedVarByName) )
@ -982,6 +987,7 @@ BOOST_PYTHON_MODULE( pykd )
.def("__setitem__", TypedVarAdapter::setElementByIndex ) .def("__setitem__", TypedVarAdapter::setElementByIndex )
.def("__dir__", TypedVarAdapter::getElementsDir) .def("__dir__", TypedVarAdapter::getElementsDir)
.def("__call__", python::raw_function(pykd::callFunctionByVar, 0) ) .def("__call__", python::raw_function(pykd::callFunctionByVar, 0) )
.def("__iter__", TypedVarAdapter::getArrayIter, python::return_value_policy<python::manage_new_object>())
//.def("__getitem__", &kdlib::TypedVar::getElementByIndexPtr ) //.def("__getitem__", &kdlib::TypedVar::getElementByIndexPtr )
#if PY_VERSION_HEX >= 0x03000000 #if PY_VERSION_HEX >= 0x03000000
.def("__bool__", TypedVarAdapter::isNotZero) .def("__bool__", TypedVarAdapter::isNotZero)

View File

@ -51,6 +51,36 @@ inline kdlib::TypedVarPtr containingRecordByType( kdlib::MEMOFFSET_64 offset, kd
} }
class TypedVarIterator {
public:
TypedVarIterator(kdlib::TypedVarPtr& var) : m_var(var), m_pos(0)
{}
static python::object self(const python::object& obj)
{
return obj;
}
kdlib::TypedVarPtr next()
{
AutoRestorePyState pystate;
if (m_pos==m_var->getElementCount())
throw StopIteration("No more data.");
return m_var->getElement(m_pos++);
}
private:
size_t m_pos;
kdlib::TypedVarPtr m_var;
};
struct TypedVarAdapter { struct TypedVarAdapter {
@ -188,6 +218,11 @@ struct TypedVarAdapter {
} }
static python::list getRawBytes(kdlib::TypedVar& typedVar); static python::list getRawBytes(kdlib::TypedVar& typedVar);
static TypedVarIterator* getArrayIter(kdlib::TypedVarPtr& typedVar)
{
return new TypedVarIterator(typedVar);
}
}; };
} // end namespace pykd } // end namespace pykd

View File

@ -110,6 +110,11 @@ class TypedVarTest( unittest.TestCase ):
self.assertNotEqual( 0, tv.m_noArrayField ) self.assertNotEqual( 0, tv.m_noArrayField )
tv.m_arrayField[len(tv.m_arrayField)] tv.m_arrayField[len(tv.m_arrayField)]
def testArrayIteration(self):
tv = target.module.typedVar( "g_structWithArray" )
self.assertEqual([0, 2], [x for x in tv.m_arrayField])
#def testArrayFieldSlice(self): #def testArrayFieldSlice(self):
# tv = target.module.typedVar( "g_structWithArray" ) # tv = target.module.typedVar( "g_structWithArray" )
# self.assertEqual( [ 0, 2 ], tv.m_arrayField[0:2] ) # self.assertEqual( [ 0, 2 ], tv.m_arrayField[0:2] )