ucommon
commoncpp/file.h
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
00002 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
00003 //
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 2 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free software
00018 // library without restriction.  Specifically, if other files instantiate
00019 // templates or use macros or inline functions from this file, or you compile
00020 // this file and link it with other files to produce an executable, this
00021 // file does not by itself cause the resulting executable to be covered by
00022 // the GNU General Public License.  This exception does not however
00023 // invalidate any other reasons why the executable file might be covered by
00024 // the GNU General Public License.
00025 //
00026 // This exception applies only to the code released under the name GNU
00027 // Common C++.  If you copy code from other releases into a copy of GNU
00028 // Common C++, as the General Public License permits, the exception does
00029 // not apply to the code that you add in this way.  To avoid misleading
00030 // anyone as to the status of such modified files, you must delete
00031 // this exception notice from them.
00032 //
00033 // If you write modifications of your own for GNU Common C++, it is your choice
00034 // whether to permit this exception to apply to your modifications.
00035 // If you do not wish that, delete this exception notice.
00036 //
00037 
00043 #ifndef COMMONCPP_FILE_H_
00044 #define COMMONCPP_FILE_H_
00045 
00046 #ifndef COMMONCPP_CONFIG_H_
00047 #include <commoncpp/config.h>
00048 #endif
00049 
00050 #ifndef COMMONCPP_THREAD_H_
00051 #include <commoncpp/thread.h>
00052 #endif
00053 
00054 #ifndef COMMONCPP_EXCEPTION_H_
00055 #include <commoncpp/exception.h>
00056 #endif
00057 
00058 #ifndef WIN32
00059 # ifdef __BORLANDC__
00060 #  include <stdio.h>
00061 #  include <sys/types.h>
00062 # else
00063 #  include <fcntl.h>
00064 #  include <cstdio>
00065 # endif
00066 # include <dirent.h>
00067 # include <sys/stat.h>
00068 # include <sys/mman.h>
00069 #else
00070 # if __BORLANDC__ >= 0x0560
00071 #  include <dirent.h>
00072 #  include <sys/stat.h>
00073 # else
00074 #  include <direct.h>
00075 # endif
00076 #endif
00077 
00078 namespace ost {
00079 
00080 typedef unsigned long pos_t;
00081 #ifndef _MSWINDOWS_
00082 // use a define so that if the sys/types.h header already defines caddr_t
00083 // as it may on BSD systems, we do not break it by redefining again.
00084 #undef  caddr_t
00085 #define caddr_t char *
00086 typedef size_t ccxx_size_t;
00087 #else
00088 typedef DWORD ccxx_size_t;
00089 #endif
00090 
00091 #ifndef PATH_MAX
00092 #define PATH_MAX    256
00093 #endif
00094 
00095 #ifndef NAME_MAX
00096 #define NAME_MAX    64
00097 #endif
00098 
00099 class __EXPORT File
00100 {
00101 public:
00102     enum Error {
00103         errSuccess = 0,
00104         errNotOpened,
00105         errMapFailed,
00106         errInitFailed,
00107         errOpenDenied,
00108         errOpenFailed,
00109         errOpenInUse,
00110         errReadInterrupted,
00111         errReadIncomplete,
00112         errReadFailure,
00113         errWriteInterrupted,
00114         errWriteIncomplete,
00115         errWriteFailure,
00116         errLockFailure,
00117         errExtended
00118     };
00119     typedef enum Error Error;
00120 
00121     enum Access {
00122 #ifndef _MSWINDOWS_
00123         accessReadOnly = O_RDONLY,
00124         accessWriteOnly= O_WRONLY,
00125         accessReadWrite = O_RDWR
00126 #else
00127         accessReadOnly = GENERIC_READ,
00128         accessWriteOnly = GENERIC_WRITE,
00129         accessReadWrite = GENERIC_READ | GENERIC_WRITE
00130 #endif
00131     };
00132     typedef enum Access Access;
00133 
00134 protected:
00135     typedef struct _fcb {
00136         struct _fcb *next;
00137         caddr_t address;
00138         ccxx_size_t len;
00139         off_t pos;
00140         bool locked;
00141     } fcb_t;
00142 
00143 public:
00144 #ifdef  _MSWINDOWS_
00145     enum Open {
00146         openReadOnly, // = FILE_OPEN_READONLY,
00147         openWriteOnly, // = FILE_OPEN_WRITEONLY,
00148         openReadWrite, // = FILE_OPEN_READWRITE,
00149         openAppend, // = FILE_OPEN_APPEND,
00150         openTruncate // = FILE_OPEN_TRUNCATE
00151     };
00152 #else
00153     enum Open {
00154         openReadOnly = O_RDONLY,
00155         openWriteOnly = O_WRONLY,
00156         openReadWrite = O_RDWR,
00157         openAppend = O_WRONLY | O_APPEND,
00158 #ifdef  O_SYNC
00159         openSync = O_RDWR | O_SYNC,
00160 #else
00161         openSync = O_RDWR,
00162 #endif
00163         openTruncate = O_RDWR | O_TRUNC
00164     };
00165     typedef enum Open Open;
00166 
00167 /* to be used in future */
00168 
00169 #ifndef S_IRUSR
00170 #define S_IRUSR 0400
00171 #define S_IWUSR 0200
00172 #define S_IRGRP 0040
00173 #define S_IWGRP 0020
00174 #define S_IROTH 0004
00175 #define S_IWOTH 0002
00176 #endif
00177 
00178 #endif // !WIN32
00179 
00180 #ifndef _MSWINDOWS_
00181     enum Attr {
00182         attrInvalid = 0,
00183         attrPrivate = S_IRUSR | S_IWUSR,
00184         attrGroup = attrPrivate | S_IRGRP | S_IWGRP,
00185         attrPublic = attrGroup | S_IROTH | S_IWOTH
00186     };
00187 #else // defined WIN32
00188     enum Attr {
00189         attrInvalid=0,
00190         attrPrivate,
00191         attrGroup,
00192         attrPublic
00193     };
00194 #endif // !WIN32
00195     typedef enum Attr Attr;
00196 
00197 #ifdef  _MSWINDOWS_
00198     enum Complete {
00199         completionImmediate, // = FILE_COMPLETION_IMMEDIATE,
00200         completionDelayed, // = FILE_COMPLETION_DELAYED,
00201         completionDeferred // = FILE_COMPLETION_DEFERRED
00202     };
00203 
00204     enum Mapping {
00205         mappedRead,
00206         mappedWrite,
00207         mappedReadWrite
00208     };
00209 #else
00210     enum Mapping {
00211         mappedRead = accessReadOnly,
00212         mappedWrite = accessWriteOnly,
00213         mappedReadWrite = accessReadWrite
00214     };
00215     enum Complete {
00216         completionImmediate,
00217         completionDelayed,
00218         completionDeferred
00219     };
00220 #endif
00221     typedef enum Complete Complete;
00222     typedef enum Mapping Mapping;
00223 
00224 public:
00225     static const char *getExtension(const char *path);
00226     static const char *getFilename(const char *path);
00227     static char *getFilename(const char *path, char *buffer, size_t size = NAME_MAX);
00228     static char *getDirname(const char *path, char *buffer, size_t size = PATH_MAX);
00229     static char *getRealpath(const char *path, char *buffer, size_t size = PATH_MAX);
00230 };
00231 
00240 class __EXPORT Dir : public File
00241 {
00242 private:
00243 #ifndef _MSWINDOWS_
00244     DIR *dir;
00245     struct dirent *save;
00246     char save_space[sizeof(struct dirent) + PATH_MAX + 1];
00247     struct dirent *entry;
00248 #else
00249     HANDLE hDir;
00250     WIN32_FIND_DATA data, fdata;
00251     char *name;
00252 #endif
00253 
00254 public:
00255     Dir(const char *name = NULL);
00256 
00257     static bool create(const char *path, Attr attr = attrGroup);
00258     static bool remove(const char *path);
00259     static bool setPrefix(const char *path);
00260     static bool getPrefix(char *path, size_t size = PATH_MAX);
00261 
00262     void open(const char *name);
00263     void close(void);
00264 
00265     virtual ~Dir();
00266 
00267     const char *getName(void);
00268 
00269     const char *operator++()
00270         {return getName();}
00271 
00272     const char *operator++(int)
00273         {return getName();}
00274 
00275     const char *operator*();
00276 
00277     bool rewind(void);
00278 
00279     bool operator!()
00280 #ifndef _MSWINDOWS_
00281         {return !dir;}
00282 #else
00283         {return hDir != INVALID_HANDLE_VALUE;}
00284 #endif
00285 
00286     bool isValid(void);
00287 };
00288 
00295 class __EXPORT  DirTree
00296 {
00297 private:
00298     char path[PATH_MAX + 1];
00299     Dir *dir;
00300     unsigned max, current, prefixpos;
00301 
00302 protected:
00312     virtual bool filter(const char *file, struct stat *ino);
00313 
00314 public:
00322     DirTree(const char *prefix, unsigned maxdepth);
00323 
00329     DirTree(unsigned maxdepth);
00330 
00331     virtual ~DirTree();
00332 
00338     void open(const char *prefix);
00339 
00343     void close(void);
00344 
00352     char *getPath(void);
00353 
00363     unsigned perform(const char *prefix);
00364 };
00365 
00376 class __EXPORT RandomFile : protected Mutex, public File
00377 {
00378 private:
00379     Error errid;
00380     char *errstr;
00381 
00382 protected:
00383 #ifndef _MSWINDOWS_
00384     int fd;
00385     // FIXME: WIN32 as no access member
00386     Access access;
00387 #else
00388     HANDLE fd;
00389 #endif
00390     char *pathname;
00391 
00392     struct {
00393         unsigned count : 16;
00394         bool thrown : 1;
00395         bool initial : 1;
00396 #ifndef _MSWINDOWS_
00397         bool immediate : 1;
00398 #endif
00399         bool temp : 1;
00400     } flags;
00401 
00405     RandomFile(const char *name = NULL);
00406 
00410     RandomFile(const RandomFile &rf);
00411 
00419     Error error(Error errid, char *errstr = NULL);
00420 
00427     inline Error error(char *err)
00428         {return error(errExtended, err);}
00429 
00436     inline void setError(bool enable)
00437         {flags.thrown = !enable;}
00438 
00439 #ifndef _MSWINDOWS_
00440 
00447     Error setCompletion(Complete mode);
00448 #endif
00449 
00456     inline void setTemporary(bool enable)
00457         {flags.temp = enable;}
00458 
00470     virtual Attr initialize(void);
00471 
00475     void final(void);
00476 
00477 public:
00481     virtual ~RandomFile();
00482 
00491     bool initial(void);
00492 
00498     off_t getCapacity(void);
00499 
00505     virtual Error restart(void);
00506 
00512     inline Error getErrorNumber(void)
00513         {return errid;}
00514 
00520     inline char *getErrorString(void)
00521         {return errstr;}
00522 
00523     bool operator!(void);
00524 };
00525 
00540 class __EXPORT SharedFile : public RandomFile
00541 {
00542 private:
00543     fcb_t fcb;
00544     Error open(const char *path);
00545 
00546 public:
00553     SharedFile(const char *path);
00554 
00561     SharedFile(const SharedFile &file);
00562 
00566     virtual ~SharedFile();
00567 
00573     Error restart(void)
00574         {return open(pathname);}
00575 
00586     Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00587 
00598     Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00599 
00608     Error clear(ccxx_size_t length = 0, off_t pos = -1);
00609 
00616     Error append(caddr_t address = NULL, ccxx_size_t length = 0);
00617 
00623     off_t getPosition(void);
00624 
00625     bool operator++(void);
00626     bool operator--(void);
00627 };
00628 
00639 class __EXPORT MappedFile : public RandomFile
00640 {
00641 private:
00642     fcb_t fcb;
00643     int prot;
00644 #ifdef  _MSWINDOWS_
00645     HANDLE map;
00646     char mapname[64];
00647 #endif
00648 
00649 public:
00657     MappedFile(const char *fname, Access mode);
00658 
00667     MappedFile(const char *fname, Access mode, size_t size);
00668 
00679     MappedFile(const char *fname, pos_t offset, size_t size, Access mode);
00680 
00685     virtual ~MappedFile();
00686 
00687     // FIXME: not use library function in header ??
00693     void sync(void);
00694 
00701     void sync(caddr_t address, size_t len);
00702 
00711     void update(size_t offset = 0, size_t len = 0);
00712 
00720     void update(caddr_t address, size_t len);
00721 
00728     void release(caddr_t address, size_t len);
00729 
00738     inline caddr_t fetch(size_t offset = 0)
00739         {return ((char *)(fcb.address)) + offset;}
00740 
00749     caddr_t fetch(off_t pos, size_t len);
00750 
00756     bool lock(void);
00757 
00761     void unlock(void);
00762 
00769     size_t pageAligned(size_t size);
00770 };
00771 
00772 
00781 class __EXPORT DSO
00782 {
00783 private:
00784     const char *err;
00785     static Mutex mutex;
00786     static DSO *first;
00787     static DSO *last;
00788     DSO *next, *prev;
00789     const char *id;
00790     void *image;
00791 
00792     typedef ucommon::dso::addr_t addr_t;
00793 
00794 protected:
00795     void loader(const char *filename, bool resolve);
00796 
00797 public:
00803     DSO(const char *filename)
00804         {loader(filename, true);}
00805 
00806     DSO(const char *filename, bool resolve)
00807         {loader(filename, resolve);}
00808 
00813     inline const char *getError(void)
00814         {return err;}
00815 
00819     virtual ~DSO();
00820 
00824     addr_t operator[](const char *sym);
00825 
00826     static void dynunload(void);
00827 
00833     static DSO *getObject(const char *name);
00834 
00840     bool isValid(void);
00841 
00845     static void setDebug(void);
00846 };
00847 
00849 bool __EXPORT isDir(const char *path);
00851 bool __EXPORT isFile(const char *path);
00852 #ifndef WIN32
00853 
00854 bool __EXPORT isDevice(const char *path);
00855 #else
00856 
00857 inline bool isDevice(const char *path)
00858 { return false; }
00859 #endif
00860 
00861 bool __EXPORT canAccess(const char *path);
00863 bool __EXPORT canModify(const char *path);
00865 time_t __EXPORT lastModified(const char *path);
00867 time_t __EXPORT lastAccessed(const char *path);
00868 
00869 #ifdef  COMMON_STD_EXCEPTION
00870 
00871 class DirException : public IOException
00872 {
00873 public:
00874     DirException(const String &str) : IOException(str) {};
00875 };
00876 
00877 class __EXPORT DSOException : public IOException
00878 {
00879 public:
00880     DSOException(const String &str) : IOException(str) {};
00881 };
00882 
00883 class __EXPORT FileException : public IOException
00884 {
00885 public:
00886     FileException(const String &str) : IOException(str) {};
00887 };
00888 
00889 #endif
00890 
00891 } // namespace ost
00892 
00893 #endif
00894