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