file.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
00002 // Copyright (C) 2006-2008 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 // use a define so that if the sys/types.h header already defines caddr_t
00097 // as it may on BSD systems, we do not break it by redefining again.
00098 #undef  caddr_t
00099 #define caddr_t char *
00100 typedef size_t ccxx_size_t;
00101 #else
00102 #if     !defined(__BORLANDC__) || __BORLANDC__ >= 0x0560
00103 typedef LONG off_t;
00104 #endif
00105 typedef void* caddr_t;
00106 typedef DWORD ccxx_size_t;
00107 #endif
00108 
00109 #ifndef PATH_MAX
00110 #define PATH_MAX        256
00111 #endif
00112 
00113 #ifndef NAME_MAX
00114 #define NAME_MAX        64
00115 #endif
00116 
00117 class __EXPORT File
00118 {
00119 public:
00120         enum Error {
00121                 errSuccess = 0,
00122                 errNotOpened,
00123                 errMapFailed,
00124                 errInitFailed,
00125                 errOpenDenied,
00126                 errOpenFailed,
00127                 errOpenInUse,
00128                 errReadInterrupted,
00129                 errReadIncomplete,
00130                 errReadFailure,
00131                 errWriteInterrupted,
00132                 errWriteIncomplete,
00133                 errWriteFailure,
00134                 errLockFailure,
00135                 errExtended
00136         };
00137         typedef enum Error Error;
00138 
00139         enum Access {
00140 #ifndef WIN32
00141                 accessReadOnly = O_RDONLY,
00142                 accessWriteOnly= O_WRONLY,
00143                 accessReadWrite = O_RDWR
00144 #else
00145                 accessReadOnly = GENERIC_READ,
00146                 accessWriteOnly = GENERIC_WRITE,
00147                 accessReadWrite = GENERIC_READ | GENERIC_WRITE
00148 #endif
00149         };
00150         typedef enum Access Access;
00151 
00152 protected:
00153         typedef struct _fcb {
00154                 struct _fcb *next;
00155                 caddr_t address;
00156                 ccxx_size_t len;
00157                 off_t pos;
00158                 bool locked;
00159         } fcb_t;
00160 
00161 public:
00162 #ifdef  WIN32
00163         enum Open {
00164                 openReadOnly, // = FILE_OPEN_READONLY,
00165                 openWriteOnly, // = FILE_OPEN_WRITEONLY,
00166                 openReadWrite, // = FILE_OPEN_READWRITE,
00167                 openAppend, // = FILE_OPEN_APPEND,
00168                 openTruncate // = FILE_OPEN_TRUNCATE
00169         };
00170         #else
00171         enum Open {
00172                 openReadOnly = O_RDONLY,
00173                 openWriteOnly = O_WRONLY,
00174                 openReadWrite = O_RDWR,
00175                 openAppend = O_WRONLY | O_APPEND,
00176 #ifdef  O_SYNC
00177                 openSync = O_RDWR | O_SYNC,
00178 #else
00179                 openSync = O_RDWR,
00180 #endif
00181                 openTruncate = O_RDWR | O_TRUNC
00182         };
00183         typedef enum Open Open;
00184 
00185 /* to be used in future */
00186 
00187 #ifndef S_IRUSR
00188 #define S_IRUSR 0400
00189 #define S_IWUSR 0200
00190 #define S_IRGRP 0040
00191 #define S_IWGRP 0020
00192 #define S_IROTH 0004
00193 #define S_IWOTH 0002
00194 #endif
00195 
00196 #endif // !WIN32
00197 
00198 #ifndef WIN32
00199         enum Attr {
00200                 attrInvalid = 0,
00201                 attrPrivate = S_IRUSR | S_IWUSR,
00202                 attrGroup = attrPrivate | S_IRGRP | S_IWGRP,
00203                 attrPublic = attrGroup | S_IROTH | S_IWOTH
00204         };
00205         #else // defined WIN32
00206         enum Attr {
00207                 attrInvalid=0,
00208                 attrPrivate,
00209                 attrGroup,
00210                 attrPublic
00211         };
00212 #endif // !WIN32
00213         typedef enum Attr Attr;
00214 
00215 #ifdef  WIN32
00216         enum Complete {
00217                 completionImmediate, // = FILE_COMPLETION_IMMEDIATE,
00218                 completionDelayed, // = FILE_COMPLETION_DELAYED,
00219                 completionDeferred // = FILE_COMPLETION_DEFERRED
00220         };
00221 
00222         enum Mapping {
00223                 mappedRead,
00224                 mappedWrite,
00225                 mappedReadWrite
00226         };
00227 #else
00228         enum Mapping {
00229                 mappedRead = accessReadOnly,
00230                 mappedWrite = accessWriteOnly,
00231                 mappedReadWrite = accessReadWrite
00232         };
00233         enum Complete {
00234                 completionImmediate,
00235                 completionDelayed,
00236                 completionDeferred
00237         };
00238 #endif
00239         typedef enum Complete Complete;
00240         typedef enum Mapping Mapping;
00241 
00242 public:
00243         static const char *getExtension(const char *path);
00244         static const char *getFilename(const char *path);
00245         static char *getFilename(const char *path, char *buffer, size_t size = NAME_MAX);
00246         static char *getDirname(const char *path, char *buffer, size_t size = PATH_MAX);
00247         static char *getRealpath(const char *path, char *buffer, size_t size = PATH_MAX);
00248 };
00249 
00258 class __EXPORT Dir : public File
00259 {
00260 private:
00261 #ifndef WIN32
00262         DIR *dir;
00263 #ifdef  HAVE_READDIR_R
00264         struct dirent *save;
00265         char save_space[sizeof(struct dirent) + PATH_MAX + 1];
00266 #endif
00267         struct dirent *entry;
00268 #else
00269         HANDLE hDir;
00270         WIN32_FIND_DATA data, fdata;
00271         char *name;
00272 #endif
00273 
00274 public:
00275         Dir(const char *name = NULL);
00276 
00277         static bool create(const char *path, Attr attr = attrGroup);
00278         static bool remove(const char *path);
00279         static bool setPrefix(const char *path);
00280         static bool getPrefix(char *path, size_t size = PATH_MAX);
00281 
00282         void open(const char *name);
00283         void close(void);
00284 
00285         virtual ~Dir();
00286 
00287         const char *getName(void);
00288 
00289         const char *operator++()
00290                 {return getName();};
00291 
00292         const char *operator++(int)
00293                 {return getName();};
00294 
00295         const char *operator*();
00296 
00297         bool rewind(void);
00298 
00299         bool operator!()
00300 #ifndef WIN32
00301                 {return !dir;};
00302 #else
00303                 {return hDir != INVALID_HANDLE_VALUE;};
00304 #endif
00305 
00306         bool isValid(void);
00307 };
00308 
00315 class __EXPORT  DirTree
00316 {
00317 private:
00318         char path[PATH_MAX + 1];
00319         Dir *dir;
00320         unsigned max, current, prefixpos;
00321 
00322 protected:
00332         virtual bool filter(const char *file, struct stat *ino);
00333 
00334 public:
00342         DirTree(const char *prefix, unsigned maxdepth);
00343 
00349         DirTree(unsigned maxdepth);
00350 
00351         virtual ~DirTree();
00352 
00358         void open(const char *prefix);
00359 
00363         void close(void);
00364 
00372         char *getPath(void);
00373 
00383         unsigned perform(const char *prefix);
00384 };
00385 
00396 class __EXPORT RandomFile : protected Mutex, public File
00397 {
00398 private:
00399         Error errid;
00400         char *errstr;
00401 
00402 protected:
00403 #ifndef WIN32
00404         int fd;
00405         // FIXME: WIN32 as no access member
00406         Access access;
00407 #else
00408         HANDLE fd;
00409 #endif
00410         char *pathname;
00411 
00412         struct {
00413                 unsigned count : 16;
00414                 bool thrown : 1;
00415                 bool initial : 1;
00416 #ifndef WIN32
00417                 bool immediate : 1;
00418 #endif
00419                 bool temp : 1;
00420         } flags;
00421 
00425         RandomFile(const char *name = NULL);
00426 
00430         RandomFile(const RandomFile &rf);
00431 
00439         Error error(Error errid, char *errstr = NULL);
00440 
00447         inline Error error(char *err)
00448                 {return error(errExtended, err);};
00449 
00456         inline void setError(bool enable)
00457                 {flags.thrown = !enable;};
00458 
00459 #ifndef WIN32
00460 
00467         Error setCompletion(Complete mode);
00468 #endif
00469 
00476         inline void setTemporary(bool enable)
00477                 {flags.temp = enable;};
00478 
00490         virtual Attr initialize(void);
00491 
00495         void final(void);
00496 
00497 public:
00501         virtual ~RandomFile();
00502 
00511         bool initial(void);
00512 
00518         off_t getCapacity(void);
00519 
00525         virtual Error restart(void);
00526 
00532         inline Error getErrorNumber(void)
00533                 {return errid;};
00534 
00540         inline char *getErrorString(void)
00541                 {return errstr;};
00542 
00543         bool operator!(void);
00544 };
00545 
00565 class __EXPORT ThreadFile : public RandomFile
00566 {
00567 private:
00568         ThreadKey state;
00569         fcb_t *first;
00570         fcb_t *getFCB(void);
00571         Error open(const char *path);
00572 
00573 public:
00580         ThreadFile(const char *path);
00581 
00585         virtual ~ThreadFile();
00586 
00592         Error restart(void);
00593 
00603         Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00604 
00614         Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00615 
00621         Error append(caddr_t address = NULL, ccxx_size_t length = 0);
00622 
00628         off_t getPosition(void);
00629 
00630         bool operator++(void);
00631         bool operator--(void);
00632 };
00633 
00648 class __EXPORT SharedFile : public RandomFile
00649 {
00650 private:
00651         fcb_t fcb;
00652         Error open(const char *path);
00653 
00654 public:
00661         SharedFile(const char *path);
00662 
00669         SharedFile(const SharedFile &file);
00670 
00674         virtual ~SharedFile();
00675 
00681         Error restart(void)
00682                 {return open(pathname);};
00683 
00694         Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00695 
00706         Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
00707 
00716         Error clear(ccxx_size_t length = 0, off_t pos = -1);
00717 
00724         Error append(caddr_t address = NULL, ccxx_size_t length = 0);
00725 
00731         off_t getPosition(void);
00732 
00733         bool operator++(void);
00734         bool operator--(void);
00735 };
00736 
00747 class __EXPORT MappedFile : public RandomFile
00748 {
00749 private:
00750         fcb_t fcb;
00751         int prot;
00752 #ifdef  WIN32
00753         HANDLE map;
00754         char mapname[64];
00755 #endif
00756 
00757 public:
00765         MappedFile(const char *fname, Access mode);
00766 
00775         MappedFile(const char *fname, Access mode, size_t size);
00776 
00787         MappedFile(const char *fname, pos_t offset, size_t size, Access mode);
00788 
00793         virtual ~MappedFile();
00794 
00795         // FIXME: not use library function in header ??
00801         void sync(void);
00802 
00809         void sync(caddr_t address, size_t len);
00810 
00819         void update(size_t offset = 0, size_t len = 0);
00820 
00828         void update(caddr_t address, size_t len);
00829 
00836         void release(caddr_t address, size_t len);
00837 
00846         inline caddr_t fetch(size_t offset = 0)
00847                 {return ((char *)(fcb.address)) + offset;};
00848 
00857         caddr_t fetch(off_t pos, size_t len);
00858 
00864         bool lock(void);
00865 
00869         void unlock(void);
00870 
00877         size_t pageAligned(size_t size);
00878 };
00879 
00880 
00889 class __EXPORT DSO
00890 {
00891 private:
00892         const char *err;
00893 #ifdef  HAVE_MODULES
00894         static Mutex mutex;
00895         static DSO *first;
00896         static DSO *last;
00897         DSO *next, *prev;
00898         const char *id;
00899 #if     defined(HAVE_MACH_DYLD)
00900         NSModule oModule;
00901 #elif   defined(HAVE_SHL_LOAD)
00902         shl_t image;
00903 #elif   defined(WIN32)
00904         HINSTANCE hImage;
00905 #else
00906         void *image;
00907 #endif
00908         void loader(const char *filename, bool resolve);
00909 #endif
00910 
00911 public:
00917 #ifdef  HAVE_MODULES
00918         DSO(const char *filename)
00919                 {loader(filename, true);};
00920 
00921         DSO(const char *filename, bool resolve)
00922                 {loader(filename, resolve);};
00923 #else
00924         DSO(const char *filename)
00925                 {throw this;};
00926         DSO(const char *filename, bool resolve)
00927                 {throw this;};
00928 #endif
00929 
00934         inline const char *getError(void)
00935                 {return err;};
00936 
00940 #ifdef  HAVE_MODULES
00941         virtual ~DSO();
00942 #endif
00943 
00947 #ifdef  HAVE_MODULES
00948         void* operator[](const char *sym);
00949 #else
00950         void *operator[](const char *)
00951                 {return NULL;};
00952 #endif
00953 
00954 #ifdef  HAVE_MODULES
00955         static void dynunload(void);
00956 #else
00957         static void dynunload(void)
00958                 {return;};
00959 #endif
00960 
00966         static DSO *getObject(const char *name);
00967 
00973         bool isValid(void);
00974 
00978         static void setDebug(void);
00979 };
00980 
00982 bool __EXPORT isDir(const char *path);
00984 bool __EXPORT isFile(const char *path);
00985 #ifndef WIN32
00986 
00987 bool __EXPORT isDevice(const char *path);
00988 #else
00989 
00990 inline bool isDevice(const char *path)
00991 { return false; }
00992 #endif
00993 
00994 bool __EXPORT canAccess(const char *path);
00996 bool __EXPORT canModify(const char *path);
00998 time_t __EXPORT lastModified(const char *path);
01000 time_t __EXPORT lastAccessed(const char *path);
01001 
01002 #ifdef  COMMON_STD_EXCEPTION
01003 
01004 class DirException : public IOException
01005 {
01006 public:
01007         DirException(const String &str) : IOException(str) {};
01008 };
01009 
01010 class __EXPORT DSOException : public IOException
01011 {
01012 public:
01013         DSOException(const String &str) : IOException(str) {};
01014 };
01015 
01016 class __EXPORT FileException : public IOException
01017 {
01018 public:
01019         FileException(const String &str) : IOException(str) {};
01020 };
01021 
01022 #endif
01023 
01024 #ifdef  CCXX_NAMESPACES
01025 }
01026 #endif
01027 
01028 #endif
01029 

Generated on Tue Apr 7 05:52:43 2009 for GNU CommonC++ by  doxygen 1.4.7