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