00001 #include "SIO/SIOWriter.h"
00002
00003 #include "EVENT/LCEvent.h"
00004 #include "EVENT/LCRunHeader.h"
00005 #include "EVENT/LCIO.h"
00006 #include "EVENT/LCCollection.h"
00007
00008 #include "SIO/LCSIO.h"
00009 #include "SIO/SIOEventHandler.h"
00010 #include "SIO/SIOCollectionHandler.h"
00011
00012 #include "SIO/SIORunHeaderHandler.h"
00013
00014 #include "SIO/SIORandomAccessHandler.h"
00015 #include "SIO/SIOIndexHandler.h"
00016
00017 #include "LCIOSTLTypes.h"
00018
00019 #include "SIO_streamManager.h"
00020 #include "SIO_recordManager.h"
00021 #include "SIO_blockManager.h"
00022 #include "SIO_stream.h"
00023 #include "SIO_record.h"
00024 #include "IMPL/LCIOExceptionHandler.h"
00025
00026
00027 #include "IMPL/LCTOOLS.h"
00028 #include "IMPL/LCRelationImpl.h"
00029
00030 #include <cstring>
00031
00032 using namespace EVENT ;
00033 using namespace IO ;
00034 using namespace IMPL ;
00035
00036 namespace SIO {
00037
00038 SIOWriter::SIOWriter() : _stream(0),
00039 _compressionLevel(-1),
00040 _hdrHandler(0),
00041 _runHandler(0) {
00042
00043 #ifdef DEBUG
00044 SIO_streamManager::setVerbosity( SIO_ALL ) ;
00045 SIO_recordManager::setVerbosity( SIO_ALL ) ;
00046 SIO_blockManager::setVerbosity( SIO_ALL ) ;
00047 #else
00048 SIO_streamManager::setVerbosity( SIO_SILENT ) ;
00049 SIO_recordManager::setVerbosity( SIO_SILENT ) ;
00050 SIO_blockManager::setVerbosity( SIO_SILENT ) ;
00051 #endif
00052
00053
00054
00055
00056
00057 _runHandler = new SIORunHeaderHandler( LCSIO_RUNBLOCKNAME ) ;
00058 _hdrHandler = new SIOEventHandler( LCSIO_HEADERBLOCKNAME ) ;
00059
00060
00061
00062
00063
00064 LCSIO::records() ;
00065
00066 LCIOExceptionHandler::createInstance() ;
00067
00068 }
00069
00070 SIOWriter::~SIOWriter(){
00071
00072 delete _hdrHandler ;
00073 delete _runHandler ;
00074 SIO_blockManager::clear();
00075
00076 }
00077
00078
00079
00080 void SIOWriter::open(const std::string & filename) throw(IOException, std::exception){
00081
00082 std::string sioFilename ;
00083 getSIOFileName( filename, sioFilename ) ;
00084
00085
00086
00087 FILE* f = FOPEN( sioFilename.c_str() , "r") ;
00088 if( f != 0 ){
00089 FCLOSE(f) ;
00090 throw IOException( std::string( "[SIOWriter::open()] File already exists: "
00091 + sioFilename
00092 + " \n open it in append or new mode !\n"
00093 )) ;
00094 }
00095
00096 return open( filename, EVENT::LCIO::WRITE_NEW ) ;
00097 }
00098
00099 void SIOWriter::getSIOFileName(const std::string& filename,
00100 std::string& sioFilename ) {
00101
00102
00103 if( filename.rfind(LCSIO::FILE_EXTENSION) == std::string::npos ||
00104 !( filename.rfind(LCSIO::FILE_EXTENSION)
00105 + strlen( LCSIO::FILE_EXTENSION ) == filename.length() ) ) {
00106
00107
00108
00109
00110 sioFilename = filename + LCSIO::FILE_EXTENSION ;
00111 }
00112 else
00113 sioFilename = filename ;
00114 }
00115
00116 void SIOWriter::open(const std::string& filename, int writeMode) throw(IOException, std::exception) {
00117
00118
00119
00120 std::string sioFilename ;
00121 getSIOFileName( filename, sioFilename ) ;
00122
00123
00124
00125 std::string stream_name = LCSIO::getValidSIOName(sioFilename) ;
00126 _stream = SIO_streamManager::add( stream_name.c_str() , 32*SIO_KBYTE*SIO_KBYTE ) ;
00127
00128 if( _stream == 0 )
00129 throw IOException( std::string( "[SIOWriter::open()] Bad or duplicate stream name: "
00130 + stream_name )) ;
00131
00132
00133 _stream->setCompressionLevel( _compressionLevel ) ;
00134
00135
00136 unsigned int status = 0 ;
00137
00138
00139 switch( writeMode )
00140 {
00141 case EVENT::LCIO::WRITE_NEW :
00142
00143 status = _stream->open( sioFilename.c_str() , SIO_MODE_WRITE_NEW ) ;
00144
00145 break ;
00146
00147 case EVENT::LCIO::WRITE_APPEND :
00148
00149
00150 status = _stream->open( sioFilename.c_str() , SIO_MODE_READ ) ;
00151
00152 if( status != SIO_STREAM_SUCCESS )
00153 throw IOException( std::string( "[SIOWriter::open()] Can't open stream for reading TOC: "
00154 + sioFilename ) ) ;
00155
00156 bool hasRandomAccess = _raMgr.initAppend( _stream ) ;
00157
00158 _stream->close() ;
00159
00160 if( hasRandomAccess ) {
00161 status = _stream->open( sioFilename.c_str() , SIO_MODE_READ_WRITE ) ;
00162
00163 LCSIO::seekStream( _stream, -LCSIO_RANDOMACCESS_SIZE ) ;
00164 } else {
00165
00166
00167 status = _stream->open( sioFilename.c_str() , SIO_MODE_WRITE_APPEND ) ;
00168
00169 }
00170
00171 break ;
00172 }
00173
00174 if( !(status &1) )
00175 throw IOException( std::string( "[SIOWriter::open()] Couldn't open file: "
00176 + sioFilename ) ) ;
00177
00178
00179 LCSIO::records().setCompress( _compressionLevel != 0 ) ;
00180 }
00181
00182 void SIOWriter::setCompressionLevel(int level) {
00183 _compressionLevel = level ;
00184 }
00185
00186
00187 void SIOWriter::writeRunHeader(const EVENT::LCRunHeader * hdr) throw(IOException, std::exception) {
00188
00189
00190 SIO_record* runRecord = LCSIO::records()[ SIORecords::Run ] ;
00191 runRecord->connect( _runHandler );
00192
00193 _runHandler->setRunHeader( hdr ) ;
00194
00195 if( _stream->getState()== SIO_STATE_OPEN ){
00196
00197 LCSIO::records().setCompress( _compressionLevel != 0 ) ;
00198
00199
00200 unsigned int status = _stream->write( LCSIO_RUNRECORDNAME ) ;
00201
00202
00203
00204 _raMgr.add( RunEvent( hdr->getRunNumber(), -1 ) , _stream->lastRecordStart() ) ;
00205
00206
00207
00208
00209 if( !(status & 1) )
00210 throw IOException( std::string( "[SIOWriter::writeRunHeader] couldn't write run header to stream: "
00211 + *_stream->getName() ) ) ;
00212 } else {
00213
00214 throw IOException( std::string( "[SIOWriter::writeRunHeader] stream not opened: "
00215 + *_stream->getName() ) ) ;
00216
00217 }
00218 }
00219
00220
00221
00222
00223
00224
00225 void SIOWriter::setUpHandlers(const LCEvent * evt){
00226
00227
00228
00229
00230 SIO_record* hdrRecord = LCSIO::records()[ SIORecords::Header ] ;
00231 hdrRecord->connect( _hdrHandler ) ;
00232
00233
00234 SIO_record* evtRecord = LCSIO::records()[ SIORecords::Event ] ;
00235 evtRecord->disconnectAll() ;
00236
00237 const std::vector<std::string>* strVec = evt->getCollectionNames() ;
00238
00239 for( std::vector<std::string>::const_iterator name = strVec->begin() ; name != strVec->end() ; name++){
00240
00241
00242 SIOCollectionHandler* ch = dynamic_cast<SIOCollectionHandler*>
00243 ( SIO_blockManager::get( name->c_str() ) ) ;
00244
00245 LCCollection* col = evt->getCollection( *name ) ;
00246
00247 if(! col->isTransient() ){
00248
00249 try{
00250
00251 if( ch == 0 ) {
00252 ch = new SIOCollectionHandler( *name, col->getTypeName()) ;
00253 }
00254
00255 evtRecord->connect( ch ) ;
00256
00257 ch->setCollection( col ) ;
00258
00259 }
00260 catch(Exception& ex){
00261 delete ch ;
00262 ch = 0 ;
00263 }
00264
00265 }
00266 }
00267 }
00268
00269 void SIOWriter::writeEvent(const LCEvent* evt) throw(IOException, std::exception) {
00270
00271
00272
00273
00274 try{ setUpHandlers( evt) ;
00275
00276 }catch(...){
00277 throw IOException( "[SIOWriter::writeEvent] could not set up handlers " ) ;
00278 }
00279
00280 LCSIO::records().setCompress( _compressionLevel != 0 ) ;
00281
00282 if( _stream->getState()== SIO_STATE_OPEN ){
00283
00284
00285 _hdrHandler->setEvent( evt ) ;
00286
00287 unsigned int status = 0 ;
00288
00289
00290
00291 status = _stream->write( LCSIO_HEADERRECORDNAME ) ;
00292
00293 _raMgr.add( RunEvent( evt->getRunNumber(), evt->getEventNumber() ) , _stream->lastRecordStart() ) ;
00294
00295
00296
00297
00298
00299 if( ! (status & 1) )
00300 throw IOException( std::string("[SIOWriter::writeEvent] couldn't write event header to stream: "
00301 + *_stream->getName() )) ;
00302
00303
00304
00305 status = _stream->write( LCSIO_EVENTRECORDNAME ) ;
00306
00307 if( ! (status & 1) )
00308 throw IOException( std::string("[SIOWriter::writeEvent] couldn't write event header to stream: "
00309 + *_stream->getName() )) ;
00310 }
00311 else
00312
00313 throw IOException( std::string("[SIOWriter::writeEvent] stream not opened : "
00314 + *_stream->getName() )) ;
00315
00316 }
00317
00318
00319 void SIOWriter::close() throw (IOException, std::exception) {
00320
00321
00322 _raMgr.writeRandomAccessRecords( _stream ) ;
00323
00324
00325 const std::string* streamName = _stream->getName() ;
00326
00327 int status = SIO_streamManager::remove( _stream ) ;
00328
00329 if(! (status &1) )
00330 throw IOException( std::string("[SIOWriter::close] couldn't close stream : "
00331 + *streamName )) ;
00332
00333 }
00334
00335 void SIOWriter::flush() throw (IOException, std::exception) {
00336
00337 const std::string* streamName = _stream->getName() ;
00338
00339 int status = _stream->flush() ;
00340
00341 if(! (status &1) )
00342 throw IOException( std::string("[SIOWriter::flush] couldn't flush stream : "
00343 + *streamName )) ;
00344
00345 }
00346
00347 }
00348