CMS 3D CMS Logo

XrdFile Class Reference

#include <Utilities/XrdAdaptor/src/XrdFile.h>

Inheritance diagram for XrdFile:

Storage IOInput IOOutput

List of all members.

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


Detailed Description

Definition at line 9 of file XrdFile.h.


Constructor & Destructor Documentation

XrdFile::XrdFile ( void   ) 

Definition at line 5 of file XrdFile.cc.

00006   : m_client (0),
00007     m_offset (0),
00008     m_close (false)
00009 {}

XrdFile::XrdFile ( IOFD  fd  ) 

XrdFile::XrdFile ( const char *  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
)

Definition at line 11 of file XrdFile.cc.

References open().

00014   : m_client (0),
00015     m_offset (0),
00016     m_close (false)
00017 { open (name, flags, perms); }

XrdFile::XrdFile ( const std::string &  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
)

Definition at line 19 of file XrdFile.cc.

References open().

00022   : m_client (0),
00023     m_offset (0),
00024     m_close (false)
00025 { open (name.c_str (), flags, perms); }

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 }


Member Function Documentation

void XrdFile::abort ( void   )  [virtual]

Definition at line 157 of file XrdFile.cc.

References m_client, m_close, m_offset, and m_stat.

Referenced by open().

00158 {
00159   delete m_client;
00160   m_client = 0;
00161   m_close = false;
00162   m_offset = 0;
00163   memset(&m_stat, 0, sizeof (m_stat));
00164 }

void XrdFile::close ( void   )  [virtual]

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 }

void XrdFile::create ( const char *  name,
bool  exclusive = false,
int  perms = 0666 
) [virtual]

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 }

void XrdFile::open ( const std::string &  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
) [virtual]

Definition at line 59 of file XrdFile.cc.

References open().

00062 { open (name.c_str (), flags, perms); }

void XrdFile::open ( const char *  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
) [virtual]

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 }

IOOffset XrdFile::position ( IOOffset  offset,
Relative  whence = SET 
) [virtual]

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 }

IOSize XrdFile::read ( void into,
IOSize  n,
IOOffset  pos 
) [virtual]

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 }

IOSize XrdFile::read ( void into,
IOSize  n 
) [virtual]

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.

Returns:
The number of bytes actually read. This is less or equal to the size of the buffer. Zero indicates that the end of the input has been reached: end of file, or remote end closing for a connected channel like a pipe or a socket. Otherwise the value can be less than requested if limited amount of input is currently available for platform or implementation reasons.
Exceptions:
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 }

IOSize XrdFile::readv ( IOBuffer into,
IOSize  buffers 
) [virtual]

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.

Returns:
The number of bytes actually read. This is less or equal to the size of the buffer. Zero indicates that the end of the input has been reached: end of file, or remote end closing for a connected channel like a pipe or a socket. Otherwise the value can be less than requested if limited amount of input is currently available for platform or implementation reasons. Note that the return value indicates the number of bytes read, not the number of buffers; it is the sum total of bytes filled into all the buffers.
Exceptions:
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 }

void XrdFile::resize ( IOOffset  size  )  [virtual]

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 }

IOSize XrdFile::write ( const void from,
IOSize  n,
IOOffset  pos 
) [virtual]

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 }

IOSize XrdFile::write ( const void from,
IOSize  n 
) [virtual]

Write n bytes of data starting at address from.

Returns:
The number of bytes written. Normally this will be n, but can be less, even zero, for example if the stream is non-blocking mode and cannot accept input at this time.
Exceptions:
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 }


Member Data Documentation

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]

Definition at line 54 of file XrdFile.h.

Referenced by abort(), close(), open(), and ~XrdFile().

std::string XrdFile::m_name [private]

Definition at line 55 of file XrdFile.h.

Referenced by close(), open(), read(), readv(), resize(), write(), and ~XrdFile().

IOOffset XrdFile::m_offset [private]

Definition at line 52 of file XrdFile.h.

Referenced by abort(), close(), open(), position(), read(), readv(), and write().

XrdClientStatInfo XrdFile::m_stat [private]

Definition at line 53 of file XrdFile.h.

Referenced by abort(), close(), open(), position(), and write().


The documentation for this class was generated from the following files:
Generated on Tue Jun 9 18:35:55 2009 for CMSSW by  doxygen 1.5.4