GNU CommonC++
|
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