CMS 3D CMS Logo

Public Member Functions | Private Attributes

XrdFile Class Reference

#include <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 char *name, bool exclusive=false, int perms=0666)
virtual void create (const std::string &name, bool exclusive=false, int perms=0666)
virtual void open (const char *name, int flags=IOFlags::OpenRead, int perms=0666)
virtual void open (const std::string &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)
virtual IOSize read (void *into, IOSize n, IOOffset pos)
virtual IOSize readv (IOBuffer *into, IOSize n)
virtual IOSize readv (IOPosBuffer *into, IOSize n)
virtual void resize (IOOffset size)
virtual IOSize write (const void *from, IOSize n, IOOffset pos)
virtual IOSize write (const void *from, IOSize n)
 XrdFile (void)
 XrdFile (IOFD fd)
 XrdFile (const std::string &name, int flags=IOFlags::OpenRead, int perms=0666)
 XrdFile (const char *name, int flags=IOFlags::OpenRead, int perms=0666)
 ~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 7 of file XrdFile.cc.

  : m_client (0),
    m_offset (0),
    m_close (false)
{}
XrdFile::XrdFile ( IOFD  fd)
XrdFile::XrdFile ( const char *  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
)

Definition at line 13 of file XrdFile.cc.

References open().

  : m_client (0),
    m_offset (0),
    m_close (false)
{ open (name, flags, perms); }
XrdFile::XrdFile ( const std::string &  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
)

Definition at line 21 of file XrdFile.cc.

References flags, and open().

  : m_client (0),
    m_offset (0),
    m_close (false)
{ open (name.c_str (), flags, perms); }
XrdFile::~XrdFile ( void  )

Definition at line 29 of file XrdFile.cc.

References m_close, and m_name.

{
  if (m_close)
    edm::LogError("XrdFileError")
      << "Destructor called on XROOTD file '" << m_name
      << "' but the file is still open";
}

Member Function Documentation

void XrdFile::abort ( void  ) [virtual]

Definition at line 170 of file XrdFile.cc.

References m_client, m_close, m_offset, and m_stat.

Referenced by open().

{
  delete m_client;
  m_client = 0;
  m_close = false;
  m_offset = 0;
  memset(&m_stat, 0, sizeof (m_stat));
}
void XrdFile::close ( void  ) [virtual]

Reimplemented from Storage.

Definition at line 144 of file XrdFile.cc.

References m_client, m_close, m_name, m_offset, and m_stat.

Referenced by open().

{
  if (! m_client)
  {
    edm::LogError("XrdFileError")
      << "XrdFile::close(name='" << m_name
      << "') called but the file is not open";
    m_close = false;
    return;
  }

  if (! m_client->Close())
    edm::LogWarning("XrdFileWarning")
      << "XrdFile::close(name='" << m_name
      << "') failed with error '" << m_client->LastServerError()->errmsg
      << "' (errno=" << m_client->LastServerError()->errnum << ")";
  delete m_client;
  m_client = 0;

  m_close = false;
  m_offset = 0;
  memset(&m_stat, 0, sizeof (m_stat));
  edm::LogInfo("XrdFileInfo") << "Closed " << m_name;
}
void XrdFile::create ( const std::string &  name,
bool  exclusive = false,
int  perms = 0666 
) [virtual]
void XrdFile::create ( const char *  name,
bool  exclusive = false,
int  perms = 0666 
) [virtual]
void XrdFile::open ( const std::string &  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
) [virtual]

Definition at line 61 of file XrdFile.cc.

References flags, and open().

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

Definition at line 67 of file XrdFile.cc.

References abort(), cms::Exception::addContext(), close(), edm::errors::FileOpenError, m_client, m_close, m_name, m_offset, m_stat, mergeVDriftHistosByStation::name, IOFlags::OpenAppend, IOFlags::OpenCreate, IOFlags::OpenExclusive, IOFlags::OpenRead, IOFlags::OpenTruncate, and IOFlags::OpenWrite.

Referenced by create(), open(), and XrdFile().

