Go to the documentation of this file.00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "STLContainerHandler.h"
00003 #include "ClassUtils.h"
00004
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
00016 m_currentElement = m_collProxy.first_func(&m_collEnv);
00017 }
00018
00019 ora::STLContainerIteratorHandler::~STLContainerIteratorHandler(){}
00020
00021 void
00022 ora::STLContainerIteratorHandler::increment(){
00023
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
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
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 }