CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_6/src/CondCore/ORA/src/STLContainerHandler.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "STLContainerHandler.h"
00003 #include "ClassUtils.h"
00004 // externals
00005 #include "RVersion.h"
00006 
00007 ora::STLContainerIteratorHandler::STLContainerIteratorHandler( const Reflex::Environ<long>& collEnv,
00008                                                                Reflex::CollFuncTable& collProxy,
00009                                                                const Reflex::Type& iteratorReturnType ):
00010   m_returnType(iteratorReturnType),
00011   m_collEnv(collEnv),
00012   m_collProxy(collProxy),
00013   m_currentElement(0){
00014 
00015   // retrieve the first element
00016   m_currentElement = m_collProxy.first_func(&m_collEnv);
00017 }
00018 
00019 ora::STLContainerIteratorHandler::~STLContainerIteratorHandler(){}
00020 
00021 void
00022 ora::STLContainerIteratorHandler::increment(){
00023   // this is required! It sets the number of memory slots (of size sizeof(Class)) to be used for the step
00024   m_collEnv.fIdx = 1;
00025   m_currentElement = m_collProxy.next_func(&m_collEnv);
00026 }
00027 
00028 void*
00029 ora::STLContainerIteratorHandler::object()
00030 {
00031   return m_currentElement;
00032 }
00033 
00034 
00035 Reflex::Type&
00036 ora::STLContainerIteratorHandler::returnType()
00037 {
00038   return m_returnType;
00039 }
00040 
00041 ora::STLContainerHandler::STLContainerHandler( const Reflex::Type& dictionary ):
00042   m_type( dictionary ),
00043   m_iteratorReturnType(),
00044   m_isAssociative( false ),
00045   m_collEnv(),
00046   m_collProxy(){
00047   m_isAssociative = ClassUtils::isTypeKeyedContainer( m_type );
00048 
00049   Reflex::Member method = m_type.MemberByName("createCollFuncTable");
00050   if(method){
00051     Reflex::CollFuncTable* collProxyPtr;
00052     method.Invoke( collProxyPtr );
00053     m_collProxy.reset( collProxyPtr );
00054   }
00055   if( !m_collProxy.get() ){
00056     throwException( "Cannot find \"createCollFuncTable\" function for type \""+m_type.Name(Reflex::SCOPED)+"\"",
00057                     "STLContainerHandler::STLContainerHandler");
00058   }
00059 
00060   // find the iterator return type as the member type_value of the containers
00061   Reflex::Type valueType = ClassUtils::containerValueType( m_type );
00062   m_iteratorReturnType = ClassUtils::resolvedType( valueType );
00063   
00064 }
00065 
00066 ora::STLContainerHandler::~STLContainerHandler(){
00067 }
00068 
00069 size_t
00070 ora::STLContainerHandler::size( const void* address ){
00071   m_collEnv.fObject = const_cast<void*>(address);
00072   return *(static_cast<size_t*>(m_collProxy->size_func(&m_collEnv)));
00073 }
00074 
00075 
00076 ora::IArrayIteratorHandler*
00077 ora::STLContainerHandler::iterate( const void* address ){
00078   if ( ! m_iteratorReturnType ) {
00079     throwException( "Missing the dictionary information for the value_type member of the container \"" +
00080                     m_type.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
00081                     "STLContainerHandler::iterate" );
00082   }
00083   m_collEnv.fObject = const_cast<void*>(address);
00084   return new STLContainerIteratorHandler( m_collEnv,*m_collProxy,m_iteratorReturnType );
00085 }
00086 
00087 
00088 void
00089 ora::STLContainerHandler::appendNewElement( void* address, void* data ){
00090 #if ROOT_VERSION_CODE < ROOT_VERSION(5,28,0)
00091   m_collEnv.fObject = address;
00092   m_collEnv.fSize = 1;
00093   m_collEnv.fStart = data;
00094   m_collProxy->feed_func(&m_collEnv);
00095 #else
00096   m_collProxy->feed_func(data,address,1);
00097 #endif
00098 }
00099 
00100 void
00101 ora::STLContainerHandler::clear( const void* address ){
00102   m_collEnv.fObject = const_cast<void*>(address);
00103   m_collProxy->clear_func(&m_collEnv);
00104 }
00105 
00106 Reflex::Type&
00107 ora::STLContainerHandler::iteratorReturnType(){
00108   return m_iteratorReturnType;
00109 }
00110 
00111 ora::SpecialSTLContainerHandler::SpecialSTLContainerHandler( const Reflex::Type& dictionary ):
00112   m_containerHandler(),
00113   m_containerOffset( 0 )
00114 {
00115   // update dictionary to include base classes members
00116   dictionary.UpdateMembers(); 
00117   for ( unsigned int i=0;i<dictionary.DataMemberSize();i++){
00118 
00119     Reflex::Member field = dictionary.DataMemberAt(i);    
00120     Reflex::Type fieldType = field.TypeOf();
00121     if ( ! fieldType ) {
00122       throwException( "The dictionary of the underlying container of \"" +
00123                       dictionary.Name(Reflex::SCOPED|Reflex::FINAL) + "\" is not available",
00124                       "SpecialSTLContainerHandler" );
00125     }
00126     if ( ClassUtils::isTypeContainer(fieldType) ) {
00127       m_containerHandler.reset( new STLContainerHandler( fieldType ) );
00128       m_containerOffset = field.Offset();
00129       break;
00130     }
00131   }
00132   if ( !m_containerHandler.get() ) {
00133     throwException( "Could not retrieve the underlying container of \"" +
00134                     dictionary.Name(Reflex::SCOPED|Reflex::FINAL) + "\" is not available",
00135                     "SpecialSTLContainerHandler" );
00136   }
00137 }
00138 
00139 
00140 ora::SpecialSTLContainerHandler::~SpecialSTLContainerHandler()
00141 {
00142 }
00143 
00144 
00145 size_t
00146 ora::SpecialSTLContainerHandler::size( const void* address )
00147 {
00148   return m_containerHandler->size( static_cast< const char* >( address ) + m_containerOffset );
00149 }
00150 
00151 
00152 ora::IArrayIteratorHandler*
00153 ora::SpecialSTLContainerHandler::iterate( const void* address )
00154 {
00155   return m_containerHandler->iterate( static_cast< const char* >( address ) + m_containerOffset );
00156 }
00157 
00158 
00159 void
00160 ora::SpecialSTLContainerHandler::appendNewElement( void* address, void* data )
00161 {
00162   m_containerHandler->appendNewElement( static_cast< char* >( address ) + m_containerOffset, data );
00163 }
00164 
00165 void 
00166 ora::SpecialSTLContainerHandler::clear( const void* address )
00167 {
00168   m_containerHandler->clear( static_cast< const char* >( address ) + m_containerOffset );
00169 }
00170 
00171 Reflex::Type&
00172 ora::SpecialSTLContainerHandler::iteratorReturnType()
00173 {
00174   return m_containerHandler->iteratorReturnType();
00175 }