{
  m_name = name;

  // Actual open
  if ((name == 0) || (*name == 0)) {
    edm::Exception ex(edm::errors::FileOpenError);
    ex << "Cannot open a file without a name";
    ex.addContext("Calling XrdFile::open()");
    throw ex;
  }
  if ((flags & (IOFlags::OpenRead | IOFlags::OpenWrite)) == 0) {
    edm::Exception ex(edm::errors::FileOpenError);
    ex << "Must open file '" << name << "' at least for read or write";
    ex.addContext("Calling XrdFile::open()");
    throw ex;
  }
  // If I am already open, close old file first
  if (m_client && m_close)
    close();
  else
    abort();

  // Translate our flags to system flags
  int openflags = 0;

  if (flags & IOFlags::OpenWrite)
    openflags |= kXR_open_updt;
  else if (flags & IOFlags::OpenRead)
    openflags |= kXR_open_read;

  if (flags & IOFlags::OpenAppend) {
    edm::Exception ex(edm::errors::FileOpenError);
    ex << "Opening file '" << name << "' in append mode not supported";
    ex.addContext("Calling XrdFile::open()");
    throw ex;
  }

  if (flags & IOFlags::OpenCreate)
  {
    if (! (flags & IOFlags::OpenExclusive))
      openflags |= kXR_delete;
    openflags |= kXR_new;
    openflags |= kXR_mkpath;
  }

  if ((flags & IOFlags::OpenTruncate) && (flags & IOFlags::OpenWrite))
    openflags |= kXR_delete;

  m_client = new XrdClient(name);
  if (! m_client->Open(perms, openflags)
      || m_client->LastServerResp()->status != kXR_ok) {
    edm::Exception ex(edm::errors::FileOpenError);
    ex << "XrdClient::Open(name='" << name
       << "', flags=0x" << std::hex << openflags
       << ", permissions=0" << std::oct << perms << std::dec
       << ") => error '" << m_client->LastServerError()->errmsg
       << "' (errno=" << m_client->LastServerError()->errnum << ")";
    ex.addContext("Calling XrdFile::open()");
    throw ex;
  }
  if (! m_client->Stat(&m_stat)) {
    edm::Exception ex(edm::errors::FileOpenError);
    ex << "XrdClient::Stat(name='" << name
      << ") => error '" << m_client->LastServerError()->errmsg
      << "' (errno=" << m_client->LastServerError()->errnum << ")";
    ex.addContext("Calling XrdFile::open()");
    throw ex;
  }
  m_offset = 0;
  m_close = true;
  edm::LogInfo("XrdFileInfo") << "Opened " << m_name;
}
IOOffset XrdFile::position ( IOOffset  offset,
Relative  whence = SET 
) [virtual]

Implements Storage.

Definition at line 405 of file XrdFile.cc.

References cms::Exception::addContext(), Storage::CURRENT, Storage::END, m_client, m_offset, m_stat, evf::evtn::offset(), and Storage::SET.

{
  if (! m_client) {
    cms::Exception ex("FilePositionError");
    ex << "XrdFile::position() called on a closed file";
    ex.addContext("Calling XrdFile::position()");
    throw ex;
  }
  switch (whence)
  {
  case SET:
    m_offset = offset;
    break;

  case CURRENT:
    m_offset += offset;
    break;

  case END:
    m_offset = m_stat.size + offset;
    break;

  default:
    cms::Exception ex("FilePositionError");
    ex << "XrdFile::position() called with incorrect 'whence' parameter";
    ex.addContext("Calling XrdFile::position()");
    throw ex;
  }

  if (m_offset < 0)
    m_offset = 0;
  if (m_offset > m_stat.size)
    m_stat.size = m_offset;

  return m_offset;
}
bool XrdFile::prefetch ( const IOPosBuffer what,
IOSize  n 
) [virtual]

Reimplemented from Storage.

Definition at line 393 of file XrdFile.cc.

References i, m_client, IOPosBuffer::offset(), csvReporter::r, and IOPosBuffer::size().

{
  XReqErrorType r = kOK;
  for (IOSize i = 0; i < n && r == kOK; ++i)
    r = m_client->Read_Async(what[i].offset(), what[i].size());
  return r == kOK;
}
IOSize XrdFile::read ( void *  into,
IOSize  n,
IOOffset  pos 
) [virtual]

Reimplemented from Storage.

Definition at line 205 of file XrdFile.cc.

References cms::Exception::addContext(), edm::errors::FileReadError, m_client, m_name, m_offset, and asciidump::s.

