UCommon
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks. 00003 // Copyright (C) 2015 Cherokees of Idaho. 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with this program. If not, see <http://www.gnu.org/licenses/>. 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 COMMONCPP_FILE_H_ 00045 #define COMMONCPP_FILE_H_ 00046 00047 #ifndef COMMONCPP_CONFIG_H_ 00048 #include <commoncpp/config.h> 00049 #endif 00050 00051 #ifndef COMMONCPP_THREAD_H_ 00052 #include <commoncpp/thread.h> 00053 #endif 00054 00055 #ifndef COMMONCPP_EXCEPTION_H_ 00056 #include <commoncpp/exception.h> 00057 #endif 00058 00059 #ifndef WIN32 00060 # ifdef __BORLANDC__ 00061 # include <stdio.h> 00062 # include <sys/types.h> 00063 # else 00064 # include <fcntl.h> 00065 # include <cstdio> 00066 # endif 00067 # include <dirent.h> 00068 # include <sys/stat.h> 00069 # include <sys/mman.h> 00070 #else 00071 # if __BORLANDC__ >= 0x0560 00072 # include <dirent.h> 00073 # include <sys/stat.h> 00074 # else 00075 # include <direct.h> 00076 # endif 00077 #endif 00078 00079 namespace ost { 00080 00081 typedef unsigned long pos_t; 00082 #ifndef _MSWINDOWS_ 00083 // use a define so that if the sys/types.h header already defines caddr_t 00084 // as it may on BSD systems, we do not break it by redefining again. 00085 #undef caddr_t 00086 #define caddr_t char * 00087 typedef size_t ccxx_size_t; 00088 #else 00089 typedef DWORD ccxx_size_t; 00090 #endif 00091 00092 #ifndef PATH_MAX 00093 #define PATH_MAX 256 00094 #endif 00095 00096 #ifndef NAME_MAX 00097 #define NAME_MAX 64 00098 #endif 00099 00100 class __EXPORT File 00101 { 00102 public: 00103 enum Error { 00104 errSuccess = 0, 00105 errNotOpened, 00106 errMapFailed, 00107 errInitFailed, 00108 errOpenDenied, 00109 errOpenFailed, 00110 errOpenInUse, 00111 errReadInterrupted, 00112 errReadIncomplete, 00113 errReadFailure, 00114 errWriteInterrupted, 00115 errWriteIncomplete, 00116 errWriteFailure, 00117 errLockFailure, 00118 errExtended 00119 }; 00120 typedef enum Error Error; 00121 00122 enum Access { 00123 #ifndef _MSWINDOWS_ 00124 accessReadOnly = O_RDONLY, 00125 accessWriteOnly= O_WRONLY, 00126 accessReadWrite = O_RDWR 00127 #else 00128 accessReadOnly = GENERIC_READ, 00129 accessWriteOnly = GENERIC_WRITE, 00130 accessReadWrite = GENERIC_READ | GENERIC_WRITE 00131 #endif 00132 }; 00133 typedef enum Access Access; 00134 00135 protected: 00136 typedef struct _fcb { 00137 struct _fcb *next; 00138 caddr_t address; 00139 ccxx_size_t len; 00140 off_t pos; 00141 bool locked; 00142 } fcb_t; 00143 00144 public: 00145 #ifdef _MSWINDOWS_ 00146 enum Open { 00147 openReadOnly, // = FILE_OPEN_READONLY, 00148 openWriteOnly, // = FILE_OPEN_WRITEONLY, 00149 openReadWrite, // = FILE_OPEN_READWRITE, 00150 openAppend, // = FILE_OPEN_APPEND, 00151 openTruncate // = FILE_OPEN_TRUNCATE 00152 }; 00153 #else 00154 enum Open { 00155 openReadOnly = O_RDONLY, 00156 openWriteOnly = O_WRONLY, 00157 openReadWrite = O_RDWR, 00158 openAppend = O_WRONLY | O_APPEND, 00159 #ifdef O_SYNC 00160 openSync = O_RDWR | O_SYNC, 00161 #else 00162 openSync = O_RDWR, 00163 #endif 00164 openTruncate = O_RDWR | O_TRUNC 00165 }; 00166 typedef enum Open Open; 00167 00168 /* to be used in future */ 00169 00170 #ifndef S_IRUSR 00171 #define S_IRUSR 0400 00172 #define S_IWUSR 0200 00173 #define S_IRGRP 0040 00174 #define S_IWGRP 0020 00175 #define S_IROTH 0004 00176 #define S_IWOTH 0002 00177 #endif 00178 00179 #endif // !WIN32 00180 00181 #ifndef _MSWINDOWS_ 00182 enum Attr { 00183 attrInvalid = 0, 00184 attrPrivate = S_IRUSR | S_IWUSR, 00185 attrGroup = attrPrivate | S_IRGRP | S_IWGRP, 00186 attrPublic = attrGroup | S_IROTH | S_IWOTH 00187 }; 00188 #else // defined WIN32 00189 enum Attr { 00190 attrInvalid=0, 00191 attrPrivate, 00192 attrGroup, 00193 attrPublic 00194 }; 00195 #endif // !WIN32 00196 typedef enum Attr Attr; 00197 00198 #ifdef _MSWINDOWS_ 00199 enum Complete { 00200 completionImmediate, // = FILE_COMPLETION_IMMEDIATE, 00201 completionDelayed, // = FILE_COMPLETION_DELAYED, 00202 completionDeferred // = FILE_COMPLETION_DEFERRED 00203 }; 00204 00205 enum Mapping { 00206 mappedRead, 00207 mappedWrite, 00208 mappedReadWrite 00209 }; 00210 #else 00211 enum Mapping { 00212 mappedRead = accessReadOnly, 00213 mappedWrite = accessWriteOnly, 00214 mappedReadWrite = accessReadWrite 00215 }; 00216 enum Complete { 00217 completionImmediate, 00218 completionDelayed, 00219 completionDeferred 00220 }; 00221 #endif 00222 typedef enum Complete Complete; 00223 typedef enum Mapping Mapping; 00224 00225 public: 00226 static const char *getExtension(const char *path); 00227 static const char *getFilename(const char *path); 00228 static char *getFilename(const char *path, char *buffer, size_t size = NAME_MAX); 00229 static char *getDirname(const char *path, char *buffer, size_t size = PATH_MAX); 00230 static char *getRealpath(const char *path, char *buffer, size_t size = PATH_MAX); 00231 }; 00232 00241 class __EXPORT Dir : public File 00242 { 00243 private: 00244 #ifndef _MSWINDOWS_ 00245 DIR *dir; 00246 struct dirent *save; 00247 char save_space[sizeof(struct dirent) + PATH_MAX + 1]; 00248 struct dirent *entry; 00249 #else 00250 HANDLE hDir; 00251 WIN32_FIND_DATA data, fdata; 00252 char *name; 00253 #endif 00254 00255 public: 00256 Dir(const char *name = NULL); 00257 00258 static bool create(const char *path, Attr attr = attrGroup); 00259 static bool remove(const char *path); 00260 static bool setPrefix(const char *path); 00261 static bool getPrefix(char *path, size_t size = PATH_MAX); 00262 00263 void open(const char *name); 00264 void close(void); 00265 00266 virtual ~Dir(); 00267 00268 const char *getName(void); 00269 00270 const char *operator++() 00271 {return getName();} 00272 00273 const char *operator++(int) 00274 {return getName();} 00275 00276 const char *operator*(); 00277 00278 bool rewind(void); 00279 00280 bool operator!() 00281 #ifndef _MSWINDOWS_ 00282 {return !dir;} 00283 #else 00284 {return hDir != INVALID_HANDLE_VALUE;} 00285 #endif 00286 00287 bool isValid(void); 00288 }; 00289 00296 class __EXPORT DirTree 00297 { 00298 private: 00299 char path[PATH_MAX + 1]; 00300 Dir *dir; 00301 unsigned max, current, prefixpos; 00302 00303 protected: 00313 virtual bool filter(const char *file, struct stat *ino); 00314 00315 public: 00323 DirTree(const char *prefix, unsigned maxdepth); 00324 00330 DirTree(unsigned maxdepth); 00331 00332 virtual ~DirTree(); 00333 00339 void open(const char *prefix); 00340 00344 void close(void); 00345 00353 char *getPath(void); 00354 00364 unsigned perform(const char *prefix); 00365 }; 00366 00377 class __EXPORT RandomFile : protected Mutex, public File 00378 { 00379 private: 00380 Error errid; 00381 char *errstr; 00382 00383 protected: 00384 #ifndef _MSWINDOWS_ 00385 int fd; 00386 // FIXME: WIN32 as no access member 00387 Access access; 00388 #else 00389 HANDLE fd; 00390 #endif 00391 char *pathname; 00392 00393 struct { 00394 unsigned count : 16; 00395 bool thrown : 1; 00396 bool initial : 1; 00397 #ifndef _MSWINDOWS_ 00398 bool immediate : 1; 00399 #endif 00400 bool temp : 1; 00401 } flags; 00402 00406 RandomFile(const char *name = NULL); 00407 00411 RandomFile(const RandomFile &rf); 00412 00420 Error error(Error errid, char *errstr = NULL); 00421 00428 inline Error error(char *err) 00429 {return error(errExtended, err);} 00430 00437 inline void setError(bool enable) 00438 {flags.thrown = !enable;} 00439 00440 #ifndef _MSWINDOWS_ 00441 00448 Error setCompletion(Complete mode); 00449 #endif 00450 00457 inline void setTemporary(bool enable) 00458 {flags.temp = enable;} 00459 00471 virtual Attr initialize(void); 00472 00476 void final(void); 00477 00478 public: 00482 virtual ~RandomFile(); 00483 00492 bool initial(void); 00493 00499 off_t getCapacity(void); 00500 00506 virtual Error restart(void); 00507 00513 inline Error getErrorNumber(void) 00514 {return errid;} 00515 00521 inline char *getErrorString(void) 00522 {return errstr;} 00523 00524 bool operator!(void); 00525 }; 00526 00541 class __EXPORT SharedFile : public RandomFile 00542 { 00543 private: 00544 fcb_t fcb; 00545 Error open(const char *path); 00546 00547 public: 00554 SharedFile(const char *path); 00555 00562 SharedFile(const SharedFile &file); 00563 00567 virtual ~SharedFile(); 00568 00574 Error restart(void) 00575 {return open(pathname);} 00576 00587 Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1); 00588 00599 Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1); 00600 00609 Error clear(ccxx_size_t length = 0, off_t pos = -1); 00610 00617 Error append(caddr_t address = NULL, ccxx_size_t length = 0); 00618 00624 off_t getPosition(void); 00625 00626 bool operator++(void); 00627 bool operator--(void); 00628 }; 00629 00640 class __EXPORT MappedFile : public RandomFile 00641 { 00642 private: 00643 fcb_t fcb; 00644 int prot; 00645 #ifdef _MSWINDOWS_ 00646 HANDLE map; 00647 char mapname[64]; 00648 #endif 00649 00650 public: 00658 MappedFile(const char *fname, Access mode); 00659 00668 MappedFile(const char *fname, Access mode, size_t size); 00669 00680 MappedFile(const char *fname, pos_t offset, size_t size, Access mode); 00681 00686 virtual ~MappedFile(); 00687 00688 // FIXME: not use library function in header ?? 00694 void sync(void); 00695 00702 void sync(caddr_t address, size_t len); 00703 00712 void update(size_t offset = 0, size_t len = 0); 00713 00721 void update(caddr_t address, size_t len); 00722 00729 void release(caddr_t address, size_t len); 00730 00739 inline caddr_t fetch(size_t offset = 0) 00740 {return ((char *)(fcb.address)) + offset;} 00741 00750 caddr_t fetch(off_t pos, size_t len); 00751 00757 bool lock(void); 00758 00762 void unlock(void); 00763 00770 size_t pageAligned(size_t size); 00771 }; 00772 00773 00782 class __EXPORT DSO 00783 { 00784 private: 00785 const char *err; 00786 static Mutex mutex; 00787 static DSO *first; 00788 static DSO *last; 00789 DSO *next, *prev; 00790 const char *id; 00791 void *image; 00792 00793 typedef ucommon::dso::addr_t addr_t; 00794 00795 protected: 00796 void loader(const char *filename, bool resolve); 00797 00798 public: 00804 DSO(const char *filename) 00805 {loader(filename, true);} 00806 00807 DSO(const char *filename, bool resolve) 00808 {loader(filename, resolve);} 00809 00814 inline const char *getError(void) 00815 {return err;} 00816 00820 virtual ~DSO(); 00821 00825 addr_t operator[](const char *sym); 00826 00827 static void dynunload(void); 00828 00834 static DSO *getObject(const char *name); 00835 00841 bool isValid(void); 00842 00846 static void setDebug(void); 00847 }; 00848 00850 bool __EXPORT isDir(const char *path); 00852 bool __EXPORT isFile(const char *path); 00853 #ifndef WIN32 00854 00855 bool __EXPORT isDevice(const char *path); 00856 #else 00857 00858 inline bool isDevice(const char *path) 00859 { return false; } 00860 #endif 00861 00862 bool __EXPORT canAccess(const char *path); 00864 bool __EXPORT canModify(const char *path); 00866 time_t __EXPORT lastModified(const char *path); 00868 time_t __EXPORT lastAccessed(const char *path); 00869 00870 #ifdef COMMON_STD_EXCEPTION 00871 00872 class DirException : public IOException 00873 { 00874 public: 00875 DirException(const String &str) : IOException(str) {}; 00876 }; 00877 00878 class __EXPORT DSOException : public IOException 00879 { 00880 public: 00881 DSOException(const String &str) : IOException(str) {}; 00882 }; 00883 00884 class __EXPORT FileException : public IOException 00885 { 00886 public: 00887 FileException(const String &str) : IOException(str) {}; 00888 }; 00889 00890 #endif 00891 00892 } // namespace ost 00893 00894 #endif 00895