ucommon
file.h
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free software
18 // library without restriction. Specifically, if other files instantiate
19 // templates or use macros or inline functions from this file, or you compile
20 // this file and link it with other files to produce an executable, this
21 // file does not by itself cause the resulting executable to be covered by
22 // the GNU General Public License. This exception does not however
23 // invalidate any other reasons why the executable file might be covered by
24 // the GNU General Public License.
25 //
26 // This exception applies only to the code released under the name GNU
27 // Common C++. If you copy code from other releases into a copy of GNU
28 // Common C++, as the General Public License permits, the exception does
29 // not apply to the code that you add in this way. To avoid misleading
30 // anyone as to the status of such modified files, you must delete
31 // this exception notice from them.
32 //
33 // If you write modifications of your own for GNU Common C++, it is your choice
34 // whether to permit this exception to apply to your modifications.
35 // If you do not wish that, delete this exception notice.
36 //
37 
43 #ifndef COMMONCPP_FILE_H_
44 #define COMMONCPP_FILE_H_
45 
46 #ifndef COMMONCPP_CONFIG_H_
47 #include <commoncpp/config.h>
48 #endif
49 
50 #ifndef COMMONCPP_THREAD_H_
51 #include <commoncpp/thread.h>
52 #endif
53 
54 #ifndef COMMONCPP_EXCEPTION_H_
55 #include <commoncpp/exception.h>
56 #endif
57 
58 #ifndef WIN32
59 # ifdef __BORLANDC__
60 # include <stdio.h>
61 # include <sys/types.h>
62 # else
63 # include <fcntl.h>
64 # include <cstdio>
65 # endif
66 # include <dirent.h>
67 # include <sys/stat.h>
68 # include <sys/mman.h>
69 #else
70 # if __BORLANDC__ >= 0x0560
71 # include <dirent.h>
72 # include <sys/stat.h>
73 # else
74 # include <direct.h>
75 # endif
76 #endif
77 
78 NAMESPACE_COMMONCPP
79 
80 typedef unsigned long pos_t;
81 #ifndef _MSWINDOWS_
82 // use a define so that if the sys/types.h header already defines caddr_t
83 // as it may on BSD systems, we do not break it by redefining again.
84 #undef caddr_t
85 #define caddr_t char *
86 typedef size_t ccxx_size_t;
87 #else
88 typedef DWORD ccxx_size_t;
89 #endif
90 
91 #ifndef PATH_MAX
92 #define PATH_MAX 256
93 #endif
94 
95 #ifndef NAME_MAX
96 #define NAME_MAX 64
97 #endif
98 
99 class __EXPORT File
100 {
101 public:
102  enum Error {
103  errSuccess = 0,
104  errNotOpened,
105  errMapFailed,
106  errInitFailed,
107  errOpenDenied,
108  errOpenFailed,
109  errOpenInUse,
110  errReadInterrupted,
111  errReadIncomplete,
112  errReadFailure,
113  errWriteInterrupted,
114  errWriteIncomplete,
115  errWriteFailure,
116  errLockFailure,
117  errExtended
118  };
119  typedef enum Error Error;
120 
121  enum Access {
122 #ifndef _MSWINDOWS_
123  accessReadOnly = O_RDONLY,
124  accessWriteOnly= O_WRONLY,
125  accessReadWrite = O_RDWR
126 #else
127  accessReadOnly = GENERIC_READ,
128  accessWriteOnly = GENERIC_WRITE,
129  accessReadWrite = GENERIC_READ | GENERIC_WRITE
130 #endif
131  };
132  typedef enum Access Access;
133 
134 protected:
135  typedef struct _fcb {
136  struct _fcb *next;
137  caddr_t address;
138  ccxx_size_t len;
139  off_t pos;
140  bool locked;
141  } fcb_t;
142 
143 public:
144 #ifdef _MSWINDOWS_
145  enum Open {
146  openReadOnly, // = FILE_OPEN_READONLY,
147  openWriteOnly, // = FILE_OPEN_WRITEONLY,
148  openReadWrite, // = FILE_OPEN_READWRITE,
149  openAppend, // = FILE_OPEN_APPEND,
150  openTruncate // = FILE_OPEN_TRUNCATE
151  };
152 #else
153  enum Open {
154  openReadOnly = O_RDONLY,
155  openWriteOnly = O_WRONLY,
156  openReadWrite = O_RDWR,
157  openAppend = O_WRONLY | O_APPEND,
158 #ifdef O_SYNC
159  openSync = O_RDWR | O_SYNC,
160 #else
161  openSync = O_RDWR,
162 #endif
163  openTruncate = O_RDWR | O_TRUNC
164  };
165  typedef enum Open Open;
166 
167 /* to be used in future */
168 
169 #ifndef S_IRUSR
170 #define S_IRUSR 0400
171 #define S_IWUSR 0200
172 #define S_IRGRP 0040
173 #define S_IWGRP 0020
174 #define S_IROTH 0004
175 #define S_IWOTH 0002
176 #endif
177 
178 #endif // !WIN32
179 
180 #ifndef _MSWINDOWS_
181  enum Attr {
182  attrInvalid = 0,
183  attrPrivate = S_IRUSR | S_IWUSR,
184  attrGroup = attrPrivate | S_IRGRP | S_IWGRP,
185  attrPublic = attrGroup | S_IROTH | S_IWOTH
186  };
187 #else // defined WIN32
188  enum Attr {
189  attrInvalid=0,
190  attrPrivate,
191  attrGroup,
192  attrPublic
193  };
194 #endif // !WIN32
195  typedef enum Attr Attr;
196 
197 #ifdef _MSWINDOWS_
198  enum Complete {
199  completionImmediate, // = FILE_COMPLETION_IMMEDIATE,
200  completionDelayed, // = FILE_COMPLETION_DELAYED,
201  completionDeferred // = FILE_COMPLETION_DEFERRED
202  };
203 
204  enum Mapping {
205  mappedRead,
206  mappedWrite,
207  mappedReadWrite
208  };
209 #else
210  enum Mapping {
211  mappedRead = accessReadOnly,
212  mappedWrite = accessWriteOnly,
213  mappedReadWrite = accessReadWrite
214  };
215  enum Complete {
216  completionImmediate,
217  completionDelayed,
218  completionDeferred
219  };
220 #endif
221  typedef enum Complete Complete;
222  typedef enum Mapping Mapping;
223 
224 public:
225  static const char *getExtension(const char *path);
226  static const char *getFilename(const char *path);
227  static char *getFilename(const char *path, char *buffer, size_t size = NAME_MAX);
228  static char *getDirname(const char *path, char *buffer, size_t size = PATH_MAX);
229  static char *getRealpath(const char *path, char *buffer, size_t size = PATH_MAX);
230 };
231 
240 class __EXPORT Dir : public File
241 {
242 private:
243 #ifndef _MSWINDOWS_
244  DIR *dir;
245  struct dirent *save;
246  char save_space[sizeof(struct dirent) + PATH_MAX + 1];
247  struct dirent *entry;
248 #else
249  HANDLE hDir;
250  WIN32_FIND_DATA data, fdata;
251  char *name;
252 #endif
253 
254 public:
255  Dir(const char *name = NULL);
256 
257  static bool create(const char *path, Attr attr = attrGroup);
258  static bool remove(const char *path);
259  static bool setPrefix(const char *path);
260  static bool getPrefix(char *path, size_t size = PATH_MAX);
261 
262  void open(const char *name);
263  void close(void);
264 
265  virtual ~Dir();
266 
267  const char *getName(void);
268 
269  const char *operator++()
270  {return getName();};
271 
272  const char *operator++(int)
273  {return getName();};
274 
275  const char *operator*();
276 
277  bool rewind(void);
278 
279  bool operator!()
280 #ifndef _MSWINDOWS_
281  {return !dir;};
282 #else
283  {return hDir != INVALID_HANDLE_VALUE;};
284 #endif
285 
286  bool isValid(void);
287 };
288 
295 class __EXPORT DirTree
296 {
297 private:
298  char path[PATH_MAX + 1];
299  Dir *dir;
300  unsigned max, current, prefixpos;
301 
302 protected:
312  virtual bool filter(const char *file, struct stat *ino);
313 
314 public:
322  DirTree(const char *prefix, unsigned maxdepth);
323 
329  DirTree(unsigned maxdepth);
330 
331  virtual ~DirTree();
332 
338  void open(const char *prefix);
339 
343  void close(void);
344 
352  char *getPath(void);
353 
363  unsigned perform(const char *prefix);
364 };
365 
376 class __EXPORT RandomFile : protected Mutex, public File
377 {
378 private:
379  Error errid;
380  char *errstr;
381 
382 protected:
383 #ifndef _MSWINDOWS_
384  int fd;
385  // FIXME: WIN32 as no access member
386  Access access;
387 #else
388  HANDLE fd;
389 #endif
390  char *pathname;
391 
392  struct {
393  unsigned count : 16;
394  bool thrown : 1;
395  bool initial : 1;
396 #ifndef _MSWINDOWS_
397  bool immediate : 1;
398 #endif
399  bool temp : 1;
400  } flags;
401 
405  RandomFile(const char *name = NULL);
406 
410  RandomFile(const RandomFile &rf);
411 
419  Error error(Error errid, char *errstr = NULL);
420 
427  inline Error error(char *err)
428  {return error(errExtended, err);};
429 
436  inline void setError(bool enable)
437  {flags.thrown = !enable;};
438 
439 #ifndef _MSWINDOWS_
440 
447  Error setCompletion(Complete mode);
448 #endif
449 
456  inline void setTemporary(bool enable)
457  {flags.temp = enable;};
458 
470  virtual Attr initialize(void);
471 
475  void final(void);
476 
477 public:
481  virtual ~RandomFile();
482 
491  bool initial(void);
492 
498  off_t getCapacity(void);
499 
505  virtual Error restart(void);
506 
512  inline Error getErrorNumber(void)
513  {return errid;};
514 
520  inline char *getErrorString(void)
521  {return errstr;};
522 
523  bool operator!(void);
524 };
525 
540 class __EXPORT SharedFile : public RandomFile
541 {
542 private:
543  fcb_t fcb;
544  Error open(const char *path);
545 
546 public:
553  SharedFile(const char *path);
554 
561  SharedFile(const SharedFile &file);
562 
566  virtual ~SharedFile();
567 
573  Error restart(void)
574  {return open(pathname);};
575 
586  Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
587 
598  Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
599 
608  Error clear(ccxx_size_t length = 0, off_t pos = -1);
609 
616  Error append(caddr_t address = NULL, ccxx_size_t length = 0);
617 
623  off_t getPosition(void);
624 
625  bool operator++(void);
626  bool operator--(void);
627 };
628 
639 class __EXPORT MappedFile : public RandomFile
640 {
641 private:
642  fcb_t fcb;
643  int prot;
644 #ifdef _MSWINDOWS_
645  HANDLE map;
646  char mapname[64];
647 #endif
648 
649 public:
657  MappedFile(const char *fname, Access mode);
658 
667  MappedFile(const char *fname, Access mode, size_t size);
668 
679  MappedFile(const char *fname, pos_t offset, size_t size, Access mode);
680 
685  virtual ~MappedFile();
686 
687  // FIXME: not use library function in header ??
693  void sync(void);
694 
701  void sync(caddr_t address, size_t len);
702 
711  void update(size_t offset = 0, size_t len = 0);
712 
720  void update(caddr_t address, size_t len);
721 
728  void release(caddr_t address, size_t len);
729 
738  inline caddr_t fetch(size_t offset = 0)
739  {return ((char *)(fcb.address)) + offset;};
740 
749  caddr_t fetch(off_t pos, size_t len);
750 
756  bool lock(void);
757 
761  void unlock(void);
762 
769  size_t pageAligned(size_t size);
770 };
771 
772 
781 class __EXPORT DSO
782 {
783 private:
784  const char *err;
785  static Mutex mutex;
786  static DSO *first;
787  static DSO *last;
788  DSO *next, *prev;
789  const char *id;
790  void *image;
791 
792  typedef ucommon::dso::addr_t addr_t;
793 
794 protected:
795  void loader(const char *filename, bool resolve);
796 
797 public:
803  DSO(const char *filename)
804  {loader(filename, true);};
805 
806  DSO(const char *filename, bool resolve)
807  {loader(filename, resolve);};
808 
813  inline const char *getError(void)
814  {return err;};
815 
819  virtual ~DSO();
820 
824  addr_t operator[](const char *sym);
825 
826  static void dynunload(void);
827 
833  static DSO *getObject(const char *name);
834 
840  bool isValid(void);
841 
845  static void setDebug(void);
846 };
847 
849 bool __EXPORT isDir(const char *path);
851 bool __EXPORT isFile(const char *path);
852 #ifndef WIN32
853 
854 bool __EXPORT isDevice(const char *path);
855 #else
856 
857 inline bool isDevice(const char *path)
858 { return false; }
859 #endif
860 
861 bool __EXPORT canAccess(const char *path);
863 bool __EXPORT canModify(const char *path);
865 time_t __EXPORT lastModified(const char *path);
867 time_t __EXPORT lastAccessed(const char *path);
868 
869 #ifdef COMMON_STD_EXCEPTION
870 
871 class DirException : public IOException
872 {
873 public:
874  DirException(const String &str) : IOException(str) {};
875 };
876 
877 class __EXPORT DSOException : public IOException
878 {
879 public:
880  DSOException(const String &str) : IOException(str) {};
881 };
882 
883 class __EXPORT FileException : public IOException
884 {
885 public:
886  FileException(const String &str) : IOException(str) {};
887 };
888 
889 #endif
890 
891 END_NAMESPACE
892 
893 #endif
894 
Common C++ thread class and sychronization objects.
Create and map a disk file into memory.
Definition: file.h:639
bool canAccess(const char *path)
void setTemporary(bool enable)
Used to set the temporary attribute for the file.
Definition: file.h:456
void unlock(void)
Unlock the conditional&#39;s supporting mutex.
Definition: thread.h:154
void release(void)
Release or decrease locking.
DSO(const char *filename)
Construct and load a DSO object file.
Definition: file.h:803
void setError(bool enable)
Used to enable or disable throwing of exceptions on errors.
Definition: file.h:436
bool canModify(const char *path)
time_t lastAccessed(const char *path)
Error restart(void)
Restart an existing database; close and re-open.
Definition: file.h:573
char * fetch(size_t offset=0)
Fetch a pointer to an offset within the memory mapped portion of the disk file.
Definition: file.h:738
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:543
A generic class to walk a hierarchical directory structure.
Definition: file.h:295
bool isDevice(const char *path)
void lock(void)
Acquire or increase locking.
bool isFile(const char *path)
Error error(char *err)
Post an extended string error message.
Definition: file.h:427
The purpose of this class is to define a base class for low level random file access that is portable...
Definition: file.h:376
The DSO dynamic loader class is used to load object files.
Definition: file.h:781
const char * getError(void)
Retrieve error indicator associated with DSO failure.
Definition: file.h:813
A low level portable directory class.
Definition: file.h:240
This class defines a database I/O file service that can be shared by multiple processes.
Definition: file.h:540
bool isDir(const char *path)
Error getErrorNumber(void)
Return current error id.
Definition: file.h:512
void access(SharedAccess &object)
Convenience function to access (lock) shared object through it&#39;s protocol.
Definition: access.h:253
time_t lastModified(const char *path)
char * getErrorString(void)
Return current error string.
Definition: file.h:520
GNU Common C++ exception model base classes.