{
  if (n > 0x7fffffff) {
    edm::Exception ex(edm::errors::FileReadError);
    ex << "XrdFile::read(name='" << m_name << "', n=" << n
       << ") exceeds read size limit 0x7fffffff";
    ex.addContext("Calling XrdFile::read()");
    throw ex;
  }
  int s = m_client->Read(into, pos, n);
  if (s < 0) {
    edm::Exception ex(edm::errors::FileReadError);
    ex << "XrdClient::Read(name='" << m_name
       << "', offset=" << m_offset << ", n=" << n
       << ") failed with error '" << m_client->LastServerError()->errmsg
       << "' (errno=" << m_client->LastServerError()->errnum << ")";
    ex.addContext("Calling XrdFile::read()");
    throw ex;
  }
  return s;
}
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:
Incase 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 181 of file XrdFile.cc.

References cms::Exception::addContext(), edm::errors::FileReadError, m_client, m_name, m_offset, and asciidump::s.

{
  if (n > 0x7fffffff) {
    edm::Exception ex(edm::errors::FileReadError);
    ex << "XrdFile::read(name='" << m_name << "', n=" << n
       << ") too many bytes, limit is 0x7fffffff";
    ex.addContext("Calling XrdFile::read()");
    throw ex;
  }
  int s = m_client->Read(into, m_offset, n);
  if (s < 0) {
    edm::Exception ex(edm::errors::FileReadError);
    ex << "XrdClient::Read(name='" << m_name
       << "', offset=" << m_offset << ", n=" << n
       << ") failed with error '" << m_client->LastServerError()->errmsg
       << "' (errno=" << m_client->LastServerError()->errnum << ")";
    ex.addContext("Calling XrdFile::read()");
    throw ex;
  }
  m_offset += s;
  return s;
}
IOSize XrdFile::readv ( IOPosBuffer into,
IOSize  n 
) [virtual]

Reimplemented from Storage.

Definition at line 290 of file XrdFile.cc.

References cms::Exception::addContext(), AlCaHLTBitMon_QueryRunRegistry::data, edm::errors::FileReadError, i, l1GtPatternGenerator_cfi::lengths, m_client, m_name, n, IOPosBuffer::offset(), asciidump::s, IOPosBuffer::size(), and pileupDistInMC::total.

{
  // See comments in readv() above.
  std::vector<long long> offsets (n);
  std::vector<int> lengths (n);
  for (IOSize i = 0; i < n; ++i)
  {
    IOSize len = into[i].size();
    if (len > 0x7fffffff) {
      edm::Exception ex(edm::errors::FileReadError);
      ex << "XrdFile::readv(name='" << m_name << "')[" << i
         << "].size=" << len << " exceeds read size limit 0x7fffffff";
      ex.addContext("Calling XrdFile::readv()");
      throw ex;
    }
    offsets[i] = into[i].offset();
    lengths[i] = len;
  }

  // Prefetch into the cache (if any).
  if (m_client->ReadV(0, &offsets[0], &lengths[0], n) < 0) {
    edm::Exception ex(edm::errors::FileReadError);
    ex << "XrdClient::ReadV(name='" << m_name
       << "') failed with error '" << m_client->LastServerError()->errmsg
       << "' (errno=" << m_client->LastServerError()->errnum << ")";
    ex.addContext("Calling XrdFile::readv()");
    throw ex;
  }
  // Issue actual reads.
  IOSize total = 0;
  for (IOSize i = 0; i < n; ++i)
  {
    int s = m_client->Read(into[i].data(), offsets[i], lengths[i]);
    if (s < 0)
    {
      if (i > 0)
        break;
      edm::Exception ex(edm::errors::FileReadError);
      ex << "XrdClient::Read(name='" << m_name
         << "', offset=" << offsets[i] << ", n=" << lengths[i]
         << ") failed with error '" << m_client->LastServerError()->errmsg
         << "' (errno=" << m_client->LastServerError()->errnum << ")";
      ex.addContext("Calling XrdFile::readv()");
      throw ex;
    }
    total += s;
  }

  return total;
}
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:
Incase 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 228 of file XrdFile.cc.

References cms::Exception::addContext(), AlCaHLTBitMon_QueryRunRegistry::data, edm::errors::FileReadError, i, l1GtPatternGenerator_cfi::lengths, m_client, m_name, m_offset, n, pos, asciidump::s, IOBuffer::size(), and pileupDistInMC::total.

