00001
00002 #include "UTIL/LCSplitWriter.h"
00003
00004 #include <sys/stat.h>
00005
00006 #include <sstream>
00007 #include <iomanip>
00008 #include <iostream>
00009
00010 #ifdef SPLIT_WRITER_NDIGITS
00011 #define NDIGITS SPLIT_WRITER_NDIGITS
00012 #else
00013 #define NDIGITS 3
00014 #endif
00015
00016 #if defined(__CYGWIN__) || defined(__APPLE_CC__)
00017 #define STAT64 stat
00018 #else
00019 #define STAT64 stat64
00020 #endif
00021
00022
00023
00024 using namespace EVENT ;
00025
00026
00027 namespace UTIL{
00028
00029
00030
00031 void LCSplitWriter::open(const std::string & filename) throw (IO::IOException, std::exception ) {
00032 _count = 0 ;
00033 setBaseFilename( filename ) ;
00034 _wrt->open( getFilename() ) ;
00035 }
00036
00037 void LCSplitWriter::open(const std::string & filename, int writeMode) throw (IO::IOException, std::exception ) {
00038 throw Exception(" LCSplitWriter doesn't support NEW and APPEND mode ! "
00039 " Please remove your old file(s) and use the default mode." ) ;
00040
00041
00042
00043
00044 }
00045
00046 void LCSplitWriter::writeRunHeader(const EVENT::LCRunHeader * hdr) throw (IO::IOException, std::exception ) {
00047
00048 _wrt->flush() ;
00049 if( fileSize() > _maxBytes ) {
00050 _wrt->close() ;
00051 ++_count ;
00052 _wrt->open( getFilename() ) ;
00053 }
00054
00055 _wrt->writeRunHeader( hdr ) ;
00056 }
00057
00058 void LCSplitWriter::writeEvent(const EVENT::LCEvent * evt) throw (IO::IOException, std::exception ) {
00059
00060 _wrt->flush() ;
00061
00062 if( fileSize() > _maxBytes ) {
00063
00064
00065
00066 _wrt->close() ;
00067 ++_count ;
00068 _wrt->open( getFilename() ) ;
00069
00070
00071
00072 }
00073
00074 _wrt->writeEvent( evt ) ;
00075 }
00076
00077 void LCSplitWriter::close() throw (IO::IOException, std::exception ) {
00078 _wrt->close() ;
00079 }
00080
00081 void LCSplitWriter::flush() throw (IO::IOException, std::exception ) {
00082 _wrt->flush() ;
00083 }
00084
00085
00086
00087
00088 const std::string& LCSplitWriter::getFilename() {
00089
00090 static unsigned int lastCount = 4294967295UL ;
00091 static std::string filename ;
00092
00093 if( _count != lastCount )
00094 filename = std::string( _baseFilename + "." + getCountingString( _count ) + _extension ) ;
00095
00096 lastCount = _count ;
00097
00098 return filename ;
00099 }
00100
00101
00102
00103 long64 LCSplitWriter::file_size( const char *fname) {
00104
00105 struct STAT64 sbuf;
00106
00107 int ret = STAT64(fname, &sbuf);
00108
00109 if( ret < 0 )
00110 return -1 ;
00111
00112 return sbuf.st_size ;
00113 }
00114
00115 long64 LCSplitWriter::fileSize() {
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 return file_size( getFilename().c_str() ) ;
00127 }
00128
00129
00130 void LCSplitWriter::setBaseFilename( const std::string& filename ) {
00131
00132 unsigned dotPos = filename.find_last_of('.') ;
00133
00134 if( ( dotPos > 0 ) &&
00135 ( dotPos == filename.length() - 6 ) &&
00136 ( filename.rfind("lcio") == dotPos + 2 ) ) {
00137
00138 _baseFilename = filename.substr( 0 , filename.length() - 6 ) ;
00139 _extension = filename.substr( filename.length() - 6 , filename.length() ) ;
00140
00141 }else{
00142
00143 throw Exception(" LCSplitWriter only works with complete file names including extension, e.g. myfile.slcio" ) ;
00144
00145
00146 }
00147 }
00148
00149 std::string LCSplitWriter::getCountingString(unsigned count) {
00150
00151 std::stringstream countStream ;
00152
00153
00154 countStream << std::setw( NDIGITS ) << std::setfill('0') << count ;
00155
00156
00157
00158 return countStream.str() ;
00159 }
00160
00161
00162 }