We primarily focus on the introspection capability by discovering parents and variables that an instance of the type may make available
/* CoreLinux++ Copyright (C) 1999 CoreLinux Consortium The CoreLinux++ Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The CoreLinux++ Library Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // // ClfwCommon.hpp included before anything else. This is not // required but it makes things consistent. You can also // wrap it with: // // #if !defined(_CLFWCOMMON_HPP) // #include <ClfwCommon.hpp> // #endif // // if file i/o during compilation should be reduced. // Each CoreLinux header has itself wrapped as well so // multiple includes or cross-includes are harmless // #define LIBRARY_LOAD_FRAMWORK #if !defined(__CLFWCOMMON_HPP) #include <clfw/ClfwCommon.hpp> #endif #if !defined(__BOOLEAN_HPP) #include <clfw/Boolean.hpp> #endif #if !defined(__REALNUMBER_HPP) #include <clfw/RealNumber.hpp> #endif #if !defined(__SHORTINTEGER_HPP) #include <clfw/ShortInteger.hpp> #endif #if !defined(__INTEGER_HPP) #include <clfw/Integer.hpp> #endif #if !defined(__SETCOLLECTION_HPP) #include <clfw/SetCollection.hpp> #endif #if !defined(__ARRAY_HPP) #include <clfw/Array.hpp> #endif #if !defined(__UNSIGNEDSHORTINTEGER_HPP) #include <clfw/UnsignedShortInteger.hpp> #endif #if !defined(__UNSIGNEDINTEGER_HPP) #include <clfw/UnsignedInteger.hpp> #endif #if !defined(__USERTYPE_HPP) #include <UserType.hpp> #endif #if !defined(__METASPACE_HPP) #include <clfw/MetaSpace.hpp> #endif #if !defined(__ONTOLOGY_HPP) #include <clfw/Ontology.hpp> #endif #if !defined(__FRAMEWORKSTRING_HPP) #include <clfw/FrameworkString.hpp> #endif #if !defined(__METACLASS_HPP) #include <clfw/MetaClass.hpp> #endif #if !defined(__FRAMEWORKENTITY_HPP) #include <clfw/FrameworkEntity.hpp> #endif #include INCL_Library using namespace corelinux; #include <iostream> using namespace std; #include <exception> // // In module function prototypes // int main( void ); // // MetaType information dump // void dumpFundementals( void ); void dumpMetaTypeInformation( MetaTypePtr ); void dumpTypeInformation( FrameworkEntityPtr ); void testDispatch( void ); void walkOntology( MetaClassPtr , int ); void dumpOntology( void ); // // Assertion and Exception handlers // void handleAssertion( AssertionCref aAssert ); void handleException( ExceptionCref ); // // Templated function // // // Attribute Getter // template < class T > T &getValue( char *name, FrameworkEntityPtr aFE ) { T *pval( NULLPTR ); pval = (T *) (aFE->getType())->get(name,aFE); return *pval; } // // Attribute Setter // template < class T > void setValue ( char *name, T value, FrameworkEntityPtr aFE ) { (aFE->getType())->set(name,(VoidPtr)&value,aFE); } // MetaType or MetaClass parents template < class T > void dumpParents( T *aMPtr ) { cout << endl << "Meta Parent List : " << endl; if( aMPtr->getParentCount() != 0 ) { Iterator<T *> *aIterator(aMPtr->createParentIterator()); while( aIterator->isValid() ) { cout << "\tClass = " << aIterator->getElement()->getInstanceTypeName() << endl << "\tMetaType = " << aIterator->getElement()->getMetaTypeName() << endl; aIterator->setNext(); } aMPtr->destroyIterator( aIterator ); } else { ; // do nothing } } // // MetaType or MetaClass Attribute Control Blocks // template < class T > void dumpInstanceMembers( T *aMPtr ) { if( aMPtr->getInstanceMemberCount() != 0 ) { Iterator<MemberDescriptorPtr> *aIterator ( aMPtr->createMemberIterator() ); while( aIterator->isValid() ) { MemberDescriptorCptr anElement( aIterator->getElement() ); cout << "\tVar name = " << anElement->theTypeVariableName << endl; cout << "\tVar type = " << anElement->theTypeName << endl; cout << "\tVar size = " << anElement->theSizeInBytes << endl; if( anElement->theTypePointer != NULLPTR ) { cout << "\tClass type = " << anElement->theTypePointer->getInstanceTypeName() << endl; } else { cout << "\tNot a FrameworkEntity" << endl; } if( anElement->theGetter != NULLPTR ) { cout << "\tHas getter " << endl; } else { ; // do nothing } if( anElement->theSetter != NULLPTR ) { cout << "\tHas setter " << endl; } else { ; // do nothing } aIterator->setNext(); } aMPtr->destroyIterator( aIterator ); } else { ; // do nothing } } // // MetaType or MetaClass Dispatch Control Blocks // template < class T > void dumpInstanceFunctions( T *aMPtr ) { if( aMPtr->getInstanceFunctionCount() != 0 ) { Iterator<DispatchDescriptorPtr> *aIterator ( aMPtr->createMethodIterator() ); while( aIterator->isValid() ) { cout << "\tFunction name = " << aIterator->getElement()->theClassMethodName << endl; aIterator->setNext(); } aMPtr->destroyIterator( aIterator ); } else { ; // do nothing } } // // Main entry point // int main( void ) { // // Practice gracefull exception management // try { MetaSpace::initialize(); testDispatch(); //dumpFundementals(); dumpOntology(); } catch( AssertionRef aAssert ) { handleAssertion(aAssert); } catch( ExceptionRef aException ) { handleException(aException); } catch( std::exception & e ) { cerr << e.what() << endl; } catch( ... ) { cerr << "Unknown exception." << endl; } return 0; } void testDispatch( void ) { UserTypePtr aType( new UserType ); UniversalIdentifier aId; UnsignedShortIntegerPtr aValue( new UnsignedShortInteger(8) ); UniversalIdentifier::setNewUid( aId ); aType->setOid( aId ); dumpTypeInformation( aType ); dumpMetaTypeInformation( FrameworkString::getTypeDescriptor() ); // // Dispatch the method // // // Get the accumulator data member of UserType, // and get it's value // cout << "Value of Accumulator before = " << getValue<UnsignedInt> ( "Value", getValue<UnsignedIntegerPtr> ( "Accumulator", aType ) ) << endl; aType->getType()->dispatch ( aType, "addToAccumulator", (void **)aValue, (void *) 0 ); // // Get the accumulator data member of UserType, // and get it's value // cout << "Value of Accumulator after = " << getValue<UnsignedInt> ( "Value", getValue<UnsignedIntegerPtr> ( "Accumulator", aType ) ) << endl; delete aType; delete aValue; } void walkOntology( MetaClassPtr aMetaClass, int indent ) { for( int x = 0; x != indent ; ++x ) { cout << "\t"; } cout << aMetaClass->getMetaTypeName() << " (" << aMetaClass->getDomainName() << ")" << endl; Iterator<MetaClassPtr> *aIterator( aMetaClass->createIterator()); while( aIterator->isValid() == true ) { walkOntology( aIterator->getElement(), indent+1 ); aIterator->setNext(); } aMetaClass->destroyIterator( aIterator ); } void dumpOntology( void ) { // // We start by resolving the root of roots :) // cout << endl; Ontology *aOntology( MetaSpace::getOntology("corelinux") ); if( aOntology != NULLPTR ) { cout << "Dumping ontology " << aOntology->getDomainName() << endl; Iterator<MetaClassCptr> *aIterator( aOntology->createRootIterator()); while( aIterator->isValid() == true ) { walkOntology( (MetaClassPtr)aIterator->getElement(),0 ); aIterator->setNext(); } aOntology->destroyIterator( aIterator ); } else { throw NullPointerException( LOCATION ); } } void dumpFundementals( void ) { // // Because the root (and a number of support classes) are abstract, // we can't allocate them, but we can reason with them // dumpMetaTypeInformation( FrameworkEntity::getTypeDescriptor() ); dumpMetaTypeInformation( Number::getTypeDescriptor() ); dumpMetaTypeInformation( UnsignedNumber::getTypeDescriptor() ); dumpMetaTypeInformation( SignedNumber::getTypeDescriptor() ); dumpMetaTypeInformation( UserType::getTypeDescriptor() ); // // Now we sweeten the pot with showing the factory methods, // introspection, getters, setters, and destructors // // bool BooleanPtr aBoolean = new Boolean(true); dumpTypeInformation( aBoolean ); cout << "Value of aBoolean = " << getValue<bool>("Value",aBoolean) << endl; delete aBoolean; // real RealNumberPtr aReal = RealNumber::create(); setValue<Real>("Value",9.7,aReal); dumpTypeInformation( aReal ); cout << "Value of aReal = " << getValue<Real>("Value",aReal) << endl; RealNumber::destroy( aReal ); // signed Integer IntegerPtr aInteger = Integer::create(); setValue<Int>("Value",8,aInteger); dumpTypeInformation( aInteger ); cout << "Value of aInteger = " << getValue<Int>("Value",aInteger) << endl; Integer::destroy( aInteger ); // Show that new is overriden even for constructors with // values by dumping the allocation information after // destructor IntegerPtr anotherInteger = new Integer(7); cout << "Value of anotherInteger = " << anotherInteger->getValue() << endl; delete anotherInteger; dumpMetaTypeInformation( (MetaTypePtr)Integer::getTypeDescriptor() ); // signed Short ShortIntegerPtr aShort = ShortInteger::create(); setValue<Short>("Value",3,aShort); dumpTypeInformation( aShort ); cout << "Value of aShort = " << getValue<Short>("Value",aShort) << endl; ShortInteger::destroy( aShort ); // unsigned Integer UnsignedIntegerPtr aUnsigned = new UnsignedInteger; setValue<UnsignedInt>( "Value",(UnsignedInt)-1,aUnsigned ); dumpTypeInformation( aUnsigned ); cout << "Value of aUnsigned = " << getValue<UnsignedInt>("Value",aUnsigned) << endl; delete aUnsigned; // unsigned short integer UnsignedShortIntegerPtr aUnsignedShort = new UnsignedShortInteger; setValue<Word>( "Value",(Word)-2,aUnsignedShort); dumpTypeInformation( aUnsignedShort ); cout << "Value of aUnsignedShort = " << getValue<UnsignedInt>("Value",aUnsigned) << endl; delete aUnsignedShort; } // // Dump info on meta types // void dumpMetaTypeInformation( MetaTypePtr aMTPtr ) { // // Standard stuff // cout << endl << "Analyzing class [" << aMTPtr->getInstanceTypeName() << "] MetaType [" << aMTPtr->getMetaTypeName() << "]" << endl << "Namespace = " << aMTPtr->getDomainName() << endl << "Description = " << aMTPtr->getTypeDescription() << endl; cout << endl << "type class version = " << aMTPtr->getTypeVersion() << endl << "instance size = " << aMTPtr->getTypeSize() << endl << "abstract type = " << ( aMTPtr->isAbstractType() ? "true" : "false" ) << endl; if( aMTPtr->isAbstractType() == false ) { AllocatorPtr aAPtr( aMTPtr->getAllocator() ); cout << "number allocs = " << aAPtr->getAllocateCount() << endl << "number deallocs = " << aAPtr->getDeallocateCount() << endl; } else { ; // do nothing } // // Parent Dump // dumpParents<MetaType>( aMTPtr ); // // Data Member dump // dumpInstanceMembers<MetaType>( aMTPtr ); // // Dump dispatch table // dumpInstanceFunctions<MetaType>( aMTPtr ); } // // Dump info on types // void dumpTypeInformation( FrameworkEntityPtr anFEPtr ) { Char buffer[40]; anFEPtr->getOid().getAsString(buffer); cout << "Object identifier = " << buffer << endl; dumpMetaTypeInformation( anFEPtr->getType() ); } // // Peform default (just show it) // void handleAssertion( AssertionCref aAssert ) { cerr << aAssert.getFile() << ":" << aAssert.getLine() << ":" << "Assertion: "; if( aAssert.getType() == Assertion::NEVERGETHERE ) { cerr << "NEVER_GET_HERE"; } else { if( aAssert.getType() == Assertion::REQUIRE ) { cerr << "REQUIRE"; } else if( aAssert.getType() == Assertion::ENSURE ) { cerr << "ENSURE"; } else if( aAssert.getType() == Assertion::CHECK ) { cerr << "CHECK"; } else { cerr << "ASSERT"; } cerr << "( " << aAssert.getWhy() << " )"; } cerr << endl; } // // Default exception handler // void handleException( ExceptionCref aExcp ) { cerr << aExcp.getFile() << ":" << aExcp.getLine() << ":" << "Exception: " << aExcp.getWhy() << endl; } /* Common rcs information do not modify $Author: frankc $ $Revision: 1.35 $ $Date: 2001/04/25 03:27:22 $ $Locker: $ */