ucommon
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // Copyright (C) 2006-2014 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 Lesser General Public License 00015 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free software 00018 // library without restriction. Specifically, if other files instantiate 00019 // templates or use macros or inline functions from this file, or you compile 00020 // this file and link it with other files to produce an executable, this 00021 // file does not by itself cause the resulting executable to be covered by 00022 // the GNU General Public License. This exception does not however 00023 // invalidate any other reasons why the executable file might be covered by 00024 // the GNU General Public License. 00025 // 00026 // This exception applies only to the code released under the name GNU 00027 // Common C++. If you copy code from other releases into a copy of GNU 00028 // Common C++, as the General Public License permits, the exception does 00029 // not apply to the code that you add in this way. To avoid misleading 00030 // anyone as to the status of such modified files, you must delete 00031 // this exception notice from them. 00032 // 00033 // If you write modifications of your own for GNU Common C++, it is your choice 00034 // whether to permit this exception to apply to your modifications. 00035 // If you do not wish that, delete this exception notice. 00036 // 00037 00043 #ifndef COMMONCPP_FILE_H_ 00044 #define COMMONCPP_FILE_H_ 00045 00046 #ifndef COMMONCPP_CONFIG_H_ 00047 #include <commoncpp/config.h> 00048 #endif 00049 00050 #ifndef COMMONCPP_THREAD_H_ 00051 #include <commoncpp/thread.h> 00052 #endif 00053 00054 #ifndef COMMONCPP_EXCEPTION_H_ 00055 #include <commoncpp/exception.h> 00056 #endif 00057 00058 #ifndef WIN32 00059 # ifdef __BORLANDC__ 00060 # include <stdio.h> 00061 # include <sys/types.h> 00062 # else 00063 # include <fcntl.h> 00064 # include <cstdio> 00065 # endif 00066 # include <dirent.h> 00067 # include <sys/stat.h> 00068 # include <sys/mman.h> 00069 #else 00070 # if __BORLANDC__ >= 0x0560 00071 # include <dirent.h> 00072 # include <sys/stat.h> 00073 # else 00074 # include <direct.h> 00075 # endif 00076 #endif 00077 00078 namespace ost { 00079 00080 typedef unsigned long pos_t; 00081 #ifndef _MSWINDOWS_ 00082 // use a define so that if the sys/types.h header already defines caddr_t 00083 // as it may on BSD systems, we do not break it by redefining again. 00084 #undef caddr_t 00085 #define caddr_t char * 00086 typedef size_t ccxx_size_t; 00087 #else 00088 typedef DWORD ccxx_size_t; 00089 #endif 00090 00091 #ifndef PATH_MAX 00092 #define PATH_MAX 256 00093 #endif 00094 00095 #ifndef NAME_MAX 00096 #define NAME_MAX 64 00097 #endif 00098 00099 class __EXPORT File 00100 { 00101 public: 00102 enum Error { 00103 errSuccess = 0, 00104 errNotOpened, 00105 errMapFailed, 00106 errInitFailed, 00107 errOpenDenied, 00108 errOpenFailed, 00109 errOpenInUse, 00110 errReadInterrupted, 00111 errReadIncomplete, 00112 errReadFailure, 00113 errWriteInterrupted, 00114 errWriteIncomplete, 00115 errWriteFailure, 00116 errLockFailure, 00117 errExtended 00118 }; 00119 typedef enum Error Error; 00120 00121 enum Access { 00122 #ifndef _MSWINDOWS_ 00123 accessReadOnly = O_RDONLY, 00124 accessWriteOnly= O_WRONLY, 00125 accessReadWrite = O_RDWR 00126 #else 00127 accessReadOnly = GENERIC_READ, 00128 accessWriteOnly = GENERIC_WRITE, 00129 accessReadWrite = GENERIC_READ | GENERIC_WRITE 00130 #endif 00131 }; 00132 typedef enum Access Access; 00133 00134 protected: 00135 typedef struct _fcb { 00136 struct _fcb *next; 00137 caddr_t address; 00138 ccxx_size_t len; 00139 off_t pos; 00140 bool locked; 00141 } fcb_t; 00142 00143 public: 00144 #ifdef _MSWINDOWS_ 00145 enum Open { 00146 openReadOnly, // = FILE_OPEN_READONLY, 00147 openWriteOnly, // = FILE_OPEN_WRITEONLY, 00148 openReadWrite, // = FILE_OPEN_READWRITE, 00149 openAppend, // = FILE_OPEN_APPEND, 00150 openTruncate // = FILE_OPEN_TRUNCATE 00151 }; 00152 #else 00153 enum Open { 00154 openReadOnly = O_RDONLY, 00155 openWriteOnly = O_WRONLY, 00156 openReadWrite = O_RDWR, 00157 openAppend = O_WRONLY | O_APPEND, 00158 #ifdef O_SYNC 00159 openSync = O_RDWR | O_SYNC, 00160 #else 00161 openSync = O_RDWR, 00162 #endif 00163 openTruncate = O_RDWR | O_TRUNC 00164 }; 00165 typedef enum Open Open; 00166 00167 /* to be used in future */ 00168 00169 #ifndef S_IRUSR 00170 #define S_IRUSR 0400 00171 #define S_IWUSR 0200 00172 #define S_IRGRP 0040 00173 #define S_IWGRP 0020 00174 #define S_IROTH 0004 00175 #define S_IWOTH 0002 00176 #endif 00177 00178 #endif // !WIN32 00179 00180 #ifndef _MSWINDOWS_ 00181 enum Attr { 00182 attrInvalid = 0, 00183 attrPrivate = S_IRUSR | S_IWUSR, 00184 attrGroup = attrPrivate | S_IRGRP | S_IWGRP, 00185 attrPublic = attrGroup | S_IROTH | S_IWOTH 00186 }; 00187 #else // defined WIN32 00188 enum Attr { 00189 attrInvalid=0, 00190 attrPrivate, 00191 attrGroup, 00192 attrPublic 00193 }; 00194 #endif // !WIN32 00195 typedef enum Attr Attr; 00196 00197 #ifdef _MSWINDOWS_ 00198 enum Complete { 00199 completionImmediate, // = FILE_COMPLETION_IMMEDIATE, 00200 completionDelayed, // = FILE_COMPLETION_DELAYED, 00201 completionDeferred // = FILE_COMPLETION_DEFERRED 00202 }; 00203 00204 enum Mapping { 00205 mappedRead, 00206 mappedWrite, 00207 mappedReadWrite 00208 }; 00209 #else 00210 enum Mapping { 00211 mappedRead = accessReadOnly, 00212 mappedWrite = accessWriteOnly, 00213 mappedReadWrite = accessReadWrite 00214 }; 00215 enum Complete { 00216 completionImmediate, 00217 completionDelayed, 00218 completionDeferred 00219 }; 00220 #endif 00221 typedef enum Complete Complete; 00222 typedef enum Mapping Mapping; 00223 00224 public: 00225 static const char *getExtension(const char *path); 00226 static const char *getFilename(const char *path); 00227 static char *getFilename(const char *path, char *buffer, size_t size = NAME_MAX); 00228 static char *getDirname(const char *path, char *buffer, size_t size = PATH_MAX); 00229 static char *getRealpath(const char *path, char *buffer, size_t size = PATH_MAX); 00230 }; 00231 00240 class __EXPORT Dir : public File 00241 { 00242 private: 00243 #ifndef _MSWINDOWS_ 00244 DIR *dir; 00245 struct dirent *save; 00246 char save_space[sizeof(struct dirent) + PATH_MAX + 1]; 00247 struct dirent *entry; 00248 #else 00249 HANDLE hDir; 00250 WIN32_FIND_DATA data, fdata; 00251 char *name; 00252 #endif 00253 00254 public: 00255 Dir(const char *name = NULL); 00256 00257 static bool create(const char *path, Attr attr = attrGroup); 00258 static bool remove(const char *path); 00259 static bool setPrefix(const char *path); 00260 static bool getPrefix(char *path, size_t size = PATH_MAX); 00261 00262 void open(const char *name); 00263 void close(void); 00264 00265 virtual ~Dir(); 00266 00267 const char *getName(void); 00268 00269 const char *operator++() 00270 {return getName();} 00271 00272 const char *operator++(int) 00273 {return getName();} 00274 00275 const char *operator*(); 00276 00277 bool rewind(void); 00278 00279 bool operator!() 00280 #ifndef _MSWINDOWS_ 00281 {return !dir;} 00282 #else 00283 {return hDir != INVALID_HANDLE_VALUE;} 00284 #endif 00285 00286 bool isValid(void); 00287 }; 00288 00295 class __EXPORT DirTree 00296 { 00297 private: 00298 char path[PATH_MAX + 1]; 00299 Dir *dir; 00300 unsigned max, current, prefixpos; 00301 00302 protected: 00312 virtual bool filter(const char *file, struct stat *ino); 00313 00314 public: 00322 DirTree(const char *prefix, unsigned maxdepth); 00323 00329 DirTree(unsigned maxdepth); 00330 00331 virtual ~DirTree(); 00332 00338 void open(const char *prefix); 00339 00343 void close(void); 00344 00352 char *getPath(void); 00353 00363 unsigned perform(const char *prefix); 00364 }; 00365 00376 class __EXPORT RandomFile : protected Mutex, public File 00377 { 00378 private: 00379 Error errid; 00380 char *errstr; 00381 00382 protected: 00383 #ifndef _MSWINDOWS_ 00384 int fd; 00385 // FIXME: WIN32 as no access member 00386 Access access; 00387 #else 00388 HANDLE fd; 00389 #endif 00390 char *pathname; 00391 00392 struct { 00393 unsigned count : 16; 00394 bool thrown : 1; 00395 bool initial : 1; 00396 #ifndef _MSWINDOWS_ 00397 bool immediate : 1; 00398 #endif 00399 bool temp : 1; 00400 } flags; 00401 00405 RandomFile(const char *name = NULL); 00406 00410 RandomFile(const RandomFile &rf); 00411 00419 Error error(Error errid, char *errstr = NULL); 00420 00427 inline Error error(char *err) 00428 {return error(errExtended, err);} 00429 00436 inline void setError(bool enable) 00437 {flags.thrown = !enable;} 00438 00439 #ifndef _MSWINDOWS_ 00440 00447 Error setCompletion(Complete mode); 00448 #endif 00449 00456 inline void setTemporary(bool enable) 00457 {flags.temp = enable;} 00458 00470 virtual Attr initialize(void); 00471 00475 void final(void); 00476 00477 public: 00481 virtual ~RandomFile(); 00482 00491 bool initial(void); 00492 00498 off_t getCapacity(void); 00499 00505 virtual Error restart(void); 00506 00512 inline Error getErrorNumber(void) 00513 {return errid;} 00514 00520 inline char *getErrorString(void) 00521 {return errstr;} 00522 00523 bool operator!(void); 00524 }; 00525 00540 class __EXPORT SharedFile : public RandomFile 00541 { 00542 private: 00543 fcb_t fcb; 00544 Error open(const char *path); 00545 00546 public: 00553 SharedFile(const char *path); 00554 00561 SharedFile(const SharedFile &file); 00562 00566 virtual ~SharedFile(); 00567 00573 Error restart(void) 00574 {return open(pathname);} 00575 00586 Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1); 00587 00598 Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1); 00599 00608 Error clear(ccxx_size_t length = 0, off_t pos = -1); 00609 00616 Error append(caddr_t address = NULL, ccxx_size_t length = 0); 00617 00623 off_t getPosition(void); 00624 00625 bool operator++(void); 00626 bool operator--(void); 00627 }; 00628 00639 class __EXPORT MappedFile : public RandomFile 00640 { 00641 private: 00642 fcb_t fcb; 00643 int prot; 00644 #ifdef _MSWINDOWS_ 00645 HANDLE map; 00646 char mapname[64]; 00647 #endif 00648 00649 public: 00657 MappedFile(const char *fname, Access mode); 00658 00667 MappedFile(const char *fname, Access mode, size_t size); 00668 00679 MappedFile(const char *fname, pos_t offset, size_t size, Access mode); 00680 00685 virtual ~MappedFile(); 00686 00687 // FIXME: not use library function in header ?? 00693 void sync(void); 00694 00701 void sync(caddr_t address, size_t len); 00702 00711 void update(size_t offset = 0, size_t len = 0); 00712 00720 void update(caddr_t address, size_t len); 00721 00728 void release(caddr_t address, size_t len); 00729 00738 inline caddr_t fetch(size_t offset = 0) 00739 {return ((char *)(fcb.address)) + offset;} 00740 00749 caddr_t fetch(off_t pos, size_t len); 00750 00756 bool lock(void); 00757 00761 void unlock(void); 00762 00769 size_t pageAligned(size_t size); 00770 }; 00771 00772 00781 class __EXPORT DSO 00782 { 00783 private: 00784 const char *err; 00785 static Mutex mutex; 00786 static DSO *first; 00787 static DSO *last; 00788 DSO *next, *prev; 00789 const char *id; 00790 void *image; 00791 00792 typedef ucommon::dso::addr_t addr_t; 00793 00794 protected: 00795 void loader(const char *filename, bool resolve); 00796 00797 public: 00803 DSO(const char *filename) 00804 {loader(filename, true);} 00805 00806 DSO(const char *filename, bool resolve) 00807 {loader(filename, resolve);} 00808 00813 inline const char *getError(void) 00814 {return err;} 00815 00819 virtual ~DSO(); 00820 00824 addr_t operator[](const char *sym); 00825 00826 static void dynunload(void); 00827 00833 static DSO *getObject(const char *name); 00834 00840 bool isValid(void); 00841 00845 static void setDebug(void); 00846 }; 00847 00849 bool __EXPORT isDir(const char *path); 00851 bool __EXPORT isFile(const char *path); 00852 #ifndef WIN32 00853 00854 bool __EXPORT isDevice(const char *path); 00855 #else 00856 00857 inline bool isDevice(const char *path) 00858 { return false; } 00859 #endif 00860 00861 bool __EXPORT canAccess(const char *path); 00863 bool __EXPORT canModify(const char *path); 00865 time_t __EXPORT lastModified(const char *path); 00867 time_t __EXPORT lastAccessed(const char *path); 00868 00869 #ifdef COMMON_STD_EXCEPTION 00870 00871 class DirException : public IOException 00872 { 00873 public: 00874 DirException(const String &str) : IOException(str) {}; 00875 }; 00876 00877 class __EXPORT DSOException : public IOException 00878 { 00879 public: 00880 DSOException(const String &str) : IOException(str) {}; 00881 }; 00882 00883 class __EXPORT FileException : public IOException 00884 { 00885 public: 00886 FileException(const String &str) : IOException(str) {}; 00887 }; 00888 00889 #endif 00890 00891 } // namespace ost 00892 00893 #endif 00894