CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Utilities/StorageFactory/src/File.cc

Go to the documentation of this file.
00001 #include "Utilities/StorageFactory/interface/File.h"
00002 #include "Utilities/StorageFactory/src/SysFile.h"
00003 #include "Utilities/StorageFactory/src/Throw.h"
00004 #include <cassert>
00005 
00006 using namespace IOFlags;
00007 
00008 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00009 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00010 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00011 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00012 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00013 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00014 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00015 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00016 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00017 
00053 
00054 
00055 
00056 
00057 File::File (void)
00058 {
00059   fd (EDM_IOFD_INVALID);
00060   m_flags = 0;
00061 }
00062 
00066 File::File (IOFD fd, bool autoclose /* = true */)
00067 {
00068   this->fd (fd);
00069   m_flags = autoclose ? InternalAutoClose : 0;
00070 }
00071 
00073 File::File (IOFD fd, unsigned flags)
00074 {
00075   this->fd (fd);
00076   m_flags = flags;
00077 }
00078 
00080 File::File (const char *name, int flags /*= OpenRead*/, int perms /*= 0666*/)
00081 { open (name, flags, perms); }
00082 
00084 File::File (const std::string &name, int flags /*= OpenRead*/, int perms /*= 0666*/)
00085 { open (name.c_str (), flags, perms); }
00086 
00090 File::~File (void)
00091 {
00092   if (m_flags & InternalAutoClose)
00093     abort ();
00094 }
00095 
00097 
00102 void
00103 File::setAutoClose (bool autoclose)
00104 {
00105   m_flags &= ~InternalAutoClose;
00106   if (autoclose)
00107     m_flags |= InternalAutoClose;
00108 }
00109 
00111 
00116 File *
00117 File::duplicate (bool copy) const
00118 {
00119   File *dup = new File (fd (), copy ? m_flags : 0);
00120   return copy ? this->duplicate (dup) : dup;
00121 }
00122 
00125 File *
00126 File::duplicate (File *child) const
00127 {
00128   IOFD fd = this->fd ();
00129   assert (fd != EDM_IOFD_INVALID);
00130   assert (child);
00131   child->fd (sysduplicate (fd));
00132   child->m_flags = m_flags;
00133   return child;
00134 }
00135 
00137 
00141 void
00142 File::create (const char *name, bool exclusive /*=false*/, int perms/*=0666*/)
00143 {
00144   open (name,
00145         (OpenCreate | OpenWrite | OpenTruncate
00146          | (exclusive ? OpenExclusive : 0)),
00147         perms);
00148 }
00149 
00154 void
00155 File::create (const std::string &name, bool exclusive /*=false*/, int perms/*=0666*/)
00156 {
00157   open (name.c_str (),
00158         (OpenCreate | OpenWrite | OpenTruncate
00159          | (exclusive ? OpenExclusive : 0)),
00160         perms);
00161 }
00162 
00168 void
00169 File::open (const std::string &name, int flags /*= OpenRead*/, int perms /*= 0666*/)
00170 { open (name.c_str (), flags, perms); }
00171 
00176 void
00177 File::open (const char *name, int flags /*= OpenRead*/, int perms /*= 0666*/)
00178 {
00179   // is zero and always implied.  OTOH, existence check should be
00180   // done with Filename::exists() -- see comments there about what
00181   // can happen on a WIN32 remote share even if the file doesn't
00182   // exist.  For now make sure that read or write was asked for.
00183 
00184   assert (name && *name);
00185   assert (flags & (OpenRead | OpenWrite));
00186 
00187   // If I am already open, close the old file first.
00188   if (fd () != EDM_IOFD_INVALID && (m_flags & InternalAutoClose))
00189     close ();
00190     
00191   IOFD          newfd = EDM_IOFD_INVALID;
00192   unsigned      newflags = InternalAutoClose;
00193 
00194   sysopen (name, flags, perms, newfd, newflags);
00195 
00196   fd (newfd);
00197   m_flags = newflags;
00198 }
00199 
00200 void
00201 File::attach (IOFD fd)
00202 {
00203   this->fd (fd);
00204   m_flags = 0;
00205 }
00206 
00208 
00209 bool
00210 File::prefetch (const IOPosBuffer *what, IOSize n)
00211 {
00212   IOFD fd = this->fd();
00213   for (IOSize i = 0; i < n; ++i)
00214   {
00215 #if F_RDADVISE
00216     radvisory info;
00217     info.ra_offset = what[i].offset();
00218     info.ra_count = what[i].size();
00219     fcntl(fd, F_RDADVISE, &info);
00220 #elif _POSIX_ADVISORY_INFO > 0
00221     posix_fadvise(fd, what[i].offset(), what[i].size(), POSIX_FADV_WILLNEED);
00222 #else
00223 # error advisory read ahead not available on this platform
00224 #endif
00225   }
00226   return true;
00227 }
00228 
00230 IOSize
00231 File::read (void *into, IOSize n)
00232 { return IOChannel::read (into, n); }
00233 
00235 IOSize
00236 File::readv (IOBuffer *into, IOSize length)
00237 { return IOChannel::readv (into, length); }
00238 
00240 IOSize
00241 File::write (const void *from, IOSize n)
00242 {
00243   // FIXME: This may create a race condition or cause trouble on
00244   // remote files.  Should be currently needed only on WIN32.
00245   if (m_flags & OpenAppend)
00246     position (0, END);
00247 
00248   IOSize s = IOChannel::write (from, n);
00249 
00250   if (m_flags & OpenUnbuffered)
00251     // FIXME: Exception handling?
00252     flush ();
00253 
00254   return s;
00255 }
00256 
00258 IOSize
00259 File::writev (const IOBuffer *from, IOSize length)
00260 {
00261   // FIXME: This may create a race condition or cause trouble on
00262   // remote files.  Should be currently needed only on WIN32.
00263   if (m_flags & OpenAppend)
00264     position (0, END);
00265 
00266   IOSize s = IOChannel::writev (from, length);
00267 
00268   if (m_flags & OpenUnbuffered)
00269     // FIXME: Exception handling?
00270     flush ();
00271 
00272   return s;
00273 }
00274 
00276 void
00277 File::close (void)
00278 {
00279   IOFD fd = this->fd ();
00280   assert (fd != EDM_IOFD_INVALID);
00281 
00282   int error;
00283   if (! sysclose (fd, &error))
00284     throwStorageError("FileCloseError", "Calling File::close()",
00285                       "sysclose", error);
00286 
00287   m_flags &= ~InternalAutoClose;
00288   this->fd (EDM_IOFD_INVALID);
00289 }
00290 
00292 void
00293 File::abort (void)
00294 {
00295   IOFD fd = this->fd ();
00296   if (fd != EDM_IOFD_INVALID)
00297   {
00298     sysclose (fd);
00299     m_flags &= ~InternalAutoClose;
00300     this->fd (EDM_IOFD_INVALID);
00301   }
00302 }