[0.2.x] added : typedVarList can get nested field name ( "field.next" ) ( once again )

git-svn-id: https://pykd.svn.codeplex.com/svn@82565 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2013-02-06 08:01:54 +00:00 committed by Mikhail I. Izmestev
parent 386c120795
commit 0c6d91692d
7 changed files with 60 additions and 117 deletions

View File

@ -586,7 +586,7 @@ python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &
ULONG64 entryAddress = 0; ULONG64 entryAddress = 0;
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName ); TypeInfoPtr fieldTypeInfo = typeInfo->getFieldRecursive( listEntryName );
ULONG64 (*ptrFunc)(ULONG64) = fieldTypeInfo->ptrSize() == 4 ? &ptrDWord : &ptrQWord; ULONG64 (*ptrFunc)(ULONG64) = fieldTypeInfo->ptrSize() == 4 ? &ptrDWord : &ptrQWord;

View File

@ -623,6 +623,53 @@ TypeInfoPtr TypeInfo::arrayOf( ULONG count )
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
ULONG UdtTypeInfoBase::getFieldOffsetByNameRecursive( const std::string &fieldName )
{
// "m_field1.m_field2" -> ["m_field1", "m_field2"]
typedef boost::char_separator<char> CharSep;
boost::tokenizer< CharSep > tokenizer(fieldName, CharSep("."));
if (tokenizer.begin() == tokenizer.end())
throw TypeException( getName(), fieldName + ": invalid field name");
ULONG fieldOffset = 0;
TypeInfoPtr typeInfo = shared_from_this();
boost::tokenizer< CharSep >::iterator it = tokenizer.begin();
for (; it != tokenizer.end(); ++it)
{
const std::string &name = *it;
fieldOffset += typeInfo->getFieldOffsetByNameNotRecursively(name);
typeInfo = typeInfo->getField(name);
}
return fieldOffset;
}
/////////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr UdtTypeInfoBase::getFieldRecursive(const std::string &fieldName )
{
// "m_field1.m_field2" -> ["m_field1", "m_field2"]
typedef boost::char_separator<char> CharSep;
boost::tokenizer< CharSep > tokenizer(fieldName, CharSep("."));
if (tokenizer.begin() == tokenizer.end())
throw TypeException( getName(), fieldName + ": invalid field name");
TypeInfoPtr typeInfo = shared_from_this();
boost::tokenizer< CharSep >::iterator it = tokenizer.begin();
for (; it != tokenizer.end(); ++it)
{
const std::string &name = *it;
typeInfo = typeInfo->getField(name);
}
return typeInfo;
}
/////////////////////////////////////////////////////////////////////////////////////
std::string UdtTypeInfoBase::print() std::string UdtTypeInfoBase::print()
{ {
std::stringstream sstr; std::stringstream sstr;

View File

@ -74,6 +74,10 @@ public:
throw TypeException( getName(), "type is not a struct" ); throw TypeException( getName(), "type is not a struct" );
} }
virtual TypeInfoPtr getFieldRecursive(const std::string &fieldName ) {
throw TypeException( getName(), "type is not a struct" );
}
virtual TypeInfoPtr getFieldByIndex( ULONG index ) { virtual TypeInfoPtr getFieldByIndex( ULONG index ) {
throw TypeException( getName(), "type is not a struct" ); throw TypeException( getName(), "type is not a struct" );
} }
@ -85,6 +89,7 @@ public:
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) { virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) {
throw TypeException( getName(), "type is not a struct" ); throw TypeException( getName(), "type is not a struct" );
} }
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) { virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
throw TypeException( getName(), "type is not a struct" ); throw TypeException( getName(), "type is not a struct" );
} }
@ -333,9 +338,9 @@ protected:
return lookupField(index)->getName(); return lookupField(index)->getName();
} }
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) { virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName );
return getFieldOffsetRecursive( shared_from_this(), fieldName );
} virtual TypeInfoPtr getFieldRecursive(const std::string &fieldName );
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) { virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
return lookupField(fieldName)->getOffset(); return lookupField(fieldName)->getOffset();

View File

@ -61,29 +61,6 @@ UdtFieldPtr &FieldCollection::lookup(const std::string &name)
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
ULONG getFieldOffsetRecursive(TypeInfoPtr typeInfo, const std::string &fieldName)
{
// "m_field1.m_field2" -> ["m_field1", "m_field2"]
typedef boost::char_separator<char> CharSep;
boost::tokenizer< CharSep > tokenizer(fieldName, CharSep("."));
if (tokenizer.begin() == tokenizer.end())
throw TypeException(typeInfo->getName(), fieldName + ": invalid field name");
ULONG fieldOffset = 0;
boost::tokenizer< CharSep >::iterator it = tokenizer.begin();
for (; it != tokenizer.end(); ++it)
{
const std::string &name = *it;
fieldOffset += typeInfo->getFieldOffsetByNameNotRecursively(name);
typeInfo = typeInfo->getField(name);
}
return fieldOffset;
}
///////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr SymbolUdtField::getTypeInfo() TypeInfoPtr SymbolUdtField::getTypeInfo()
{ {
return TypeInfo::getTypeInfo(m_symbol); return TypeInfo::getTypeInfo(m_symbol);

View File

@ -183,89 +183,4 @@ private:
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
ULONG getFieldOffsetRecursive(TypeInfoPtr typeInfo, const std::string &fieldName);
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
//
//namespace UdtUtils {
//
/////////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
//
//struct Field {
//
// Field( ULONG offset, const std::string &name, SymbolPtr &symbol, SymbolPtr &baseVirtClass = SymbolPtr(),
// ULONG virtualBasePtr = 0, ULONG virtualDispIndex = 0, ULONG virtualDispSize = 0 ) :
// m_offset(offset),
// m_name(name),
// m_symbol(symbol),
// m_baseVirtClass( baseVirtClass ),
// m_virtualBasePtr( virtualBasePtr ),
// m_virtualDispIndex( virtualDispIndex ),
// m_virtualDispSize( virtualDispSize )
// {}
//
// bool operator ==(const std::string &name) const {
// return m_name == name;
// }
//
// ULONG m_offset;
// std::string m_name;
// SymbolPtr m_symbol;
// SymbolPtr m_baseVirtClass;
// ULONG m_virtualBasePtr;
// ULONG m_virtualDispIndex;
// ULONG m_virtualDispSize;
//};
//
/////////////////////////////////////////////////////////////////////////////////////
//
//class FieldCollection : public std::vector< Field > {
// typedef std::vector< Field > Base;
//public:
// FieldCollection(const std::string &baseTypeName) : m_baseTypeName(baseTypeName)
// {}
//
// const Field &lookup(ULONG index) const;
// const Field &lookup(const std::string &name) const;
//
// Field &lookup(ULONG index);
// Field &lookup(const std::string &name);
//
// const std::string &getName() const {
// return m_baseTypeName;
// }
//
//private:
// std::string m_baseTypeName;
//};
//
/////////////////////////////////////////////////////////////////////////////////////
//
//ULONG getFieldOffsetRecursive(TypeInfoPtr typeInfo, const std::string &fieldName);
//
/////////////////////////////////////////////////////////////////////////////////////
//
//} // namespace UdtUtils
//
/////////////////////////////////////////////////////////////////////////////////////
} // namespace pykd } // namespace pykd

View File

@ -68,10 +68,5 @@ if __name__ == "__main__":
target.appPath = sys.argv[1] target.appPath = sys.argv[1]
target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0] target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0]
#print "Test module: %s" % target.appPath
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() ) unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
#unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite("customtypestest.CustomTypesTest.testPtrToCustomType") )
raw_input(">")
#

View File

@ -150,6 +150,10 @@ class TypedVarTest( unittest.TestCase ):
tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" ) tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" )
self.assertEqual( 3, len( tvl ) ) self.assertEqual( 3, len( tvl ) )
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry.Flink" )
self.assertEqual( 3, len( tvl ) )
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
tvl = target.module.typedVarList( target.module.g_listHead1, "listStruct1", "next" ) tvl = target.module.typedVarList( target.module.g_listHead1, "listStruct1", "next" )
self.assertEqual( 3, len( tvl ) ) self.assertEqual( 3, len( tvl ) )