#include <Utilities/XrdAdaptor/src/XrdFile.h>
Public Member Functions | |
virtual void | abort (void) |
virtual void | close (void) |
virtual void | create (const std::string &name, bool exclusive=false, int perms=0666) |
virtual void | create (const char *name, bool exclusive=false, int perms=0666) |
virtual void | open (const std::string &name, int flags=IOFlags::OpenRead, int perms=0666) |
virtual void | open (const char *name, int flags=IOFlags::OpenRead, int perms=0666) |
virtual IOOffset | position (IOOffset offset, Relative whence=SET) |
virtual bool | prefetch (const IOPosBuffer *what, IOSize n) |
virtual IOSize | read (void *into, IOSize n, IOOffset pos) |
virtual IOSize | read (void *into, IOSize n) |
Read into into at most n number of bytes. | |
virtual IOSize | readv (IOPosBuffer *into, IOSize n) |
virtual IOSize | readv (IOBuffer *into, IOSize n) |
Read from the input stream into multiple scattered buffers. | |
virtual void | resize (IOOffset size) |
virtual IOSize | write (const void *from, IOSize n, IOOffset pos) |
virtual IOSize | write (const void *from, IOSize n) |
Write n bytes of data starting at address from. | |
XrdFile (const std::string &name, int flags=IOFlags::OpenRead, int perms=0666) | |
XrdFile (const char *name, int flags=IOFlags::OpenRead, int perms=0666) | |
XrdFile (IOFD fd) | |
XrdFile (void) | |
~XrdFile (void) | |
Private Attributes | |
XrdClient * | m_client |
bool | m_close |
std::string | m_name |
IOOffset | m_offset |
XrdClientStatInfo | m_stat |
Definition at line 9 of file XrdFile.h.
XrdFile::XrdFile | ( | void | ) |
XrdFile::XrdFile | ( | IOFD | fd | ) |
XrdFile::~XrdFile | ( | void | ) |
Definition at line 27 of file XrdFile.cc.
References m_close, and m_name.
00028 { 00029 if (m_close) 00030 edm::LogError("XrdFileError") 00031 << "Destructor called on XROOTD file '" << m_name 00032 << "' but the file is still open"; 00033 }
Reimplemented from Storage.
Definition at line 131 of file XrdFile.cc.
References m_client, m_close, m_name, m_offset, and m_stat.
Referenced by open().
00132 { 00133 if (! m_client) 00134 { 00135 edm::LogError("XrdFileError") 00136 << "XrdFile::close(name='" << m_name 00137 << "') called but the file is not open"; 00138 m_close = false; 00139 return; 00140 } 00141 00142 if (! m_client->Close()) 00143 edm::LogWarning("XrdFileWarning") 00144 << "XrdFile::close(name='" << m_name 00145 << "') failed with error '" << m_client->LastServerError()->errmsg 00146 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00147 delete m_client; 00148 m_client = 0; 00149 00150 m_close = false; 00151 m_offset = 0; 00152 memset(&m_stat, 0, sizeof (m_stat)); 00153 edm::LogInfo("XrdFileInfo") << "Closed " << m_name; 00154 }
void XrdFile::create | ( | const std::string & | name, | |
bool | exclusive = false , |
|||
int | perms = 0666 | |||
) | [virtual] |
Definition at line 48 of file XrdFile.cc.
References open(), IOFlags::OpenCreate, IOFlags::OpenExclusive, IOFlags::OpenTruncate, and IOFlags::OpenWrite.
00051 { 00052 open (name.c_str (), 00053 (IOFlags::OpenCreate | IOFlags::OpenWrite | IOFlags::OpenTruncate 00054 | (exclusive ? IOFlags::OpenExclusive : 0)), 00055 perms); 00056 }
Definition at line 37 of file XrdFile.cc.
References open(), IOFlags::OpenCreate, IOFlags::OpenExclusive, IOFlags::OpenTruncate, and IOFlags::OpenWrite.
00040 { 00041 open (name, 00042 (IOFlags::OpenCreate | IOFlags::OpenWrite | IOFlags::OpenTruncate 00043 | (exclusive ? IOFlags::OpenExclusive : 0)), 00044 perms); 00045 }
Definition at line 65 of file XrdFile.cc.
References abort(), close(), Exception, m_client, m_close, m_name, m_offset, m_stat, IOFlags::OpenAppend, IOFlags::OpenCreate, IOFlags::OpenExclusive, IOFlags::OpenRead, IOFlags::OpenTruncate, and IOFlags::OpenWrite.
Referenced by create(), open(), and XrdFile().
00068 { 00069 m_name = name; 00070 00071 // Actual open 00072 if ((name == 0) || (*name == 0)) 00073 throw cms::Exception("XrdFile::open()") 00074 << "Cannot open a file without a name"; 00075 00076 if ((flags & (IOFlags::OpenRead | IOFlags::OpenWrite)) == 0) 00077 throw cms::Exception("XrdFile::open()") 00078 << "Must open file '" << name << "' at least for read or write"; 00079 00080 // If I am already open, close old file first 00081 if (m_client && m_close) 00082 close(); 00083 else 00084 abort(); 00085 00086 // Translate our flags to system flags 00087 int openflags = 0; 00088 00089 if (flags & IOFlags::OpenWrite) 00090 openflags |= kXR_open_updt; 00091 else if (flags & IOFlags::OpenRead) 00092 openflags |= kXR_open_read; 00093 00094 if (flags & IOFlags::OpenAppend) 00095 throw cms::Exception("XrdFile::open()") 00096 << "Opening file '" << name << "' in append mode not supported"; 00097 00098 if (flags & IOFlags::OpenCreate) 00099 { 00100 if (! (flags & IOFlags::OpenExclusive)) 00101 openflags |= kXR_delete; 00102 openflags |= kXR_new; 00103 openflags |= kXR_mkpath; 00104 } 00105 00106 if ((flags & IOFlags::OpenTruncate) && (flags & IOFlags::OpenWrite)) 00107 openflags |= kXR_delete; 00108 00109 m_client = new XrdClient(name); 00110 if (! m_client->Open(perms, openflags) 00111 || m_client->LastServerResp()->status != kXR_ok) 00112 throw cms::Exception("XrdFile::open()") 00113 << "XrdClient::Open(name='" << name 00114 << "', flags=0x" << std::hex << openflags 00115 << ", permissions=0" << std::oct << perms << std::dec 00116 << ") => error '" << m_client->LastServerError()->errmsg 00117 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00118 00119 if (! m_client->Stat(&m_stat)) 00120 throw cms::Exception("XrdFile::open()") 00121 << "XrdClient::Stat(name='" << name 00122 << ") => error '" << m_client->LastServerError()->errmsg 00123 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00124 00125 m_offset = 0; 00126 m_close = true; 00127 edm::LogInfo("XrdFileInfo") << "Opened " << m_name; 00128 }
Implements Storage.
Definition at line 359 of file XrdFile.cc.
References Storage::CURRENT, Storage::END, Exception, m_client, m_offset, m_stat, and Storage::SET.
00360 { 00361 if (! m_client) 00362 throw cms::Exception("XrdFile::position()") 00363 << "XrdFile::position() called on a closed file"; 00364 00365 switch (whence) 00366 { 00367 case SET: 00368 m_offset = offset; 00369 break; 00370 00371 case CURRENT: 00372 m_offset += offset; 00373 break; 00374 00375 case END: 00376 m_offset = m_stat.size + offset; 00377 break; 00378 00379 default: 00380 throw cms::Exception("XrdFile::position()") 00381 << "XrdFile::position() called with incorrect 'whence' parameter"; 00382 } 00383 00384 if (m_offset < 0) 00385 m_offset = 0; 00386 if (m_offset > m_stat.size) 00387 m_stat.size = m_offset; 00388 00389 return m_offset; 00390 }
bool XrdFile::prefetch | ( | const IOPosBuffer * | what, | |
IOSize | n | |||
) | [virtual] |
Reimplemented from Storage.
Definition at line 347 of file XrdFile.cc.
References i, m_client, IOPosBuffer::offset(), r, and IOPosBuffer::size().
00348 { 00349 XReqErrorType r = kOK; 00350 for (IOSize i = 0; i < n && r == kOK; ++i) 00351 r = m_client->Read_Async(what[i].offset(), what[i].size()); 00352 return r == kOK; 00353 }
Reimplemented from Storage.
Definition at line 187 of file XrdFile.cc.
References Exception, m_client, m_name, m_offset, and s.
00188 { 00189 if (n > 0x7fffffff) 00190 throw cms::Exception("XrdFile::read()") 00191 << "XrdFile::read(name='" << m_name << "', n=" << n 00192 << ") exceeds read size limit 0x7fffffff"; 00193 00194 int s = m_client->Read(into, pos, n); 00195 if (s < 0) 00196 throw cms::Exception("XrdFile::read()") 00197 << "XrdClient::Read(name='" << m_name 00198 << "', offset=" << m_offset << ", n=" << n 00199 << ") failed with error '" << m_client->LastServerError()->errmsg 00200 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00201 return s; 00202 }
Read into into at most n number of bytes.
If this is a blocking stream, the call will block until some data can be read, end of input is reached, or an exception is thrown. For a non-blocking stream the available input is returned. If none is available, an exception is thrown.
In | case of error, a IOError exception is thrown. This includes the situation where the input stream is in non-blocking mode and no input is currently available (FIXME: make this simpler; clarify which exception). |
Implements IOInput.
Definition at line 168 of file XrdFile.cc.
References Exception, m_client, m_name, m_offset, and s.
00169 { 00170 if (n > 0x7fffffff) 00171 throw cms::Exception("XrdFile::read()") 00172 << "XrdFile::read(name='" << m_name << "', n=" << n 00173 << ") too many bytes, limit is 0x7fffffff"; 00174 00175 int s = m_client->Read(into, m_offset, n); 00176 if (s < 0) 00177 throw cms::Exception("XrdFile::read()") 00178 << "XrdClient::Read(name='" << m_name 00179 << "', offset=" << m_offset << ", n=" << n 00180 << ") failed with error '" << m_client->LastServerError()->errmsg 00181 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00182 m_offset += s; 00183 return s; 00184 }
IOSize XrdFile::readv | ( | IOPosBuffer * | into, | |
IOSize | n | |||
) | [virtual] |
Reimplemented from Storage.
Definition at line 259 of file XrdFile.cc.
References data, Exception, i, len, m_client, m_name, IOPosBuffer::offset(), s, and IOPosBuffer::size().
00260 { 00261 // See comments in readv() above. 00262 std::vector<long long> offsets (n); 00263 std::vector<int> lengths (n); 00264 for (IOSize i = 0; i < n; ++i) 00265 { 00266 IOSize len = into[i].size(); 00267 if (len > 0x7fffffff) 00268 throw cms::Exception("XrdFile::readv()") 00269 << "XrdFile::readv(name='" << m_name << "')[" << i 00270 << "].size=" << len << " exceeds read size limit 0x7fffffff"; 00271 offsets[i] = into[i].offset(); 00272 lengths[i] = len; 00273 } 00274 00275 // Prefetch into the cache (if any). 00276 if (m_client->ReadV(0, &offsets[0], &lengths[0], n) < 0) 00277 throw cms::Exception("XrdFile::readv()") 00278 << "XrdClient::ReadV(name='" << m_name 00279 << "') failed with error '" << m_client->LastServerError()->errmsg 00280 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00281 00282 // Issue actual reads. 00283 IOSize total = 0; 00284 for (IOSize i = 0; i < n; ++i) 00285 { 00286 int s = m_client->Read(into[i].data(), offsets[i], lengths[i]); 00287 if (s < 0) 00288 { 00289 if (i > 0) 00290 break; 00291 throw cms::Exception("XrdFile::readv()") 00292 << "XrdClient::Read(name='" << m_name 00293 << "', offset=" << offsets[i] << ", n=" << lengths[i] 00294 << ") failed with error '" << m_client->LastServerError()->errmsg 00295 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00296 } 00297 total += s; 00298 } 00299 00300 return total; 00301 }
Read from the input stream into multiple scattered buffers.
There are buffers to fill in an array starting at into; the memory those buffers occupy does not need to be contiguous. The buffers are filled in the order given, eac buffer is filled fully before the subsequent buffers.
If this is a blocking stream, the call will block until some data can be read, end of input is reached, or an exception is thrown. For a non-blocking stream the available input is returned. If none is available, an exception is thrown.
The base class implementation uses read(void *, IOSize) method, but derived classes may implement a more efficient alternative.
In | case of error, a IOError exception is thrown. However if some data has already been read, the error is swallowed and the method returns the data read so far. It is assumed that persistent errors will occur anyway on the next read and sporadic errors like stream becoming unvailable can be ignored. Use xread() if a different policy is desirable. |
Reimplemented from IOInput.
Definition at line 205 of file XrdFile.cc.
References data, Exception, i, len, m_client, m_name, m_offset, s, and IOBuffer::size().
00206 { 00207 // Note that the XROOTD and our interfaces do not match. 00208 // XROOTD expects readv() into a single monolithic buffer 00209 // from multiple file locations, whereas we expect scatter 00210 // gather buffers read from a single file location. 00211 // 00212 // We work around this mismatch for now by issuing a cache 00213 // read on the background, and then individual reads. 00214 IOOffset pos = m_offset; 00215 std::vector<long long> offsets (n); 00216 std::vector<int> lengths (n); 00217 for (IOSize i = 0; i < n; ++i) 00218 { 00219 IOSize len = into[i].size(); 00220 if (len > 0x7fffffff) 00221 throw cms::Exception("XrdFile::readv()") 00222 << "XrdFile::readv(name='" << m_name << "')[" << i 00223 << "].size=" << len << " exceeds read size limit 0x7fffffff"; 00224 offsets[i] = pos; 00225 lengths[i] = len; 00226 pos += len; 00227 } 00228 00229 // Prefetch into the cache (if any). 00230 if (m_client->ReadV(0, &offsets[0], &lengths[0], n) < 0) 00231 throw cms::Exception("XrdFile::readv()") 00232 << "XrdClient::ReadV(name='" << m_name 00233 << "') failed with error '" << m_client->LastServerError()->errmsg 00234 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00235 00236 // Issue actual reads. 00237 IOSize total = 0; 00238 for (IOSize i = 0; i < n; ++i) 00239 { 00240 int s = m_client->Read(into[i].data(), offsets[i], lengths[i]); 00241 if (s < 0) 00242 { 00243 if (i > 0) 00244 break; 00245 throw cms::Exception("XrdFile::readv()") 00246 << "XrdClient::Read(name='" << m_name 00247 << "', offset=" << offsets[i] << ", n=" << lengths[i] 00248 << ") failed with error '" << m_client->LastServerError()->errmsg 00249 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00250 } 00251 total += s; 00252 m_offset += s; 00253 } 00254 00255 return total; 00256 }
Implements Storage.
Definition at line 393 of file XrdFile.cc.
References Exception, and m_name.
00394 { 00395 throw cms::Exception("XrdFile::resize()") 00396 << "XrdFile::resize(name='" << m_name << "') not implemented"; 00397 }
Reimplemented from Storage.
Definition at line 326 of file XrdFile.cc.
References Exception, m_client, m_name, m_stat, and s.
00327 { 00328 if (n > 0x7fffffff) 00329 throw cms::Exception("XrdFile::write()") 00330 << "XrdFile::write(name='" << m_name << "', n=" << n 00331 << ") too many bytes, limit is 0x7fffffff"; 00332 00333 ssize_t s = m_client->Write(from, pos, n); 00334 if (s < 0) 00335 throw cms::Exception("XrdFile::write()") 00336 << "XrdFile::write(name='" << m_name << "', n=" << n 00337 << ") failed with error '" << m_client->LastServerError()->errmsg 00338 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00339 00340 if (pos + s > m_stat.size) 00341 m_stat.size = pos + s; 00342 00343 return s; 00344 }
Write n bytes of data starting at address from.
In | case of error, an exception is thrown. However if the stream is in non-blocking mode and cannot accept output, it will not throw an exception -- the return value will be less than requested. |
Implements IOOutput.
Definition at line 304 of file XrdFile.cc.
References Exception, m_client, m_name, m_offset, m_stat, and s.
00305 { 00306 if (n > 0x7fffffff) 00307 throw cms::Exception("XrdFile::write()") 00308 << "XrdFile::write(name='" << m_name << "', n=" << n 00309 << ") too many bytes, limit is 0x7fffffff"; 00310 00311 ssize_t s = m_client->Write(from, m_offset, n); 00312 if (s < 0) 00313 throw cms::Exception("XrdFile::write()") 00314 << "XrdFile::write(name='" << m_name << "', n=" << n 00315 << ") failed with error '" << m_client->LastServerError()->errmsg 00316 << "' (errno=" << m_client->LastServerError()->errnum << ")"; 00317 00318 m_offset += s; 00319 if (m_offset > m_stat.size) 00320 m_stat.size = m_offset; 00321 00322 return s; 00323 }
XrdClient* XrdFile::m_client [private] |
Definition at line 51 of file XrdFile.h.
Referenced by abort(), close(), open(), position(), prefetch(), read(), readv(), and write().
bool XrdFile::m_close [private] |
std::string XrdFile::m_name [private] |
IOOffset XrdFile::m_offset [private] |
XrdClientStatInfo XrdFile::m_stat [private] |