{
  // Note that the XROOTD and our interfaces do not match.
  // XROOTD expects readv() into a single monolithic buffer
  // from multiple file locations, whereas we expect scatter
  // gather buffers read from a single file location.
  //
  // We work around this mismatch for now by issuing a cache
  // read on the background, and then individual reads.
  IOOffset pos = m_offset;
  std::vector<long long> offsets (n);
  std::vector<int> lengths (n);
  for (IOSize i = 0; i < n; ++i)
  {
    IOSize len = into[i].size();
    if (len > 0x7fffffff) {
      edm::Exception ex(edm::errors::FileReadError);
      ex << "XrdFile::readv(name='" << m_name << "')[" << i
         << "].size=" << len << " exceeds read size limit 0x7fffffff";
      ex.addContext("Calling XrdFile::readv()");
      throw ex;
    }
    offsets[i] = pos;
    lengths[i] = len;
    pos += len;
  }

  // Prefetch into the cache (if any).
  if (m_client->ReadV(0, &offsets[0], &lengths[0], n) < 0) {
    edm::Exception ex(edm::errors::FileReadError);
    ex << "XrdClient::ReadV(name='" << m_name
       << "') failed with error '" << m_client->LastServerError()->errmsg
       << "' (errno=" << m_client->LastServerError()->errnum << ")";
    ex.addContext("Calling XrdFile::readv()");
    throw ex;
  }

  // Issue actual reads.
  IOSize total = 0;
  for (IOSize i = 0; i < n; ++i)
  {
    int s = m_client->Read(into[i].data(), offsets[i], lengths[i]);
    if (s < 0)
    {
      if (i > 0)
        break;
      edm::Exception ex(edm::errors::FileReadError);
      ex << "XrdClient::Read(name='" << m_name
         << "', offset=" << offsets[i] << ", n=" << lengths[i]
         << ") failed with error '" << m_client->LastServerError()->errmsg
         << "' (errno=" << m_client->LastServerError()->errnum << ")";
      ex.addContext("Calling XrdFile::readv()");
      throw ex;
    }
    total += s;
    m_offset += s;
  }

  return total;
}
void XrdFile::resize ( IOOffset  size) [virtual]

Implements Storage.

Definition at line 443 of file XrdFile.cc.

References cms::Exception::addContext(), and m_name.

{
  cms::Exception ex("FileResizeError");
  ex << "XrdFile::resize(name='" << m_name << "') not implemented";
  ex.addContext("Calling XrdFile::resize()");
  throw ex;
}
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:
Incase 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 342 of file XrdFile.cc.

References cms::Exception::addContext(), m_client, m_name, m_offset, m_stat, and asciidump::s.

{
  if (n > 0x7fffffff) {
    cms::Exception ex("FileWriteError");
    ex << "XrdFile::write(name='" << m_name << "', n=" << n
       << ") too many bytes, limit is 0x7fffffff";
    ex.addContext("Calling XrdFile::write()");
    throw ex;
  }
  ssize_t s = m_client->Write(from, m_offset, n);
  if (s < 0) {
    cms::Exception ex("FileWriteError");
    ex << "XrdFile::write(name='" << m_name << "', n=" << n
       << ") failed with error '" << m_client->LastServerError()->errmsg
       << "' (errno=" << m_client->LastServerError()->errnum << ")";
    ex.addContext("Calling XrdFile::write()");
    throw ex;
  }
  m_offset += s;
  if (m_offset > m_stat.size)
    m_stat.size = m_offset;

  return s;
}
IOSize XrdFile::write ( const void *  from,
IOSize  n,
IOOffset  pos 
) [virtual]

Reimplemented from Storage.

Definition at line 368 of file XrdFile.cc.

References cms::Exception::addContext(), m_client, m_name, m_stat, and asciidump::s.

{
  if (n > 0x7fffffff) {
    cms::Exception ex("FileWriteError");
    ex << "XrdFile::write(name='" << m_name << "', n=" << n
       << ") too many bytes, limit is 0x7fffffff";
    ex.addContext("Calling XrdFile::write()");
    throw ex;
  }
  ssize_t s = m_client->Write(from, pos, n);
  if (s < 0) {
    cms::Exception ex("FileWriteError");
    ex << "XrdFile::write(name='" << m_name << "', n=" << n
       << ") failed with error '" << m_client->LastServerError()->errmsg
       << "' (errno=" << m_client->LastServerError()->errnum << ")";
    ex.addContext("Calling XrdFile::write()");
    throw ex;
  }
  if (pos + s > m_stat.size)
    m_stat.size = pos + s;

  return s;
}

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().

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().