| // Copyright (C) 1999-2005 Open Source Telecom Corporation. |
| // Copyright (C) 2006-2010 David Sugar, Tycho Softworks. |
| // |
| // This program is free software; you can redistribute it and/or modify |
| // it under the terms of the GNU General Public License as published by |
| // the Free Software Foundation; either version 2 of the License, or |
| // (at your option) any later version. |
| // |
| // This program is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU General Public License for more details. |
| // |
| // You should have received a copy of the GNU General Public License |
| // along with this program; if not, write to the Free Software |
| // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| // |
| // As a special exception, you may use this file as part of a free software |
| // library without restriction. Specifically, if other files instantiate |
| // templates or use macros or inline functions from this file, or you compile |
| // this file and link it with other files to produce an executable, this |
| // file does not by itself cause the resulting executable to be covered by |
| // the GNU General Public License. This exception does not however |
| // invalidate any other reasons why the executable file might be covered by |
| // the GNU General Public License. |
| // |
| // This exception applies only to the code released under the name GNU |
| // Common C++. If you copy code from other releases into a copy of GNU |
| // Common C++, as the General Public License permits, the exception does |
| // not apply to the code that you add in this way. To avoid misleading |
| // anyone as to the status of such modified files, you must delete |
| // this exception notice from them. |
| // |
| // If you write modifications of your own for GNU Common C++, it is your choice |
| // whether to permit this exception to apply to your modifications. |
| // If you do not wish that, delete this exception notice. |
| // |
| |
| /** |
| * @file file.h |
| * @short Files and dynamic loader services. |
| **/ |
| |
| #ifndef COMMONCPP_FILE_H_ |
| #define COMMONCPP_FILE_H_ |
| |
| #ifndef COMMONCPP_CONFIG_H_ |
| #include <commoncpp/config.h> |
| #endif |
| |
| #ifndef COMMONCPP_THREAD_H_ |
| #include <commoncpp/thread.h> |
| #endif |
| |
| #ifndef COMMONCPP_EXCEPTION_H_ |
| #include <commoncpp/exception.h> |
| #endif |
| |
| #ifndef WIN32 |
| # ifdef __BORLANDC__ |
| # include <stdio.h> |
| # include <sys/types.h> |
| # else |
| # include <fcntl.h> |
| # include <cstdio> |
| # endif |
| # include <dirent.h> |
| # include <sys/stat.h> |
| # include <sys/mman.h> |
| #else |
| # if __BORLANDC__ >= 0x0560 |
| # include <dirent.h> |
| # include <sys/stat.h> |
| # else |
| # include <direct.h> |
| # endif |
| #endif |
| |
| NAMESPACE_COMMONCPP |
| |
| typedef unsigned long pos_t; |
| #ifndef _MSWINDOWS_ |
| // use a define so that if the sys/types.h header already defines caddr_t |
| // as it may on BSD systems, we do not break it by redefining again. |
| #undef caddr_t |
| #define caddr_t char * |
| typedef size_t ccxx_size_t; |
| #else |
| typedef DWORD ccxx_size_t; |
| #endif |
| |
| #ifndef PATH_MAX |
| #define PATH_MAX 256 |
| #endif |
| |
| #ifndef NAME_MAX |
| #define NAME_MAX 64 |
| #endif |
| |
| class __EXPORT File |
| { |
| public: |
| enum Error { |
| errSuccess = 0, |
| errNotOpened, |
| errMapFailed, |
| errInitFailed, |
| errOpenDenied, |
| errOpenFailed, |
| errOpenInUse, |
| errReadInterrupted, |
| errReadIncomplete, |
| errReadFailure, |
| errWriteInterrupted, |
| errWriteIncomplete, |
| errWriteFailure, |
| errLockFailure, |
| errExtended |
| }; |
| typedef enum Error Error; |
| |
| enum Access { |
| #ifndef _MSWINDOWS_ |
| accessReadOnly = O_RDONLY, |
| accessWriteOnly= O_WRONLY, |
| accessReadWrite = O_RDWR |
| #else |
| accessReadOnly = GENERIC_READ, |
| accessWriteOnly = GENERIC_WRITE, |
| accessReadWrite = GENERIC_READ | GENERIC_WRITE |
| #endif |
| }; |
| typedef enum Access Access; |
| |
| protected: |
| typedef struct _fcb { |
| struct _fcb *next; |
| caddr_t address; |
| ccxx_size_t len; |
| off_t pos; |
| bool locked; |
| } fcb_t; |
| |
| public: |
| #ifdef _MSWINDOWS_ |
| enum Open { |
| openReadOnly, // = FILE_OPEN_READONLY, |
| openWriteOnly, // = FILE_OPEN_WRITEONLY, |
| openReadWrite, // = FILE_OPEN_READWRITE, |
| openAppend, // = FILE_OPEN_APPEND, |
| openTruncate // = FILE_OPEN_TRUNCATE |
| }; |
| #else |
| enum Open { |
| openReadOnly = O_RDONLY, |
| openWriteOnly = O_WRONLY, |
| openReadWrite = O_RDWR, |
| openAppend = O_WRONLY | O_APPEND, |
| #ifdef O_SYNC |
| openSync = O_RDWR | O_SYNC, |
| #else |
| openSync = O_RDWR, |
| #endif |
| openTruncate = O_RDWR | O_TRUNC |
| }; |
| typedef enum Open Open; |
| |
| /* to be used in future */ |
| |
| #ifndef S_IRUSR |
| #define S_IRUSR 0400 |
| #define S_IWUSR 0200 |
| #define S_IRGRP 0040 |
| #define S_IWGRP 0020 |
| #define S_IROTH 0004 |
| #define S_IWOTH 0002 |
| #endif |
| |
| #endif // !WIN32 |
| |
| #ifndef _MSWINDOWS_ |
| enum Attr { |
| attrInvalid = 0, |
| attrPrivate = S_IRUSR | S_IWUSR, |
| attrGroup = attrPrivate | S_IRGRP | S_IWGRP, |
| attrPublic = attrGroup | S_IROTH | S_IWOTH |
| }; |
| #else // defined WIN32 |
| enum Attr { |
| attrInvalid=0, |
| attrPrivate, |
| attrGroup, |
| attrPublic |
| }; |
| #endif // !WIN32 |
| typedef enum Attr Attr; |
| |
| #ifdef _MSWINDOWS_ |
| enum Complete { |
| completionImmediate, // = FILE_COMPLETION_IMMEDIATE, |
| completionDelayed, // = FILE_COMPLETION_DELAYED, |
| completionDeferred // = FILE_COMPLETION_DEFERRED |
| }; |
| |
| enum Mapping { |
| mappedRead, |
| mappedWrite, |
| mappedReadWrite |
| }; |
| #else |
| enum Mapping { |
| mappedRead = accessReadOnly, |
| mappedWrite = accessWriteOnly, |
| mappedReadWrite = accessReadWrite |
| }; |
| enum Complete { |
| completionImmediate, |
| completionDelayed, |
| completionDeferred |
| }; |
| #endif |
| typedef enum Complete Complete; |
| typedef enum Mapping Mapping; |
| |
| public: |
| static const char *getExtension(const char *path); |
| static const char *getFilename(const char *path); |
| static char *getFilename(const char *path, char *buffer, size_t size = NAME_MAX); |
| static char *getDirname(const char *path, char *buffer, size_t size = PATH_MAX); |
| static char *getRealpath(const char *path, char *buffer, size_t size = PATH_MAX); |
| }; |
| |
| /** |
| * A low level portable directory class. Used to support ccstd Directory |
| * container. This provides a basic mechanism for allocating and |
| * accessing file entries. |
| * |
| * @author David Sugar <dyfet@ostel.com> |
| * @short low level directory access class. |
| */ |
| class __EXPORT Dir : public File |
| { |
| private: |
| #ifndef _MSWINDOWS_ |
| DIR *dir; |
| struct dirent *save; |
| char save_space[sizeof(struct dirent) + PATH_MAX + 1]; |
| struct dirent *entry; |
| #else |
| HANDLE hDir; |
| WIN32_FIND_DATA data, fdata; |
| char *name; |
| #endif |
| |
| public: |
| Dir(const char *name = NULL); |
| |
| static bool create(const char *path, Attr attr = attrGroup); |
| static bool remove(const char *path); |
| static bool setPrefix(const char *path); |
| static bool getPrefix(char *path, size_t size = PATH_MAX); |
| |
| void open(const char *name); |
| void close(void); |
| |
| virtual ~Dir(); |
| |
| const char *getName(void); |
| |
| const char *operator++() |
| {return getName();}; |
| |
| const char *operator++(int) |
| {return getName();}; |
| |
| const char *operator*(); |
| |
| bool rewind(void); |
| |
| bool operator!() |
| #ifndef _MSWINDOWS_ |
| {return !dir;}; |
| #else |
| {return hDir != INVALID_HANDLE_VALUE;}; |
| #endif |
| |
| bool isValid(void); |
| }; |
| |
| /** |
| * A generic class to walk a hierarchical directory structure. |
| * |
| * @author David Sugar <dyfet@ostel.com> |
| * @short Directory tree walking. |
| */ |
| class __EXPORT DirTree |
| { |
| private: |
| char path[PATH_MAX + 1]; |
| Dir *dir; |
| unsigned max, current, prefixpos; |
| |
| protected: |
| /** |
| * Virtual method to filter results. Virtual override methods |
| * should call baseclass method to assure . and .. names are |
| * stripped out. |
| * |
| * @return true if current filename is accepted. |
| * @param file path to examine |
| * @param ino info of type, date, etc. |
| */ |
| virtual bool filter(const char *file, struct stat *ino); |
| |
| public: |
| /** |
| * Construct a directory tree walk starting at the specified |
| * prefix. A maximum subdirectory depth is also specified. |
| * |
| * @param prefix to start walk. |
| * @param maxdepth subdirectory depth to examine. |
| */ |
| DirTree(const char *prefix, unsigned maxdepth); |
| |
| /** |
| * Construct an un-opened directory tree of a known maximum depth |
| * |
| * @param maxdepth subdirectory subdirectory depth. |
| */ |
| DirTree(unsigned maxdepth); |
| |
| virtual ~DirTree(); |
| |
| /** |
| * Open a directory tree path. |
| * |
| * @param prefix directory path to open. |
| */ |
| void open(const char *prefix); |
| |
| /** |
| * Close the directory path. |
| */ |
| void close(void); |
| |
| /** |
| * Extract the next full pathname from the directory walk. |
| * When returning directories, a '/' is appended. The |
| * returned string is a buffer of MAX_PATH size. |
| * |
| * @return path of next subdirectory entry or NULL. |
| */ |
| char *getPath(void); |
| |
| /** |
| * This is used to step through the filter virtual for an |
| * entire subtree, and is used for cases where a derived |
| * DirTree class performs it's primary operations through |
| * filter rather than externally by calling getPath(). |
| * |
| * @return number of files and directories examined. |
| * @param prefix directory path to examine. |
| */ |
| unsigned perform(const char *prefix); |
| }; |
| |
| /** |
| * The purpose of this class is to define a base class for low level |
| * random file access that is portable between Win32 and Posix systems. |
| * This class is a foundation both for optimized thread shared and |
| * traditional locked file access that is commonly used to build |
| * database services, rather than the standard C++ streaming file classes. |
| * |
| * @author David Sugar <dyfet@ostel.com> |
| * @short Portable random disk file access. |
| */ |
| class __EXPORT RandomFile : protected Mutex, public File |
| { |
| private: |
| Error errid; |
| char *errstr; |
| |
| protected: |
| #ifndef _MSWINDOWS_ |
| int fd; |
| // FIXME: WIN32 as no access member |
| Access access; |
| #else |
| HANDLE fd; |
| #endif |
| char *pathname; |
| |
| struct { |
| unsigned count : 16; |
| bool thrown : 1; |
| bool initial : 1; |
| #ifndef _MSWINDOWS_ |
| bool immediate : 1; |
| #endif |
| bool temp : 1; |
| } flags; |
| |
| /** |
| * Create an unopened random access file. |
| */ |
| RandomFile(const char *name = NULL); |
| |
| /** |
| * Default copy constructor. |
| */ |
| RandomFile(const RandomFile &rf); |
| |
| /** |
| * Post an error event. |
| * |
| * @return error code. |
| * @param errid error code. |
| * @param errstr error message string. |
| */ |
| Error error(Error errid, char *errstr = NULL); |
| |
| /** |
| * Post an extended string error message. |
| * |
| * @return errExtended. |
| * @param err error string. |
| */ |
| inline Error error(char *err) |
| {return error(errExtended, err);}; |
| |
| /** |
| * Used to enable or disable throwing of exceptions on |
| * errors. |
| * |
| * @param enable true if errors will be thrown. |
| */ |
| inline void setError(bool enable) |
| {flags.thrown = !enable;}; |
| |
| #ifndef _MSWINDOWS_ |
| /** |
| * Used to set file completion modes. |
| * |
| * @return errSuccess if okay. |
| * @param mode completion mode. |
| * @todo implement in win32 |
| */ |
| Error setCompletion(Complete mode); |
| #endif |
| |
| /** |
| * Used to set the temporary attribute for the file. Temporary |
| * files are automatically deleted when closed. |
| * |
| * @param enable true for marking as temporary. |
| */ |
| inline void setTemporary(bool enable) |
| {flags.temp = enable;}; |
| |
| /** |
| * This method is used to initialize a newly created file as |
| * indicated by the "initial" flag. This method also returns |
| * the file access permissions that should be associated with |
| * the file. This method should never be called directly, but |
| * is instead used to impliment the "Initial" method. Typically |
| * one would use this to build an empty database shell when a |
| * previously empty database file is created. |
| * |
| * @return access, or attrInvalid if should be removed. |
| */ |
| virtual Attr initialize(void); |
| |
| /** |
| * Close the file. |
| */ |
| void final(void); |
| |
| public: |
| /** |
| * Destroy a random access file or it's derived class. |
| */ |
| virtual ~RandomFile(); |
| |
| /** |
| * This method should be called right after a RandomFile derived |
| * object has been created. This method will invoke initialize |
| * if the object is newly created, and set file access permissions |
| * appropriately. |
| * |
| * @return true if file had to be initialized. |
| */ |
| bool initial(void); |
| |
| /** |
| * Get current file capacity. |
| * |
| * @return total file size. |
| */ |
| off_t getCapacity(void); |
| |
| /** |
| * This method is commonly used to close and re-open an existing |
| * database. This may be used when the database has been unlinked |
| * and an external process provides a new one to use. |
| */ |
| virtual Error restart(void); |
| |
| /** |
| * Return current error id. |
| * |
| * @return last error identifier set. |
| */ |
| inline Error getErrorNumber(void) |
| {return errid;}; |
| |
| /** |
| * Return current error string. |
| * |
| * @return last error string set. |
| */ |
| inline char *getErrorString(void) |
| {return errstr;}; |
| |
| bool operator!(void); |
| }; |
| |
| /** |
| * This class defines a database I/O file service that can be shared |
| * by multiple processes. Each thread should access a dup of the database |
| * object, and mutex locks can be used to preserve transaction |
| * integrety if multiple threads are used. |
| * |
| * SharedFile is used when a database may be shared between multiple |
| * processes. SharedFile automatically applies low level byte-range "file |
| * locks", and provides an interface to fetch and release byte-range locked |
| * portions of a file. |
| * |
| * @author David Sugar <dyfet@ostel.com> |
| * @short This class defines a database I/O file service that can be shared by multiple processes. |
| */ |
| class __EXPORT SharedFile : public RandomFile |
| { |
| private: |
| fcb_t fcb; |
| Error open(const char *path); |
| |
| public: |
| /** |
| * Open or create a new database file. You should also use |
| * Initial. |
| * |
| * @param path pathname of database to open. |
| */ |
| SharedFile(const char *path); |
| |
| /** |
| * Create a shared file as a duplicate of an existing shared |
| * file. |
| * |
| * @param file original file. |
| */ |
| SharedFile(const SharedFile &file); |
| |
| /** |
| * Close and finish a database file. |
| */ |
| virtual ~SharedFile(); |
| |
| /** |
| * Restart an existing database; close and re-open. |
| * |
| * @return errSuccess if successful. |
| */ |
| Error restart(void) |
| {return open(pathname);}; |
| |
| /** |
| * Lock and Fetch a portion of the file into physical memory. |
| * This can use state information to fetch the current record |
| * multiple times. |
| * |
| * @return errSuccess on success. |
| * @param address address to use, or NULL if same as last I/O. |
| * @param length length to use, or 0 if same as last I/O. |
| * @param position file position to use -1 if same as last I/O. |
| */ |
| Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1); |
| |
| /** |
| * Update a portion of a file from physical memory. This can use |
| * state information to commit the last read record. The current |
| * lock is also cleared. |
| * |
| * @return errSuccess on success. |
| * @param address address to use, or NULL if same as last I/O. |
| * @param length length to use, or 0 if same as last I/O. |
| * @param position file position to use or -1 if same as last I/O. |
| */ |
| Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1); |
| |
| /** |
| * Clear a lock held from a previous fetch operation without |
| * updating. |
| * |
| * @return errSuccess on success. |
| * @param length length to use, or 0 if same as last I/O. |
| * @param pos file position to use or -1 if same as last I/O. |
| */ |
| Error clear(ccxx_size_t length = 0, off_t pos = -1); |
| |
| /** |
| * Add new data to the end of the file. Locks file during append. |
| * |
| * @param address address to use, or NULL if same as last I/O. |
| * @param length length to use, or 0 if same as last I/O. |
| */ |
| Error append(caddr_t address = NULL, ccxx_size_t length = 0); |
| |
| /** |
| * Fetch the current file position marker for this thread. |
| * |
| * @return file position offset. |
| */ |
| off_t getPosition(void); |
| |
| bool operator++(void); |
| bool operator--(void); |
| }; |
| |
| /** |
| * Create and map a disk file into memory. This portable class works |
| * under both Posix via mmap and under the win32 API. A mapped file |
| * can be referenced directly by it's memory segment. One can map |
| * and unmap portions of a file on demand, and update |
| * changed memory pages mapped from files immediately through sync(). |
| * |
| * @author David Sugar <dyfet@ostel.com> |
| * @short Map a named disk file into memory. |
| */ |
| class __EXPORT MappedFile : public RandomFile |
| { |
| private: |
| fcb_t fcb; |
| int prot; |
| #ifdef _MSWINDOWS_ |
| HANDLE map; |
| char mapname[64]; |
| #endif |
| |
| public: |
| /** |
| * Open a file for mapping. More than one segment of a file |
| * may be mapped into seperate regions of memory. |
| * |
| * @param fname file name to access for mapping. |
| * @param mode access mode to map file. |
| */ |
| MappedFile(const char *fname, Access mode); |
| |
| /** |
| * Create if not exists, and map a file of specified size |
| * into memory. |
| * |
| * @param fname file name to access for mapping. |
| * @param mode access mode to map file. |
| * @param size of file to map. |
| */ |
| MappedFile(const char *fname, Access mode, size_t size); |
| |
| /** |
| * Map a portion or all of a specified file in the specified |
| * shared memory access mode. Valid mapping modes include |
| * mappedRead, mappedWrite, and mappedReadWrite. |
| * |
| * @param fname pathname of file to map into memory. |
| * @param offset from start of file to begin mapping in bytes. |
| * @param size of mapped area in bytes. |
| * @param mode to map file. |
| */ |
| MappedFile(const char *fname, pos_t offset, size_t size, Access mode); |
| |
| /** |
| * Release a mapped section of memory associated with a file. The |
| * mapped area is updated back to disk. |
| */ |
| virtual ~MappedFile(); |
| |
| // FIXME: not use library function in header ?? |
| /** |
| * Synchronize the contents of the mapped portion of memory with |
| * the disk file and wait for completion. This assures the memory |
| * mapped from the file is written back. |
| */ |
| void sync(void); |
| |
| /** |
| * Synchronize a segment of memory mapped from a segment fetch. |
| * |
| * @param address memory address to update. |
| * @param len size of segment. |
| */ |
| void sync(caddr_t address, size_t len); |
| |
| /** |
| * Map a portion of the memory mapped from the file back to the |
| * file and do not wait for completion. This is useful when mapping |
| * a database file and updating a single record. |
| * |
| * @param offset offset into the mapped region of memory. |
| * @param len length of partial region (example, record length). |
| */ |
| void update(size_t offset = 0, size_t len = 0); |
| |
| /** |
| * Update a mapped region back to disk as specified by address |
| * and length. |
| * |
| * @param address address of segment. |
| * @param len length of segment. |
| */ |
| void update(caddr_t address, size_t len); |
| |
| /** |
| * Release (unmap) a memory segment. |
| * |
| * @param address address of memory segment to release. |
| * @param len length of memory segment to release. |
| */ |
| void release(caddr_t address, size_t len); |
| |
| /** |
| * Fetch a pointer to an offset within the memory mapped portion |
| * of the disk file. This really is used for convience of matching |
| * operations between Update and Fetch, as one could simply have |
| * accessed the base pointer where the file was mapped directly. |
| * |
| * @param offset from start of mapped memory. |
| */ |
| inline caddr_t fetch(size_t offset = 0) |
| {return ((char *)(fcb.address)) + offset;}; |
| |
| /** |
| * Fetch and map a portion of a disk file to a logical memory |
| * block. |
| * |
| * @return pointer to memory segment. |
| * @param pos offset of file segment to map. |
| * @param len size of memory segment to map. |
| */ |
| caddr_t fetch(off_t pos, size_t len); |
| |
| /** |
| * Lock the currently mapped portion of a file. |
| * |
| * @return true if pages are locked. |
| */ |
| bool lock(void); |
| |
| /** |
| * Unlock a locked mapped portion of a file. |
| */ |
| void unlock(void); |
| |
| /** |
| * Compute map size to aligned page boundry. |
| * |
| * @param size request. |
| * @return page aligned size. |
| */ |
| size_t pageAligned(size_t size); |
| }; |
| |
| |
| /** |
| * The DSO dynamic loader class is used to load object files. On |
| * elf based systems this is typically done with dlopen. A dummy |
| * stub class is generated for non-dl capable systems. |
| * |
| * @author David Sugar <dyfet@ostel.com> |
| * @short Dynamic class file loader. |
| */ |
| class __EXPORT DSO |
| { |
| private: |
| const char *err; |
| static Mutex mutex; |
| static DSO *first; |
| static DSO *last; |
| DSO *next, *prev; |
| const char *id; |
| void *image; |
| |
| typedef ucommon::dso::addr_t addr_t; |
| |
| protected: |
| void loader(const char *filename, bool resolve); |
| |
| public: |
| /** |
| * Construct and load a DSO object file. |
| * |
| * @param filename pathname of object file to load. |
| */ |
| DSO(const char *filename) |
| {loader(filename, true);}; |
| |
| DSO(const char *filename, bool resolve) |
| {loader(filename, resolve);}; |
| |
| /** |
| * Retrieve error indicator associated with DSO failure. This |
| * is often used in catch handlers. |
| */ |
| inline const char *getError(void) |
| {return err;}; |
| |
| /** |
| * Detach a DSO object from running memory. |
| */ |
| virtual ~DSO(); |
| |
| /** |
| * Lookup a symbol in the loaded file. |
| */ |
| addr_t operator[](const char *sym); |
| |
| static void dynunload(void); |
| |
| /** |
| * Find a specific DSO object by filename. |
| * |
| * @param name of DSO object file (partial). |
| */ |
| static DSO *getObject(const char *name); |
| |
| /** |
| * See if DSO object is valid. |
| * |
| * @return true if valid. |
| */ |
| bool isValid(void); |
| |
| /** |
| * Install debug handler... |
| */ |
| static void setDebug(void); |
| }; |
| |
| /** @relates RandomFile */ |
| bool __EXPORT isDir(const char *path); |
| /** @relates RandomFile */ |
| bool __EXPORT isFile(const char *path); |
| #ifndef WIN32 |
| /** @relates RandomFile */ |
| bool __EXPORT isDevice(const char *path); |
| #else |
| /** @relates RandomFile */ |
| inline bool isDevice(const char *path) |
| { return false; } |
| #endif |
| /** @relates RandomFile */ |
| bool __EXPORT canAccess(const char *path); |
| /** @relates RandomFile */ |
| bool __EXPORT canModify(const char *path); |
| /** @relates RandomFile */ |
| time_t __EXPORT lastModified(const char *path); |
| /** @relates RandomFile */ |
| time_t __EXPORT lastAccessed(const char *path); |
| |
| #ifdef COMMON_STD_EXCEPTION |
| |
| class DirException : public IOException |
| { |
| public: |
| DirException(const String &str) : IOException(str) {}; |
| }; |
| |
| class __EXPORT DSOException : public IOException |
| { |
| public: |
| DSOException(const String &str) : IOException(str) {}; |
| }; |
| |
| class __EXPORT FileException : public IOException |
| { |
| public: |
| FileException(const String &str) : IOException(str) {}; |
| }; |
| |
| #endif |
| |
| END_NAMESPACE |
| |
| #endif |
| |
| /** EMACS ** |
| * Local variables: |
| * mode: c++ |
| * c-basic-offset: 4 |
| * End: |
| */ |