Reader for MIDAS .mid files. More...
#include <TMidasFile.h>
Public Member Functions | |
TMidasFile () | |
default constructor | |
~TMidasFile () | |
destructor | |
bool | Open (const char *filename) |
Open input file. | |
bool | OutOpen (const char *filename) |
Open output file. | |
void | Close () |
Close input file. | |
void | OutClose () |
Close output file. | |
bool | Read (TMidasEvent *event) |
Read one event from the file. | |
bool | Write (TMidasEvent *event) |
Write one event to the output file. | |
const char * | GetFilename () const |
Get the name of this file. | |
int | GetLastErrno () const |
Get error value for the last file error. | |
const char * | GetLastError () const |
Get error text for the last file error. | |
Protected Attributes | |
std::string | fFilename |
name of the currently open file | |
std::string | fOutFilename |
name of the currently open file | |
int | fLastErrno |
errno from the last operation | |
std::string | fLastError |
error string from last errno | |
bool | fDoByteSwap |
"true" if file has to be byteswapped | |
int | fFile |
open input file descriptor | |
void * | fGzFile |
zlib compressed input file reader | |
void * | fPoFile |
popen() input file reader | |
int | fOutFile |
open output file descriptor | |
void * | fOutGzFile |
zlib compressed output file reader |
Reader for MIDAS .mid files.
Definition at line 14 of file TMidasFile.h.
TMidasFile::TMidasFile | ( | ) |
default constructor
Definition at line 20 of file TMidasFile.cxx.
References fDoByteSwap, fFile, fGzFile, fLastErrno, fOutFile, fOutGzFile, and fPoFile.
00021 { 00022 uint32_t endian = 0x12345678; 00023 00024 fFile = -1; 00025 fGzFile = NULL; 00026 fPoFile = NULL; 00027 fLastErrno = 0; 00028 00029 fOutFile = -1; 00030 fOutGzFile = NULL; 00031 00032 fDoByteSwap = *(char*)(&endian) != 0x78; 00033 }
TMidasFile::~TMidasFile | ( | ) |
destructor
Definition at line 35 of file TMidasFile.cxx.
References Close(), and OutClose().
void TMidasFile::Close | ( | ) |
Close input file.
Definition at line 379 of file TMidasFile.cxx.
References fFile, fFilename, fGzFile, and fPoFile.
Referenced by Open(), TRootanaEventLoop::ProcessMidasFile(), ProcessMidasFile(), and ~TMidasFile().
00380 { 00381 if (fPoFile) 00382 pclose((FILE*)fPoFile); 00383 fPoFile = NULL; 00384 #ifdef HAVE_ZLIB 00385 if (fGzFile) 00386 gzclose(*(gzFile*)fGzFile); 00387 fGzFile = NULL; 00388 #endif 00389 if (fFile > 0) 00390 close(fFile); 00391 fFile = -1; 00392 fFilename = ""; 00393 }
const char* TMidasFile::GetFilename | ( | ) | const [inline] |
int TMidasFile::GetLastErrno | ( | ) | const [inline] |
Get error value for the last file error.
Definition at line 30 of file TMidasFile.h.
References fLastErrno.
Referenced by ProcessMidasFile().
const char* TMidasFile::GetLastError | ( | ) | const [inline] |
Get error text for the last file error.
Definition at line 31 of file TMidasFile.h.
References fLastError.
Referenced by ProcessMidasFile().
bool TMidasFile::Open | ( | const char * | filename | ) |
Open input file.
Open a midas .mid file with given file name.
Remote files can be accessed using these special file names:
Examples:
[in] | filename | The file to open. |
Definition at line 50 of file TMidasFile.cxx.
References Close(), fFile, fFilename, fGzFile, fLastErrno, fLastError, fPoFile, hasSuffix(), and O_LARGEFILE.
Referenced by main(), TRootanaEventLoop::ProcessMidasFile(), and ProcessMidasFile().
00051 { 00052 /// Open a midas .mid file with given file name. 00053 /// 00054 /// Remote files can be accessed using these special file names: 00055 /// - pipein://command - read data produced by given command, see examples below 00056 /// - ssh://username\@hostname/path/file.mid - read remote file through an ssh pipe 00057 /// - ssh://username\@hostname/path/file.mid.gz and file.mid.bz2 - same for compressed files 00058 /// - dccp://path/file.mid (also file.mid.gz and file.mid.bz2) - read data from dcache, requires dccp in the PATH 00059 /// 00060 /// Examples: 00061 /// - ./event_dump.exe /ladd/data9/t2km11/data/run02696.mid.gz - read normal compressed file 00062 /// - ./event_dump.exe ssh://ladd09//ladd/data9/t2km11/data/run02696.mid.gz - read compressed file through ssh to ladd09 (note double "/") 00063 /// - ./event_dump.exe pipein://"cat /ladd/data9/t2km11/data/run02696.mid.gz | gzip -dc" - read data piped from a command or script (note quotes) 00064 /// - ./event_dump.exe pipein://"gzip -dc /ladd/data9/t2km11/data/run02696.mid.gz" - another way to read compressed files 00065 /// - ./event_dump.exe dccp:///pnfs/triumf.ca/data/t2km11/aug2008/run02837.mid.gz - read file directly from a dcache pool (note triple "/") 00066 /// 00067 /// \param [in] filename The file to open. 00068 /// \returns "true" for succes, "false" for error, use GetLastError() to see why 00069 00070 if (fFile > 0) 00071 Close(); 00072 00073 fFilename = filename; 00074 00075 std::string pipe; 00076 00077 // Do we need these? 00078 //signal(SIGPIPE,SIG_IGN); // crash if reading from closed pipe 00079 //signal(SIGXFSZ,SIG_IGN); // crash if reading from file >2GB without O_LARGEFILE 00080 00081 if (strncmp(filename, "ssh://", 6) == 0) 00082 { 00083 const char* name = filename + 6; 00084 const char* s = strstr(name, "/"); 00085 00086 if (s == NULL) 00087 { 00088 fLastErrno = -1; 00089 fLastError = "TMidasFile::Open: Invalid ssh:// URI. Should be: ssh://user@host/file/path/..."; 00090 return false; 00091 } 00092 00093 const char* remoteFile = s + 1; 00094 00095 std::string remoteHost; 00096 for (s=name; *s != '/'; s++) 00097 remoteHost += *s; 00098 00099 pipe = "ssh -e none -T -x -n "; 00100 pipe += remoteHost; 00101 pipe += " dd if="; 00102 pipe += remoteFile; 00103 pipe += " bs=1024k"; 00104 00105 if (hasSuffix(remoteFile,".gz")) 00106 pipe += " | gzip -dc"; 00107 else if (hasSuffix(remoteFile,".bz2")) 00108 pipe += " | bzip2 -dc"; 00109 } 00110 else if (strncmp(filename, "dccp://", 7) == 0) 00111 { 00112 const char* name = filename + 7; 00113 00114 pipe = "dccp "; 00115 pipe += name; 00116 pipe += " /dev/fd/1"; 00117 00118 if (hasSuffix(filename,".gz")) 00119 pipe += " | gzip -dc"; 00120 else if (hasSuffix(filename,".bz2")) 00121 pipe += " | bzip2 -dc"; 00122 } 00123 else if (strncmp(filename, "pipein://", 9) == 0) 00124 { 00125 pipe = filename + 9; 00126 } 00127 #if 0 // read compressed files using the zlib library 00128 else if (hasSuffix(filename, ".gz")) 00129 { 00130 pipe = "gzip -dc "; 00131 pipe += filename; 00132 } 00133 #endif 00134 else if (hasSuffix(filename, ".bz2")) 00135 { 00136 pipe = "bzip2 -dc "; 00137 pipe += filename; 00138 } 00139 else if (hasSuffix(filename, ".lz4")) 00140 { 00141 pipe = "lz4 -d "; 00142 pipe += filename; 00143 } 00144 00145 if (pipe.length() > 0) 00146 { 00147 fprintf(stderr,"TMidasFile::Open: Reading from pipe: %s\n", pipe.c_str()); 00148 00149 fPoFile = popen(pipe.c_str(), "r"); 00150 00151 if (fPoFile == NULL) 00152 { 00153 fLastErrno = errno; 00154 fLastError = strerror(errno); 00155 return false; 00156 } 00157 00158 fFile = fileno((FILE*)fPoFile); 00159 } 00160 else 00161 { 00162 #ifndef O_LARGEFILE 00163 #define O_LARGEFILE 0 00164 #endif 00165 00166 fFile = open(filename, O_RDONLY | O_LARGEFILE); 00167 00168 if (fFile <= 0) 00169 { 00170 fLastErrno = errno; 00171 fLastError = strerror(errno); 00172 return false; 00173 } 00174 00175 if (hasSuffix(filename, ".gz")) 00176 { 00177 // this is a compressed file 00178 #ifdef HAVE_ZLIB 00179 fGzFile = new gzFile; 00180 (*(gzFile*)fGzFile) = gzdopen(fFile,"rb"); 00181 if ((*(gzFile*)fGzFile) == NULL) 00182 { 00183 fLastErrno = -1; 00184 fLastError = "zlib gzdopen() error"; 00185 return false; 00186 } 00187 #else 00188 fLastErrno = -1; 00189 fLastError = "Do not know how to read compressed MIDAS files"; 00190 return false; 00191 #endif 00192 } 00193 } 00194 00195 return true; 00196 }
void TMidasFile::OutClose | ( | ) |
Close output file.
Definition at line 395 of file TMidasFile.cxx.
References fOutFile, fOutFilename, and fOutGzFile.
Referenced by OutOpen(), ProcessMidasFile(), and ~TMidasFile().
00396 { 00397 #ifdef HAVE_ZLIB 00398 if (fOutGzFile) { 00399 gzflush(*(gzFile*)fOutGzFile, Z_FULL_FLUSH); 00400 gzclose(*(gzFile*)fOutGzFile); 00401 } 00402 fOutGzFile = NULL; 00403 #endif 00404 if (fOutFile > 0) 00405 close(fOutFile); 00406 fOutFile = -1; 00407 fOutFilename = ""; 00408 }
bool TMidasFile::OutOpen | ( | const char * | filename | ) |
Open output file.
Open a midas .mid file for OUTPUT with given file name.
Remote files not yet implemented
[in] | filename | The file to open. |
Definition at line 198 of file TMidasFile.cxx.
References fLastErrno, fLastError, fOutFile, fOutFilename, fOutGzFile, hasSuffix(), O_LARGEFILE, and OutClose().
Referenced by ProcessMidasFile().
00199 { 00200 /// Open a midas .mid file for OUTPUT with given file name. 00201 /// 00202 /// Remote files not yet implemented 00203 /// 00204 /// \param [in] filename The file to open. 00205 /// \returns "true" for succes, "false" for error, use GetLastError() to see why 00206 00207 if (fOutFile > 0) 00208 OutClose(); 00209 00210 fOutFilename = filename; 00211 00212 printf ("Attempting normal open of file %s\n", filename); 00213 //fOutFile = open(filename, O_CREAT | O_WRONLY | O_LARGEFILE , S_IRUSR| S_IWUSR | S_IRGRP | S_IROTH ); 00214 //fOutFile = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644); 00215 fOutFile = open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); 00216 00217 if (fOutFile <= 0) 00218 { 00219 fLastErrno = errno; 00220 fLastError = strerror(errno); 00221 return false; 00222 } 00223 00224 printf("Opened output file %s ; return fOutFile is %i\n",filename,fOutFile); 00225 00226 if (hasSuffix(filename, ".gz")) 00227 // (hasSuffix(filename, ".dummy")) 00228 { 00229 // this is a compressed file 00230 #ifdef HAVE_ZLIB 00231 fOutGzFile = new gzFile; 00232 *(gzFile*)fOutGzFile = gzdopen(fOutFile,"wb"); 00233 if ((*(gzFile*)fOutGzFile) == NULL) 00234 { 00235 fLastErrno = -1; 00236 fLastError = "zlib gzdopen() error"; 00237 return false; 00238 } 00239 printf("Opened gz file successfully\n"); 00240 if (1) 00241 { 00242 if (gzsetparams(*(gzFile*)fOutGzFile, 1, Z_DEFAULT_STRATEGY) != Z_OK) { 00243 printf("Cannot set gzparams\n"); 00244 fLastErrno = -1; 00245 fLastError = "zlib gzsetparams() error"; 00246 return false; 00247 } 00248 printf("setparams for gz file successfully\n"); 00249 } 00250 #else 00251 fLastErrno = -1; 00252 fLastError = "Do not know how to write compressed MIDAS files"; 00253 return false; 00254 #endif 00255 } 00256 return true; 00257 }
bool TMidasFile::Read | ( | TMidasEvent * | event | ) |
Read one event from the file.
[in] | midasEvent | Pointer to an empty TMidasEvent |
Definition at line 284 of file TMidasFile.cxx.
References TMidasEvent::Clear(), fDoByteSwap, fFile, fGzFile, fLastErrno, fLastError, TMidasEvent::GetData(), TMidasEvent::GetDataSize(), TMidasEvent::GetEventHeader(), TMidasEvent::IsGoodSize(), readpipe(), TMidasEvent::SwapBytes(), and TMidasEvent::SwapBytesEventHeader().
Referenced by main(), TRootanaEventLoop::ProcessMidasFile(), and ProcessMidasFile().
00285 { 00286 /// \param [in] midasEvent Pointer to an empty TMidasEvent 00287 /// \returns "true" for success, "false" for failure, see GetLastError() to see why 00288 00289 midasEvent->Clear(); 00290 00291 int rd = 0; 00292 00293 if (fGzFile) 00294 #ifdef HAVE_ZLIB 00295 rd = gzread(*(gzFile*)fGzFile, (char*)midasEvent->GetEventHeader(), sizeof(TMidas_EVENT_HEADER)); 00296 #else 00297 assert(!"Cannot get here"); 00298 #endif 00299 else 00300 rd = readpipe(fFile, (char*)midasEvent->GetEventHeader(), sizeof(TMidas_EVENT_HEADER)); 00301 00302 if (rd == 0) 00303 { 00304 fLastErrno = 0; 00305 fLastError = "EOF"; 00306 return false; 00307 } 00308 else if (rd != sizeof(TMidas_EVENT_HEADER)) 00309 { 00310 fLastErrno = errno; 00311 fLastError = strerror(errno); 00312 return false; 00313 } 00314 00315 if (fDoByteSwap) 00316 midasEvent->SwapBytesEventHeader(); 00317 00318 if (!midasEvent->IsGoodSize()) 00319 { 00320 fLastErrno = -1; 00321 fLastError = "Invalid event size"; 00322 return false; 00323 } 00324 00325 if (fGzFile) 00326 #ifdef HAVE_ZLIB 00327 rd = gzread(*(gzFile*)fGzFile, midasEvent->GetData(), midasEvent->GetDataSize()); 00328 #else 00329 assert(!"Cannot get here"); 00330 #endif 00331 else 00332 rd = readpipe(fFile, midasEvent->GetData(), midasEvent->GetDataSize()); 00333 00334 if (rd != (int)midasEvent->GetDataSize()) 00335 { 00336 fLastErrno = errno; 00337 fLastError = strerror(errno); 00338 return false; 00339 } 00340 00341 midasEvent->SwapBytes(false); 00342 00343 return true; 00344 }
bool TMidasFile::Write | ( | TMidasEvent * | event | ) |
Write one event to the output file.
Definition at line 346 of file TMidasFile.cxx.
References fOutFile, fOutGzFile, TMidasEvent::GetData(), TMidasEvent::GetDataSize(), and TMidasEvent::GetEventHeader().
Referenced by ProcessMidasFile().
00347 { 00348 int wr = -2; 00349 00350 if (fOutGzFile) 00351 #ifdef HAVE_ZLIB 00352 wr = gzwrite(*(gzFile*)fOutGzFile, (char*)midasEvent->GetEventHeader(), sizeof(TMidas_EVENT_HEADER)); 00353 #else 00354 assert(!"Cannot get here"); 00355 #endif 00356 else 00357 wr = write(fOutFile, (char*)midasEvent->GetEventHeader(), sizeof(TMidas_EVENT_HEADER)); 00358 00359 if(wr != sizeof(TMidas_EVENT_HEADER)){ 00360 printf("TMidasFile: error on write event header, return %i, size requested %lu\n",wr,sizeof(TMidas_EVENT_HEADER)); 00361 return false; 00362 } 00363 00364 printf("Written event header to outfile , return is %i\n",wr); 00365 00366 if (fOutGzFile) 00367 #ifdef HAVE_ZLIB 00368 wr = gzwrite(*(gzFile*)fOutGzFile, (char*)midasEvent->GetData(), midasEvent->GetDataSize()); 00369 #else 00370 assert(!"Cannot get here"); 00371 #endif 00372 else 00373 wr = write(fOutFile, (char*)midasEvent->GetData(), midasEvent->GetDataSize()); 00374 printf("Written event to outfile , return is %d\n",wr); 00375 00376 return wr; 00377 }
bool TMidasFile::fDoByteSwap [protected] |
"true" if file has to be byteswapped
Definition at line 41 of file TMidasFile.h.
Referenced by Read(), and TMidasFile().
int TMidasFile::fFile [protected] |
open input file descriptor
Definition at line 43 of file TMidasFile.h.
Referenced by Close(), Open(), Read(), and TMidasFile().
std::string TMidasFile::fFilename [protected] |
name of the currently open file
Definition at line 35 of file TMidasFile.h.
Referenced by Close(), GetFilename(), and Open().
void* TMidasFile::fGzFile [protected] |
zlib compressed input file reader
Definition at line 44 of file TMidasFile.h.
Referenced by Close(), Open(), Read(), and TMidasFile().
int TMidasFile::fLastErrno [protected] |
errno from the last operation
Definition at line 38 of file TMidasFile.h.
Referenced by GetLastErrno(), Open(), OutOpen(), Read(), and TMidasFile().
std::string TMidasFile::fLastError [protected] |
error string from last errno
Definition at line 39 of file TMidasFile.h.
Referenced by GetLastError(), Open(), OutOpen(), and Read().
int TMidasFile::fOutFile [protected] |
open output file descriptor
Definition at line 46 of file TMidasFile.h.
Referenced by OutClose(), OutOpen(), TMidasFile(), and Write().
std::string TMidasFile::fOutFilename [protected] |
name of the currently open file
Definition at line 36 of file TMidasFile.h.
Referenced by OutClose(), and OutOpen().
void* TMidasFile::fOutGzFile [protected] |
zlib compressed output file reader
Definition at line 47 of file TMidasFile.h.
Referenced by OutClose(), OutOpen(), TMidasFile(), and Write().
void* TMidasFile::fPoFile [protected] |
popen() input file reader
Definition at line 45 of file TMidasFile.h.
Referenced by Close(), Open(), and TMidasFile().