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 // 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