00001 #include <cstring>
00002
00003 #include "Reflex/Member.h"
00004 #include "Reflex/Object.h"
00005
00006 #include "CondCore/DBCommon/interface/Exception.h"
00007 #include "PrimitivesContainerStreamer.h"
00008
00009 cond::BlobWriter::BlobWriter( const ROOT::Reflex::Type& type ):
00010 m_type( type ),
00011 m_blob()
00012 {}
00013
00014 cond::BlobWriter::~BlobWriter()
00015 {}
00016
00017 const coral::Blob&
00018 cond::BlobWriter::write( const void* addressOfInputData )
00019 {
00020
00021 ROOT::Reflex::Object theContainer( m_type, const_cast<void*>( addressOfInputData ) );
00022
00023 ROOT::Reflex::Member sizeMethod = m_type.MemberByName( "size" );
00024 if ( ! sizeMethod )
00025 throw cond::Exception( "BlobWriter::write No size method is defined for the container" );
00026 ROOT::Reflex::Object ret = sizeMethod.Invoke(theContainer);
00027 if( !ret.TypeOf() || !ret.Address() )
00028 throw cond::Exception( "BlobWriter::write Could not invoke the size method on the container" );
00029 size_t containerSize = *(static_cast<size_t*>(ret.Address()));
00030 if(containerSize==0){
00031
00032 return m_blob;
00033 }
00034
00035
00036
00037
00038 size_t elementSize=m_type.TemplateArgumentAt(0).SizeOf();
00039
00040 ROOT::Reflex::Member beginMethod = m_type.MemberByName( "begin" );
00041 if ( ! beginMethod )
00042 throw cond::Exception( "BlobWriter::write No begin method is defined for the container" );
00043 ROOT::Reflex::Type iteratorType = beginMethod.TypeOf().ReturnType();
00044 ROOT::Reflex::Member dereferenceMethod = iteratorType.MemberByName( "operator*" );
00045 if ( ! dereferenceMethod )
00046 throw cond::Exception( "BlobWriter::write Could not retrieve the dereference method of the container's iterator" );
00047
00048
00049 ROOT::Reflex::Object iteratorObject = beginMethod.Invoke( ROOT::Reflex::Object( m_type, const_cast< void * > ( addressOfInputData ) ) );
00050
00051 void* elementAddress = dereferenceMethod.Invoke( iteratorObject ).Address();
00052 m_blob.resize( containerSize * elementSize );
00053 void* startingAddress = m_blob.startingAddress();
00054
00055
00056 ::memcpy( startingAddress, elementAddress, containerSize*elementSize );
00057 iteratorObject.Destruct();
00058
00059 return m_blob;
00060 }
00061
00062
00063 cond::BlobReader::BlobReader( const ROOT::Reflex::Type& type ):
00064 m_type( type )
00065 {}
00066
00067
00068 cond::BlobReader::~BlobReader()
00069 {}
00070
00071
00072 void
00073 cond::BlobReader::read( const coral::Blob& blobData,
00074 void* containerAddress ) const
00075 {
00076
00077 const void * srcstartingAddress=blobData.startingAddress();
00078
00079
00080 long bsize=blobData.size();
00081 if(bsize==0){
00082
00083 return;
00084 }
00085
00086 ROOT::Reflex::Member clearMethod = m_type.MemberByName( "clear" );
00087 if ( ! clearMethod )
00088 throw cond::Exception( "BlobReader::read Could not retrieve the clear method of the container" );
00089 ROOT::Reflex::Object containerObject( m_type, containerAddress );
00090
00091 clearMethod.Invoke( containerObject );
00092
00093 ROOT::Reflex::Member resizeMethod = m_type.MemberByName( "resize",ROOT::Reflex::Type::ByName("void (size_t)") );
00094 if ( ! resizeMethod )
00095 throw cond::Exception( "BlobReader::read Could not retrieve the resize method of the container" );
00096
00097
00098
00099 size_t elementSize=m_type.TemplateArgumentAt(0).SizeOf();
00100
00101 std::vector<void *> v(1);
00102 size_t containerSize = bsize / elementSize;
00103
00104
00105
00106
00107
00108
00109 v[0] = (void*)(&containerSize);
00110
00111
00112
00113
00114 resizeMethod.Invoke( containerObject,v );
00115
00116 ROOT::Reflex::Member beginMethod = m_type.MemberByName( "begin" );
00117 if ( ! beginMethod )
00118 throw cond::Exception( "BlobReader::read No begin method is defined for the container" );
00119 ROOT::Reflex::Object iteratorObject = beginMethod.Invoke( ROOT::Reflex::Object( m_type, const_cast< void * > ( containerAddress ) ) );
00120 ROOT::Reflex::Type iteratorType = beginMethod.TypeOf().ReturnType();
00121
00122 ROOT::Reflex::Member dereferenceMethod = iteratorType.MemberByName( "operator*" );
00123 if ( ! dereferenceMethod )
00124 throw cond::Exception( "BlobReader::read Could not retrieve the dereference method of the container's iterator" );
00125 void* elementAddress = dereferenceMethod.Invoke( iteratorObject ).Address();
00126 ::memcpy( elementAddress, srcstartingAddress, (size_t)bsize);
00127
00128 iteratorObject.Destruct();
00129 }