Go to the documentation of this file.00001 #ifndef         __NITRO_MEMORY_HANDLER_H__
00002 #define         __NITRO_MEMORY_HANDLER_H__
00003 
00004 #include        <vector>
00005 
00006 #include        <utilities/exception.h>
00007 #include        <utilities/pointer_interface.h>
00008 
00009 #if !defined( WIN32_PLATFORM ) && !defined( NIX_PLATFORM ) && !defined( MINGW_PLATFORM ) && !defined( CYGWIN_PLATFORM )
00010         #define WIN32_PLATFORM
00011 #endif
00012 
00013 #ifdef MEMORY_HANDLER
00014         #define DLL_ENTITY __declspec( dllexport )
00015 #else
00016         #define DLL_ENTITY __declspec( dllimport )
00017 
00018         #ifdef WIN32_PLATFORM
00019                 #pragma comment( lib , "memory_handler.lib" )
00020         #endif
00021         
00022         #ifdef NIX_PLATFORM
00023                 #define DLL_ENTITY
00024         #endif
00025 #endif
00026 
00027 namespace       nitro{
00028 
00039         class DLL_ENTITY MemoryDescription{
00040         public:
00041         
00064                 MemoryDescription( void * theMemoryBlock , const std::size_t theMemoryBlockSize , const std::string & theBlockDescription );
00065                 
00076                 void                                                                                                    OnAssigned( void );
00077                 
00088                 void                                                                                                    OnCopied( void );
00089                 
00108                 bool                                                                                                    AddressIn( void * Address );
00109 
00128                 void                                                                                                    RegisterPointer( PointerInterface * Ptr );
00129 
00144                 void                                                                                                    ReleaseNestedPointers( void );
00145 
00146         private:
00147         
00158                 void *                                                                                                  MemoryBlock;
00159                 
00170                 std::size_t                                                                                     MemoryBlockSize;
00171                 
00182                 std::string                                                                                             BlockDescription;
00183                 
00194                 std::size_t                                                                                             ReferenceCounter;
00195 
00206                 std::vector< PointerInterface * >                                               NestedPointers;
00207         };
00208 
00219         class DLL_ENTITY MemoryHandler{
00220         public:
00221         
00252                 template< class stored_type >stored_type *                      Allocate( PointerInterface * Ptr , const std::size_t ItemCount , const std::string & BlockDescription = "" );
00253                 
00272                 template< class stored_type >void                                       Deallocate( stored_type * DeallocatingData );
00273                 
00296                 template< class stored_type >void                                       Copy( stored_type * & Ptr1 , stored_type * & Ptr2 );
00297                 
00298         private:
00299         
00310                 std::vector< MemoryDescription >                                                MemoryDesriptions;
00311         };
00312         
00313         template< class stored_type >void                                       MemoryHandler::Copy( stored_type * & Ptr1 , stored_type * & Ptr2 )
00314         {
00315                 try
00316                 {
00317                         for( std::size_t i( 0 ) ; i < MemoryDesriptions.size() ; i++ )
00318                         {
00319                                 if( MemoryDesriptions[ i ].AddressIn( Ptr1 ) )
00320                                 {
00321                                         MemoryDesriptions[ i ].OnAssigned();
00322                                         break;
00323                                 }
00324                         }
00325                         
00326                         for( std::size_t i( 0 ) ; i < MemoryDesriptions.size() ; i++ )
00327                         {
00328                                 if( MemoryDesriptions[ i ].AddressIn( Ptr2 ) )
00329                                 {
00330                                         MemoryDesriptions[ i ].OnCopied();
00331                                         break;
00332                                 }
00333                         }
00334                         
00335                         Ptr1 = Ptr2;
00336                 }
00337                 catch( nitro::exception e )
00338                 {
00339                         throw( nitro::exception( std::string( "MemoryHandler::Copy( stored_type & * Ptr1 , stored_type & * Ptr2 )::" ) + e.what() , e.code() ) );
00340                 }
00341                 catch( ... )
00342                 {
00343                         throw( nitro::exception( std::string( "MemoryHandler::Copy( stored_type & * Ptr1 , stored_type & * Ptr2 )::An error occured" ) , 0 ) );
00344                 }
00345         }
00346 
00347         template< class stored_type >stored_type *                      MemoryHandler::Allocate( PointerInterface * PtrI , const std::size_t ItemCount , const std::string & BlockDescription  )
00348         {
00349                 try
00350                 {
00351                         stored_type             * Ptr( new stored_type[ ItemCount ] );
00352                 
00353                         for( std::size_t i( 0 ) ; i < MemoryDesriptions.size() ; i++ )
00354                         {
00355                                 if( MemoryDesriptions[ i ].AddressIn( PtrI ) )
00356                                 {
00357                                         MemoryDesriptions[ i ].RegisterPointer( PtrI );
00358                                 }
00359                         }
00360 
00361                         MemoryDesriptions.push_back( MemoryDescription( ( void * )Ptr , sizeof( stored_type ) * ItemCount , BlockDescription ) );
00362 
00363                         return( Ptr );
00364                 }
00365                 catch( nitro::exception e )
00366                 {
00367                         throw( nitro::exception( std::string( "MemoryHandler::Allocate( PointerInterface * PtrI , const std::size_t ItemCount , const std::string & BlockDescription /* = "" */ )::" ) + e.what() , e.code() ) );
00368                 }
00369                 catch( ... )
00370                 {
00371                         throw( nitro::exception( std::string( "MemoryHandler::Allocate( PointerInterface * PtrI , const std::size_t ItemCount , const std::string & BlockDescription /* = "" */ )::An error occured" ) , 0 ) );
00372                 }
00373         }
00374                 
00375         template< class stored_type >void                                       MemoryHandler::Deallocate( stored_type * DeallocatingData )
00376         {
00377                 try
00378                 {
00379                         for( std::size_t i( 0 ) ; i < MemoryDesriptions.size() ; i++ )
00380                         {
00381                                 if( MemoryDesriptions[ i ].AddressIn( DeallocatingData ) )
00382                                 {
00383                                         MemoryDesriptions[ i ].ReleaseNestedPointers();
00384 
00385                                         delete [] DeallocatingData;
00386                                         
00387                                         MemoryDesriptions.erase( MemoryDesriptions.begin() + i );
00388                                 }
00389                         }
00390                 }
00391                 catch( nitro::exception e )
00392                 {
00393                         throw( nitro::exception( std::string( "MemoryHandler::Deallocate( stored_type * DeallocatingData )::" ) + e.what() , e.code() ) );
00394                 }
00395                 catch( ... )
00396                 {
00397                         throw( nitro::exception( std::string( "MemoryHandler::Deallocate( stored_type * DeallocatingData )::An error occured" ) , 0 ) );
00398                 }
00399         }
00400         
00401         #ifndef MEMORY_HANDLER
00402                 extern MemoryHandler            StdMemoryHandler;
00403         #endif
00404 
00405 }
00406 
00407 #endif