00001
00002
00003
00004
00005 #include <stdio.h>
00006 #include <string.h>
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <fcntl.h>
00010 #include <errno.h>
00011 #include <assert.h>
00012
00013 #ifdef HAVE_ZLIB
00014 #include <zlib.h>
00015 #endif
00016
00017 #include "TMidasFile.h"
00018 #include "TMidasEvent.h"
00019
00020 TMidasFile::TMidasFile()
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 }
00034
00035 TMidasFile::~TMidasFile()
00036 {
00037 Close();
00038 OutClose();
00039 }
00040
00041 static int hasSuffix(const char*name,const char*suffix)
00042 {
00043 const char* s = strstr(name,suffix);
00044 if (s == NULL)
00045 return 0;
00046
00047 return (s-name)+strlen(suffix) == strlen(name);
00048 }
00049
00050 bool TMidasFile::Open(const char *filename)
00051 {
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 if (fFile > 0)
00071 Close();
00072
00073 fFilename = filename;
00074
00075 std::string pipe;
00076
00077
00078
00079
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
00140 if (pipe.length() > 0)
00141 {
00142 fprintf(stderr,"TMidasFile::Open: Reading from pipe: %s\n", pipe.c_str());
00143
00144 fPoFile = popen(pipe.c_str(), "r");
00145
00146 if (fPoFile == NULL)
00147 {
00148 fLastErrno = errno;
00149 fLastError = strerror(errno);
00150 return false;
00151 }
00152
00153 fFile = fileno((FILE*)fPoFile);
00154 }
00155 else
00156 {
00157 #ifndef O_LARGEFILE
00158 #define O_LARGEFILE 0
00159 #endif
00160
00161 fFile = open(filename, O_RDONLY | O_LARGEFILE);
00162
00163 if (fFile <= 0)
00164 {
00165 fLastErrno = errno;
00166 fLastError = strerror(errno);
00167 return false;
00168 }
00169
00170 if (hasSuffix(filename, ".gz"))
00171 {
00172
00173 #ifdef HAVE_ZLIB
00174 fGzFile = new gzFile;
00175 (*(gzFile*)fGzFile) = gzdopen(fFile,"rb");
00176 if ((*(gzFile*)fGzFile) == NULL)
00177 {
00178 fLastErrno = -1;
00179 fLastError = "zlib gzdopen() error";
00180 return false;
00181 }
00182 #else
00183 fLastErrno = -1;
00184 fLastError = "Do not know how to read compressed MIDAS files";
00185 return false;
00186 #endif
00187 }
00188 }
00189
00190 return true;
00191 }
00192
00193 bool TMidasFile::OutOpen(const char *filename)
00194 {
00195
00196
00197
00198
00199
00200
00201
00202 if (fOutFile > 0)
00203 OutClose();
00204
00205 fOutFilename = filename;
00206
00207 printf ("Attempting normal open of file %s\n", filename);
00208
00209
00210 fOutFile = open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);
00211
00212 if (fOutFile <= 0)
00213 {
00214 fLastErrno = errno;
00215 fLastError = strerror(errno);
00216 return false;
00217 }
00218
00219 printf("Opened output file %s ; return fOutFile is %i\n",filename,fOutFile);
00220
00221 if (hasSuffix(filename, ".gz"))
00222
00223 {
00224
00225 #ifdef HAVE_ZLIB
00226 fOutGzFile = new gzFile;
00227 *(gzFile*)fOutGzFile = gzdopen(fOutFile,"wb");
00228 if ((*(gzFile*)fOutGzFile) == NULL)
00229 {
00230 fLastErrno = -1;
00231 fLastError = "zlib gzdopen() error";
00232 return false;
00233 }
00234 printf("Opened gz file successfully\n");
00235 if (1)
00236 {
00237 if (gzsetparams(*(gzFile*)fOutGzFile, 1, Z_DEFAULT_STRATEGY) != Z_OK) {
00238 printf("Cannot set gzparams\n");
00239 fLastErrno = -1;
00240 fLastError = "zlib gzsetparams() error";
00241 return false;
00242 }
00243 printf("setparams for gz file successfully\n");
00244 }
00245 #else
00246 fLastErrno = -1;
00247 fLastError = "Do not know how to write compressed MIDAS files";
00248 return false;
00249 #endif
00250 }
00251 return true;
00252 }
00253
00254
00255 static int readpipe(int fd, char* buf, int length)
00256 {
00257 int count = 0;
00258 while (length > 0)
00259 {
00260 int rd = read(fd, buf, length);
00261 if (rd > 0)
00262 {
00263 buf += rd;
00264 length -= rd;
00265 count += rd;
00266 }
00267 else if (rd == 0)
00268 {
00269 return count;
00270 }
00271 else
00272 {
00273 return -1;
00274 }
00275 }
00276 return count;
00277 }
00278
00279 bool TMidasFile::Read(TMidasEvent *midasEvent)
00280 {
00281
00282
00283
00284 midasEvent->Clear();
00285
00286 int rd = 0;
00287
00288 if (fGzFile)
00289 #ifdef HAVE_ZLIB
00290 rd = gzread(*(gzFile*)fGzFile, (char*)midasEvent->GetEventHeader(), sizeof(TMidas_EVENT_HEADER));
00291 #else
00292 assert(!"Cannot get here");
00293 #endif
00294 else
00295 rd = readpipe(fFile, (char*)midasEvent->GetEventHeader(), sizeof(TMidas_EVENT_HEADER));
00296
00297 if (rd == 0)
00298 {
00299 fLastErrno = 0;
00300 fLastError = "EOF";
00301 return false;
00302 }
00303 else if (rd != sizeof(TMidas_EVENT_HEADER))
00304 {
00305 fLastErrno = errno;
00306 fLastError = strerror(errno);
00307 return false;
00308 }
00309
00310 if (fDoByteSwap)
00311 midasEvent->SwapBytesEventHeader();
00312
00313 if (!midasEvent->IsGoodSize())
00314 {
00315 fLastErrno = -1;
00316 fLastError = "Invalid event size";
00317 return false;
00318 }
00319
00320 if (fGzFile)
00321 #ifdef HAVE_ZLIB
00322 rd = gzread(*(gzFile*)fGzFile, midasEvent->GetData(), midasEvent->GetDataSize());
00323 #else
00324 assert(!"Cannot get here");
00325 #endif
00326 else
00327 rd = readpipe(fFile, midasEvent->GetData(), midasEvent->GetDataSize());
00328
00329 if (rd != (int)midasEvent->GetDataSize())
00330 {
00331 fLastErrno = errno;
00332 fLastError = strerror(errno);
00333 return false;
00334 }
00335
00336 midasEvent->SwapBytes(false);
00337
00338 return true;
00339 }
00340
00341 bool TMidasFile::Write(TMidasEvent *midasEvent)
00342 {
00343 int wr = -2;
00344
00345 if (fOutGzFile)
00346 #ifdef HAVE_ZLIB
00347 wr = gzwrite(*(gzFile*)fOutGzFile, (char*)midasEvent->GetEventHeader(), sizeof(TMidas_EVENT_HEADER));
00348 #else
00349 assert(!"Cannot get here");
00350 #endif
00351 else
00352 wr = write(fOutFile, (char*)midasEvent->GetEventHeader(), sizeof(TMidas_EVENT_HEADER));
00353
00354 if(wr != sizeof(TMidas_EVENT_HEADER)){
00355 printf("TMidasFile: error on write event header, return %i, size requested %lu\n",wr,sizeof(TMidas_EVENT_HEADER));
00356 return false;
00357 }
00358
00359 printf("Written event header to outfile , return is %i\n",wr);
00360
00361 if (fOutGzFile)
00362 #ifdef HAVE_ZLIB
00363 wr = gzwrite(*(gzFile*)fOutGzFile, (char*)midasEvent->GetData(), midasEvent->GetDataSize());
00364 #else
00365 assert(!"Cannot get here");
00366 #endif
00367 else
00368 wr = write(fOutFile, (char*)midasEvent->GetData(), midasEvent->GetDataSize());
00369 printf("Written event to outfile , return is %d\n",wr);
00370
00371 return wr;
00372 }
00373
00374 void TMidasFile::Close()
00375 {
00376 if (fPoFile)
00377 pclose((FILE*)fPoFile);
00378 fPoFile = NULL;
00379 #ifdef HAVE_ZLIB
00380 if (fGzFile)
00381 gzclose(*(gzFile*)fGzFile);
00382 fGzFile = NULL;
00383 #endif
00384 if (fFile > 0)
00385 close(fFile);
00386 fFile = -1;
00387 fFilename = "";
00388 }
00389
00390 void TMidasFile::OutClose()
00391 {
00392 #ifdef HAVE_ZLIB
00393 if (fOutGzFile) {
00394 gzflush(*(gzFile*)fOutGzFile, Z_FULL_FLUSH);
00395 gzclose(*(gzFile*)fOutGzFile);
00396 }
00397 fOutGzFile = NULL;
00398 #endif
00399 if (fOutFile > 0)
00400 close(fOutFile);
00401 fOutFile = -1;
00402 fOutFilename = "";
00403 }
00404
00405