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 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
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 }
00197
00198 bool TMidasFile::OutOpen(const char *filename)
00199 {
00200
00201
00202
00203
00204
00205
00206
00207 if (fOutFile > 0)
00208 OutClose();
00209
00210 fOutFilename = filename;
00211
00212 printf ("Attempting normal open of file %s\n", filename);
00213
00214
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
00228 {
00229
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 }
00258
00259
00260 static int readpipe(int fd, char* buf, int length)
00261 {
00262 int count = 0;
00263 while (length > 0)
00264 {
00265 int rd = read(fd, buf, length);
00266 if (rd > 0)
00267 {
00268 buf += rd;
00269 length -= rd;
00270 count += rd;
00271 }
00272 else if (rd == 0)
00273 {
00274 return count;
00275 }
00276 else
00277 {
00278 return -1;
00279 }
00280 }
00281 return count;
00282 }
00283
00284 bool TMidasFile::Read(TMidasEvent *midasEvent)
00285 {
00286
00287
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 }
00345
00346 bool TMidasFile::Write(TMidasEvent *midasEvent)
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 }
00378
00379 void TMidasFile::Close()
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 }
00394
00395 void TMidasFile::OutClose()
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 }
00409
00410