GNU CommonC++
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 CCXX_FILE_H_
00045 #define CCXX_FILE_H_
00046 
00047 #ifndef CCXX_CONFIG_H_
00048 #include <cc++/config.h>
00049 #endif
00050 
00051 #ifndef CCXX_MISSING_H_
00052 #include <cc++/missing.h>
00053 #endif
00054 
00055 #ifndef CCXX_THREAD_H_
00056 #include <cc++/thread.h>
00057 #endif
00058 
00059 #ifndef CCXX_EXCEPTION_H_
00060 #include <cc++/exception.h>
00061 #endif
00062 
00063 #ifndef WIN32
00064 # ifdef __BORLANDC__
00065 #  include <stdio.h>
00066 #  include <sys/types.h>
00067 # else
00068 #  include <cstdio>
00069 # endif
00070 # include <dirent.h>
00071 # include <sys/stat.h>
00072 # include <sys/mman.h>
00073 #else
00074 # if __BORLANDC__ >= 0x0560
00075 #  include <dirent.h>
00076 #  include <sys/stat.h>
00077 # else
00078 #  include <direct.h>
00079 # endif
00080 #endif
00081 
00082 #ifdef  HAVE_SHL_LOAD
00083 #include <dl.h>
00084 #endif
00085 
00086 #ifdef  HAVE_MACH_DYLD
00087 #include <mach-o/dyld.h>
00088 #endif
00089 
00090 #ifdef  CCXX_NAMESPACES
00091 namespace ost {
00092 #endif
00093 
00094 typedef unsigned long pos_t;
00095 #ifndef WIN32
00096 #include <sys/types.h>
00097 typedef size_t ccxx_size_t;
00098 #else
00099 #if !defined(__BORLANDC__) || __BORLANDC__ >= 0x0560
00100 typedef LONG off_t;
00101 #endif
00102 typedef void* caddr_t;
00103 typedef DWORD ccxx_size_t;
00104 #endif
00105 
00106 #ifndef PATH_MAX
00107 #define PATH_MAX    256
00108 #endif
00109 
00110 #ifndef NAME_MAX
00111 #define NAME_MAX    64
00112 #endif
00113 
00114 class __EXPORT File
00115 {
00116 public:
00117     enum Error {
00118         errSuccess = 0,
00119         errNotOpened,
00120         errMapFailed,
00121         errInitFailed,
00122         errOpenDenied,
00123         errOpenFailed,
00124         errOpenInUse,
00125         errReadInterrupted,
00126         errReadIncomplete,
00127         errReadFailure,
00128         errWriteInterrupted,
00129         errWriteIncomplete,
00130         errWriteFailure,
00131         errLockFailure,
00132         errExtended
00133     };
00134     typedef enum Error Error;
00135 
00136     enum Access {
00137 #ifndef WIN32
00138         accessReadOnly = O_RDONLY,
00139         accessWriteOnly= O_WRONLY,
00140         accessReadWrite = O_RDWR
00141 #else
00142         accessReadOnly = GENERIC_READ,
00143         accessWriteOnly = GENERIC_WRITE,
00144         accessReadWrite = GENERIC_READ | GENERIC_WRITE
00145 #endif
00146     };
00147     typedef enum Access Access;
00148 
00149 protected:
00150     typedef struct _fcb {
00151         struct _fcb *next;
00152         caddr_t address;
00153         ccxx_size_t len;
00154         off_t pos;
00155         bool locked;
00156     } fcb_t;
00157 
00158 public:
00159 #ifdef  WIN32
00160     enum Open {
00161         openReadOnly, // = FILE_OPEN_READONLY,
00162         openWriteOnly, // = FILE_OPEN_WRITEONLY,
00163         openReadWrite, // = FILE_OPEN_READWRITE,
00164         openAppend, // = FILE_OPEN_APPEND,
00165         openTruncate // = FILE_OPEN_TRUNCATE
00166     };
00167     #else
00168     enum Open {
00169         openReadOnly = O_RDONLY,
00170         openWriteOnly = O_WRONLY,
00171         openReadWrite = O_RDWR,
00172         openAppend = O_WRONLY | O_APPEND,
00173 #ifdef  O_SYNC
00174         openSync = O_RDWR | O_SYNC,
00175 #else
00176         openSync = O_RDWR,
00177 #endif
00178         openTruncate = O_RDWR | O_TRUNC
00179     };
00180     typedef enum Open Open;
00181 
00182 /* to be used in future */
00183 
00184 #ifndef S_IRUSR
00185 #define S_IRUSR 0400
00186 #define S_IWUSR 0200
00187 #define S_IRGRP 0040
00188 #define S_IWGRP 0020
00189 #define S_IROTH 0004
00190 #define S_IWOTH 0002
00191 #endif
00192 
00193 #endif // !WIN32
00194 
00195 #ifndef WIN32
00196     enum Attr {
00197         attrInvalid = 0,
00198         attrPrivate = S_IRUSR | S_IWUSR,
00199         attrGroup = attrPrivate | S_IRGRP | S_IWGRP,
00200         attrPublic = attrGroup | S_IROTH | S_IWOTH
00201     };
00202     #else // defined WIN32
00203     enum Attr {
00204         attrInvalid=0,
00205         attrPrivate,
00206         attrGroup,
00207         attrPublic
00208     };
00209 #endif // !WIN32
00210     typedef enum Attr Attr;
00211 
00212 #ifdef  WIN32
00213     enum Complete {
00214         completionImmediate, // = FILE_COMPLETION_IMMEDIATE,
00215         completionDelayed, // = FILE_COMPLETION_DELAYED,
00216         completionDeferred // = FILE_COMPLETION_DEFERRED
00217     };
00218 
00219     enum Mapping {
00220         mappedRead,
00221         mappedWrite,
00222         mappedReadWrite
00223     };
00224 #else
00225     enum Mapping {
00226         mappedRead = accessReadOnly,
00227         mappedWrite = accessWriteOnly,
00228         mappedReadWrite = accessReadWrite
00229     };
00230     enum Complete {
00231         completionImmediate,
00232         completionDelayed,
00233         completionDeferred
00234     };
00235 #endif
00236     typedef enum Complete Complete;
00237     typedef enum Mapping Mapping;
00238 
00239 public:
00240     static const char *getExtension(const char *path);
00241     static const char *getFilename(const char *path);
00242     static char *getFilename(const char *path, char *buffer, size_t size = NAME_MAX);
00243     static char *getDirname(const char *path, char *buffer, size_t size = PATH_MAX);
00244     static char *getRealpath(const char *path, char *buffer, size_t size = PATH_MAX);
00245 };
00246 
00255 class __EXPORT Dir : public File
00256 {
00257 private:
00258 #ifndef WIN32
00259     DIR *dir;
00260 #ifdef  HAVE_READDIR_R
00261     struct dirent *save;
00262     char save_space[sizeof(struct dirent) + PATH_MAX + 1];
00263 #endif
00264     struct dirent *entry;
00265 #else
00266     HANDLE hDir;
00267     WIN32_FIND_DATA data, fdata;
00268     char *name;
00269 #endif
00270 
00271 public:
00272     Dir(const char *name = NULL);
00273 
00274     static bool create(const char *path, Attr attr = attrGroup);
00275     static bool remove(const char *path);
00276     static bool setPrefix(const char *path);
00277     static bool getPrefix(char *path, size_t size = PATH_MAX);
00278 
00279     void open(const char *name);
00280     void close(void);
00281 
00282     virtual ~Dir();
00283 
00284     const char *getName(void);
00285 
00286     const char *operator++()
00287         {return getName();};
00288 
00289     const char *operator++(int)
00290         {return getName();};
00291 
00292     const char *operator*();
00293 
00294     bool rewind(void);
00295 
00296     bool operator!()
00297 #ifndef WIN32
00298         {return !dir;};
00299 #else
00300         {return hDir != INVALID_HANDLE_VALUE;};
00301 #endif
00302 
00303     bool isValid(void);
00304 };
00305 
00312 class __EXPORT  DirTree
00313 {
00314 private:
00315     char path[PATH_MAX + 1];
00316     Dir *dir;
00317     unsigned max, current, prefixpos;
00318 
00319 protected:
00329     virtual bool filter(const char *file, struct stat *ino);
00330 
00331 public:
00339     DirTree(const char *prefix, unsigned maxdepth);
00340 
00346     DirTree(unsigned maxdepth);
00347 
00348     virtual ~DirTree();
00349 
00355     void open(const char *prefix);
00356 
00360     void close(void);
00361 
00369     char *getPath(void);
00370 
00380     unsigned perform(const char *prefix);
00381 };
00382 
00393 class __EXPORT RandomFile : protected Mutex, public File
00394 {
00395 private:
00396     Error errid;
00397     char *errstr;
00398 
00399 protected:
00400 #ifndef WIN32
00401     int fd;
00402     // FIXME: WIN32 as no access member
00403     Access access;
00404 #else
00405     HANDLE fd;
00406 #endif
00407     char *pathname;
00408 
00409     struct {
00410         unsigned count : 16;
00411         bool thrown : 1;
00412         bool initial : 1;
00413 #ifndef WIN32
00414         bool immediate : 1;
00415 #endif
00416         bool temp : 1;
00417     } flags;
00418 
00422     RandomFile(const char *name = NULL);
00423 
00427     RandomFile(const RandomFile &rf);
00428 
00436     Error error(Error errid, char *errstr = NULL);
00437 
00444     inline Error error(char *err)
00445         {return error(errExtended, err);};
00446 
00453     inline void setError(bool enable)
00454         {flags.thrown = !enable;};
00455 
00456 #ifndef WIN32
00457 
00464     Error setCompletion(Complete mode);
00465 #endif
00466 
00473     inline void setTemporary(bool enable)
00474         {flags.temp = enable;};
00475 
00487     virtual Attr initialize(void);
00488 
00492     void final(void);
00493 
00494 public:
00498     virtual ~RandomFile();
00499 
00508     bool initial(void);
00509 
00515     off_t getCapacity(void);
00516 
00522     virtual Error restart(void);
00523 
00529     inline Error getErrorNumber(void)
00530         {return errid;};
00531 
00537     inline char *getErrorString(void)
00538         {return errstr;};
00539 
00540     bool operator!(void);
00541 };
00542 
00562 class __EXPORT ThreadFile : public RandomFile
00563 {
00564 private:
00565     ThreadKey state;
00566     fcb_t *first;
00567     fcb_t *getFCB(void);
00568     Error open(const char *path);
00569 
00570 public:
00577     ThreadFile(const char *path);
00578 
00582     virtual ~ThreadFile();
00583 
00589     Error restart(void);
00590 
00600     Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00601 
00611     Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00612 
00618     Error append(caddr_t address = NULL, ccxx_size_t length = 0);
00619 
00625     off_t getPosition(void);
00626 
00627     bool operator++(void);
00628     bool operator--(void);
00629 };
00630 
00645 class __EXPORT SharedFile : public RandomFile
00646 {
00647 private:
00648     fcb_t fcb;
00649     Error open(const char *path);
00650 
00651 public:
00658     SharedFile(const char *path);
00659 
00666     SharedFile(const SharedFile &file);
00667 
00671     virtual ~SharedFile();
00672 
00678     Error restart(void)
00679         {return open(pathname);};
00680 
00691     Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00692 
00703     Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00704 
00713     Error clear(ccxx_size_t length = 0, off_t pos = -1);
00714 
00721     Error append(caddr_t address = NULL, ccxx_size_t length = 0);
00722 
00728     off_t getPosition(void);
00729 
00730     bool operator++(void);
00731     bool operator--(void);
00732 };
00733 
00744 class __EXPORT MappedFile : public RandomFile
00745 {
00746 private:
00747     fcb_t fcb;
00748     int prot;
00749 #ifdef  WIN32
00750     HANDLE map;
00751     char mapname[64];
00752 #endif
00753 
00754 public:
00762     MappedFile(const char *fname, Access mode);
00763 
00772     MappedFile(const char *fname, Access mode, size_t size);
00773 
00784     MappedFile(const char *fname, pos_t offset, size_t size, Access mode);
00785 
00790     virtual ~MappedFile();
00791 
00792     // FIXME: not use library function in header ??
00798     void sync(void);
00799 
00806     void sync(caddr_t address, size_t len);
00807 
00816     void update(size_t offset = 0, size_t len = 0);
00817 
00825     void update(caddr_t address, size_t len);
00826 
00833     void release(caddr_t address, size_t len);
00834 
00843     inline caddr_t fetch(size_t offset = 0)
00844         {return ((char *)(fcb.address)) + offset;};
00845 
00854     caddr_t fetch(off_t pos, size_t len);
00855 
00861     bool lock(void);
00862 
00866     void unlock(void);
00867 
00874     size_t pageAligned(size_t size);
00875 };
00876 
00877 
00886 class __EXPORT DSO
00887 {
00888 private:
00889     const char *err;
00890 #ifdef  HAVE_MODULES
00891     static Mutex mutex;
00892     static DSO *first;
00893     static DSO *last;
00894     DSO *next, *prev;
00895     const char *id;
00896 #if defined(HAVE_MACH_DYLD)
00897     NSModule oModule;
00898 #elif   defined(HAVE_SHL_LOAD)
00899     shl_t image;
00900 #elif   defined(WIN32)
00901     HINSTANCE hImage;
00902 #else
00903     void *image;
00904 #endif
00905     void loader(const char *filename, bool resolve);
00906 #endif
00907 
00908 public:
00914 #ifdef  HAVE_MODULES
00915     DSO(const char *filename)
00916         {loader(filename, true);};
00917 
00918     DSO(const char *filename, bool resolve)
00919         {loader(filename, resolve);};
00920 #else
00921     DSO(const char *filename)
00922         {throw this;};
00923     DSO(const char *filename, bool resolve)
00924         {throw this;};
00925 #endif
00926 
00931     inline const char *getError(void)
00932         {return err;};
00933 
00937 #ifdef  HAVE_MODULES
00938     virtual ~DSO();
00939 #endif
00940 
00944 #ifdef  HAVE_MODULES
00945     void* operator[](const char *sym);
00946 #else
00947     void *operator[](const char *)
00948         {return NULL;};
00949 #endif
00950 
00951 #ifdef  HAVE_MODULES
00952     static void dynunload(void);
00953 #else
00954     static void dynunload(void)
00955         {return;};
00956 #endif
00957 
00963     static DSO *getObject(const char *name);
00964 
00970     bool isValid(void);
00971 
00975     static void setDebug(void);
00976 };
00977 
00979 bool __EXPORT isDir(const char *path);
00981 bool __EXPORT isFile(const char *path);
00982 #ifndef WIN32
00983 
00984 bool __EXPORT isDevice(const char *path);
00985 #else
00986 
00987 inline bool isDevice(const char *path)
00988 { return false; }
00989 #endif
00990 
00991 bool __EXPORT canAccess(const char *path);
00993 bool __EXPORT canModify(const char *path);
00995 time_t __EXPORT lastModified(const char *path);
00997 time_t __EXPORT lastAccessed(const char *path);
00998 
00999 #ifdef  COMMON_STD_EXCEPTION
01000 
01001 class DirException : public IOException
01002 {
01003 public:
01004     DirException(const String &str) : IOException(str) {};
01005 };
01006 
01007 class __EXPORT DSOException : public IOException
01008 {
01009 public:
01010     DSOException(const String &str) : IOException(str) {};
01011 };
01012 
01013 class __EXPORT FileException : public IOException
01014 {
01015 public:
01016     FileException(const String &str) : IOException(str) {};
01017 };
01018 
01019 #endif
01020 
01021 #ifdef  CCXX_NAMESPACES
01022 }
01023 #endif
01024 
01025 #endif
01026