00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "TChirpFile.h"
00023 #include "TError.h"
00024 #include "TSystem.h"
00025 #include "TROOT.h"
00026
00027 #include <errno.h>
00028 #include <sys/stat.h>
00029 #include <unistd.h>
00030
00031 #include "chirp_client.h"
00032
00033
00034 static const char* const CHIRP_PREFIX = "chirp:";
00035 static const size_t CHIRP_PREFIX_LEN = 6;
00036
00037
00038 ClassImp(TChirpFile)
00039
00040
00041 TChirpFile::TChirpFile(const char *path, Option_t *option,
00042 const char *ftitle, Int_t compress):
00043 TFile(path, "NET", ftitle, compress)
00044 {
00045
00046
00047 chirp_client = 0;
00048
00049 fOption = option;
00050 fOption.ToUpper();
00051
00052 if (fOption == "NEW")
00053 fOption = "CREATE";
00054
00055 Bool_t create = (fOption == "CREATE") ? kTRUE : kFALSE;
00056 Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE;
00057 Bool_t update = (fOption == "UPDATE") ? kTRUE : kFALSE;
00058 Bool_t read = (fOption == "READ") ? kTRUE : kFALSE;
00059 if (!create && !recreate && !update && !read) {
00060 read = kTRUE;
00061 fOption = "READ";
00062 }
00063
00064 char const *path_part;
00065 const char *fname;
00066
00067 if (OpenChirpClient(path, &path_part)) {
00068 SysError("TChirpFile", "chirp client for %s can not be opened", path);
00069 goto zombie;
00070 }
00071
00072 fname = path_part;
00073
00074 fRealName = fname;
00075
00076 if (create || update || recreate) {
00077 Int_t mode = O_RDWR | O_CREAT;
00078 if (recreate) mode |= O_TRUNC;
00079
00080 #ifndef WIN32
00081 fD = SysOpen(fname, mode, 0644);
00082 #else
00083 fD = SysOpen(fname, mode | O_BINARY, S_IREAD | S_IWRITE);
00084 #endif
00085 if (fD == -1) {
00086 SysError("TChirpFile", "file %s can not be opened", fname);
00087 goto zombie;
00088 }
00089 fWritable = kTRUE;
00090 } else {
00091 #ifndef WIN32
00092 fD = SysOpen(fname, O_RDONLY, 0644);
00093 #else
00094 fD = SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
00095 #endif
00096 if (fD == -1) {
00097 SysError("TFile", "file %s can not be opened for reading", fname);
00098 goto zombie;
00099 }
00100 fWritable = kFALSE;
00101 }
00102
00103 Init(create || recreate);
00104
00105 return;
00106
00107 zombie:
00108
00109 MakeZombie();
00110 gDirectory = gROOT;
00111 }
00112
00113
00114 TChirpFile::~TChirpFile()
00115 {
00116
00117
00118 Close();
00119 CloseChirpClient();
00120 }
00121
00122
00123 Bool_t TChirpFile::ReadBuffer(char *buf, Int_t len)
00124 {
00125
00126
00127
00128 Int_t st;
00129 if ((st = ReadBufferViaCache(buf, len))) {
00130 if (st == 2)
00131 return kTRUE;
00132 return kFALSE;
00133 }
00134
00135 return TFile::ReadBuffer(buf, len);
00136 }
00137
00138
00139 Bool_t TChirpFile::ReadBuffer(char *buf, Long64_t pos, Int_t len)
00140 {
00141
00142
00143
00144 SetOffset(pos);
00145 Int_t st;
00146 if ((st = ReadBufferViaCache(buf, len))) {
00147 if (st == 2)
00148 return kTRUE;
00149 return kFALSE;
00150 }
00151
00152 return TFile::ReadBuffer(buf, pos, len);
00153 }
00154
00155
00156 Bool_t TChirpFile::WriteBuffer(const char *buf, Int_t len)
00157 {
00158
00159
00160
00161 if (!IsOpen() || !fWritable) return kTRUE;
00162
00163 Int_t st;
00164 if ((st = WriteBufferViaCache(buf, len))) {
00165 if (st == 2)
00166 return kTRUE;
00167 return kFALSE;
00168 }
00169
00170 return TFile::WriteBuffer(buf, len);
00171 }
00172
00173
00174 Int_t TChirpFile::OpenChirpClient(char const *URL, char const **path_part)
00175 {
00176
00177
00178
00179
00180 *path_part = 0;
00181
00182 CloseChirpClient();
00183
00184 chirp_client = chirp_client_connect_url(URL, path_part);
00185
00186 if (!chirp_client) {
00187 gSystem->SetErrorStr(strerror(errno));
00188 return -1;
00189 }
00190 return 0;
00191 }
00192
00193
00194 Int_t TChirpFile::CloseChirpClient()
00195 {
00196 if (chirp_client) {
00197 struct chirp_client *c = chirp_client;
00198 chirp_client = 0;
00199
00200 chirp_client_disconnect(c);
00201 }
00202
00203 return 0;
00204 }
00205
00206
00207 Int_t TChirpFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
00208 {
00209 char open_flags[8];
00210 char *f = open_flags;
00211
00212 if ((flags & O_WRONLY) || (flags & O_RDWR)) *(f++) = 'w';
00213 if ((flags & O_RDONLY) || (flags & O_RDWR) || !flags) *(f++) = 'r';
00214 if (flags & O_APPEND) *(f++) = 'a';
00215 if (flags & O_CREAT) *(f++) = 'c';
00216 if (flags & O_TRUNC) *(f++) = 't';
00217 if (flags & O_EXCL) *(f++) = 'x';
00218
00219 *f = '\0';
00220
00221 Int_t rc = chirp_client_open(chirp_client, pathname, open_flags, (Int_t) mode);
00222
00223 if (rc < 0) {
00224 gSystem->SetErrorStr(strerror(errno));
00225 }
00226
00227 return rc;
00228 }
00229
00230
00231 Int_t TChirpFile::SysClose(Int_t fd)
00232 {
00233 Int_t rc = chirp_client_close(chirp_client,fd);
00234
00235 if (rc < 0) {
00236 gSystem->SetErrorStr(strerror(errno));
00237 }
00238
00239 return rc;
00240 }
00241
00242
00243 Int_t TChirpFile::SysRead(Int_t fd, void *buf, Int_t len)
00244 {
00245 Int_t rc = chirp_client_read(chirp_client, fd, buf, len);
00246
00247 if (rc < 0) {
00248 gSystem->SetErrorStr(strerror(errno));
00249 }
00250
00251 return rc;
00252 }
00253
00254
00255 Int_t TChirpFile::SysWrite(Int_t fd, const void *buf, Int_t len)
00256 {
00257 Int_t rc = chirp_client_write(chirp_client, fd, (char *)buf, len);
00258
00259 if (rc < 0) {
00260 gSystem->SetErrorStr(strerror(errno));
00261 }
00262
00263 return rc;
00264 }
00265
00266
00267 Long64_t TChirpFile::SysSeek(Int_t fd, Long64_t offset, Int_t whence)
00268 {
00269 Long64_t rc = chirp_client_lseek(chirp_client, fd, offset, whence);
00270
00271 if (rc < 0)
00272 gSystem->SetErrorStr(strerror(errno));
00273
00274 return rc;
00275 }
00276
00277
00278 Int_t TChirpFile::SysSync(Int_t fd)
00279 {
00280 Int_t rc = chirp_client_fsync(chirp_client, fd);
00281
00282 if (rc < 0) {
00283 gSystem->SetErrorStr(strerror(errno));
00284 }
00285
00286 return rc;
00287 }
00288
00289
00290 Int_t TChirpFile::SysStat(Int_t fd, Long_t *id, Long64_t *size,
00291 Long_t *flags, Long_t *modtime)
00292 {
00293
00294
00295 *id = ::Hash(fRealName);
00296
00297 Long64_t offset = SysSeek(fd, 0, SEEK_CUR);
00298 *size = SysSeek(fd, 0, SEEK_END);
00299 SysSeek(fd, offset, SEEK_SET);
00300
00301 *flags = 0;
00302 *modtime = 0;
00303 return 0;
00304 }
00305
00306
00307 void TChirpFile::ResetErrno() const
00308 {
00309 TSystem::ResetErrno();
00310 }