From b3e8165aa1c3f4e29f1cc9a78a4f009ac5e53325 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 22 May 2012 11:21:02 +0000 Subject: [PATCH] [0.1.x] added : "subscription" for UDT typedVar git-svn-id: https://pykd.svn.codeplex.com/svn@76519 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/typedvar.cpp | 25 +++++++++++++++++++++++++ pykd/typedvar.h | 10 +++++++++- pykd/typeinfo.cpp | 6 ++++++ test/scripts/typedvar.py | 9 ++++++++- 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/pykd/typedvar.cpp b/pykd/typedvar.cpp index 3ea6395..890e9a3 100644 --- a/pykd/typedvar.cpp +++ b/pykd/typedvar.cpp @@ -252,6 +252,31 @@ UdtTypedVar::getField( const std::string &fieldName ) /////////////////////////////////////////////////////////////////////////////////// +TypedVarPtr +UdtTypedVar::getElementByIndex( ULONG index ) +{ + TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(index); + + if ( fieldType->isStaticMember() ) + { + if ( fieldType->getStaticOffset() == 0 ) + throw ImplementException( __FILE__, __LINE__, "Fix ME"); + + return TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) ); + } + + ULONG fieldOffset = fieldType->getOffset(); + + if ( fieldType->isVirtualMember() ) + { + fieldOffset += getVirtualBaseDisplacement( fieldType ); + } + + return TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldOffset) ); +} + +/////////////////////////////////////////////////////////////////////////////////// + LONG UdtTypedVar::getVirtualBaseDisplacement( TypeInfoPtr& typeInfo ) { ULONG virtualBasePtr, virtualDispIndex, virtualDispSize; diff --git a/pykd/typedvar.h b/pykd/typedvar.h index acb32ff..8c2ddc0 100644 --- a/pykd/typedvar.h +++ b/pykd/typedvar.h @@ -68,7 +68,7 @@ public: throw PyException( PyExc_TypeError, "object is unsubscriptable"); } - virtual TypedVarPtr getElementByIndexPtr( const TypedVarPtr& tv ) { + TypedVarPtr getElementByIndexPtr( const TypedVarPtr& tv ) { return getElementByIndex( boost::apply_visitor( VariantToULong(), tv->getValue() ) ); } @@ -172,12 +172,20 @@ public: { } +protected: + virtual std::string print(); virtual std::string printValue(); virtual TypedVarPtr getField( const std::string &fieldName ); + virtual ULONG getElementCount() { + return m_typeInfo->getFieldCount(); + } + + virtual TypedVarPtr getElementByIndex( ULONG index ); + LONG getVirtualBaseDisplacement( TypeInfoPtr& typeInfo ); }; diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index 349adfa..afaa716 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -529,6 +529,9 @@ TypeInfoPtr UdtTypeInfo::getFieldByIndex( ULONG index ) getVirtualFields(); } + if ( index >= m_fields.size() ) + throw PyException( PyExc_IndexError, "Index out of range"); + return m_fields[ index ].second; } @@ -542,6 +545,9 @@ std::string UdtTypeInfo::getFieldNameByIndex( ULONG index ) getVirtualFields(); } + if ( index >= m_fields.size() ) + throw PyException( PyExc_IndexError, "Index out of range"); + return m_fields[ index ].first; } diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py index 7ee527f..b8a382b 100644 --- a/test/scripts/typedvar.py +++ b/test/scripts/typedvar.py @@ -253,4 +253,11 @@ class TypedVarTest( unittest.TestCase ): def testDinkumwareMap(self): g_map = target.module.typedVar( "g_map" ) self.assertEqual( 1, g_map._Mysize ) - + + + def testUdtSubscribe(self): + tv = pykd.typedVar( "g_virtChild" ) + self.assertEqual( 5, len(tv) ) + self.assertEqual( tv[4], tv.m_baseField ) + for field in tv: + str( field )