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
00009
00010
00011
00012
00013
00014
00015
00016
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 )
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 , int perms )
00081 { open (name, flags, perms); }
00082
00084 File::File (const std::string &name, int flags , int perms )
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 , int perms)
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 , int perms)
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 , int perms )
00170 { open (name.c_str (), flags, perms); }
00171
00176 void
00177 File::open (const char *name, int flags , int perms )
00178 {
00179
00180
00181
00182
00183
00184 assert (name && *name);
00185 assert (flags & (OpenRead | OpenWrite));
00186
00187
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
00244
00245 if (m_flags & OpenAppend)
00246 position (0, END);
00247
00248 IOSize s = IOChannel::write (from, n);
00249
00250 if (m_flags & OpenUnbuffered)
00251
00252 flush ();
00253
00254 return s;
00255 }
00256
00258 IOSize
00259 File::writev (const IOBuffer *from, IOSize length)
00260 {
00261
00262
00263 if (m_flags & OpenAppend)
00264 position (0, END);
00265
00266 IOSize s = IOChannel::writev (from, length);
00267
00268 if (m_flags & OpenUnbuffered)
00269
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("File::sysclose()", "close()", error);
00285
00286 m_flags &= ~InternalAutoClose;
00287 this->fd (EDM_IOFD_INVALID);
00288 }
00289
00291 void
00292 File::abort (void)
00293 {
00294 IOFD fd = this->fd ();
00295 if (fd != EDM_IOFD_INVALID)
00296 {
00297 sysclose (fd);
00298 m_flags &= ~InternalAutoClose;
00299 this->fd (EDM_IOFD_INVALID);
00300 }
00301 }