Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Examples  

examp1.cpp

This example is to show use of the MetaType object

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:  $
*/



This is the CoreLinux++ Framework reference manual
Provided by The CoreLinux Consortium