UCommon
file.h
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3 // Copyright (C) 2015 Cherokees of Idaho.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free software
19 // library without restriction. Specifically, if other files instantiate
20 // templates or use macros or inline functions from this file, or you compile
21 // this file and link it with other files to produce an executable, this
22 // file does not by itself cause the resulting executable to be covered by
23 // the GNU General Public License. This exception does not however
24 // invalidate any other reasons why the executable file might be covered by
25 // the GNU General Public License.
26 //
27 // This exception applies only to the code released under the name GNU
28 // Common C++. If you copy code from other releases into a copy of GNU
29 // Common C++, as the General Public License permits, the exception does
30 // not apply to the code that you add in this way. To avoid misleading
31 // anyone as to the status of such modified files, you must delete
32 // this exception notice from them.
33 //
34 // If you write modifications of your own for GNU Common C++, it is your choice
35 // whether to permit this exception to apply to your modifications.
36 // If you do not wish that, delete this exception notice.
37 //
38 
44 #ifndef COMMONCPP_FILE_H_
45 #define COMMONCPP_FILE_H_
46 
47 #ifndef COMMONCPP_CONFIG_H_
48 #include <commoncpp/config.h>
49 #endif
50 
51 #ifndef COMMONCPP_THREAD_H_
52 #include <commoncpp/thread.h>
53 #endif
54 
55 #ifndef COMMONCPP_EXCEPTION_H_
56 #include <commoncpp/exception.h>
57 #endif
58 
59 #ifndef WIN32
60 # ifdef __BORLANDC__
61 # include <stdio.h>
62 # include <sys/types.h>
63 # else
64 # include <fcntl.h>
65 # include <cstdio>
66 # endif
67 # include <dirent.h>
68 # include <sys/stat.h>
69 # include <sys/mman.h>
70 #else
71 # if __BORLANDC__ >= 0x0560
72 # include <dirent.h>
73 # include <sys/stat.h>
74 # else
75 # include <direct.h>
76 # endif
77 #endif
78 
79 namespace ost {
80 
81 typedef unsigned long pos_t;
82 #ifndef _MSWINDOWS_
83 // use a define so that if the sys/types.h header already defines caddr_t
84 // as it may on BSD systems, we do not break it by redefining again.
85 #undef caddr_t
86 #define caddr_t char *
87 typedef size_t ccxx_size_t;
88 #else
89 typedef DWORD ccxx_size_t;
90 #endif
91 
92 #ifndef PATH_MAX
93 #define PATH_MAX 256
94 #endif
95 
96 #ifndef NAME_MAX
97 #define NAME_MAX 64
98 #endif
99 
100 class __EXPORT File
101 {
102 public:
103  enum Error {
104  errSuccess = 0,
105  errNotOpened,
106  errMapFailed,
107  errInitFailed,
108  errOpenDenied,
109  errOpenFailed,
110  errOpenInUse,
111  errReadInterrupted,
112  errReadIncomplete,
113  errReadFailure,
114  errWriteInterrupted,
115  errWriteIncomplete,
116  errWriteFailure,
117  errLockFailure,
118  errExtended
119  };
120  typedef enum Error Error;
121 
122  enum Access {
123 #ifndef _MSWINDOWS_
124  accessReadOnly = O_RDONLY,
125  accessWriteOnly= O_WRONLY,
126  accessReadWrite = O_RDWR
127 #else
128  accessReadOnly = GENERIC_READ,
129  accessWriteOnly = GENERIC_WRITE,
130  accessReadWrite = GENERIC_READ | GENERIC_WRITE
131 #endif
132  };
133  typedef enum Access Access;
134 
135 protected:
136  typedef struct _fcb {
137  struct _fcb *next;
138  caddr_t address;
139  ccxx_size_t len;
140  off_t pos;
141  bool locked;
142  } fcb_t;
143 
144 public:
145 #ifdef _MSWINDOWS_
146  enum Open {
147  openReadOnly, // = FILE_OPEN_READONLY,
148  openWriteOnly, // = FILE_OPEN_WRITEONLY,
149  openReadWrite, // = FILE_OPEN_READWRITE,
150  openAppend, // = FILE_OPEN_APPEND,
151  openTruncate // = FILE_OPEN_TRUNCATE
152  };
153 #else
154  enum Open {
155  openReadOnly = O_RDONLY,
156  openWriteOnly = O_WRONLY,
157  openReadWrite = O_RDWR,
158  openAppend = O_WRONLY | O_APPEND,
159 #ifdef O_SYNC
160  openSync = O_RDWR | O_SYNC,
161 #else
162  openSync = O_RDWR,
163 #endif
164  openTruncate = O_RDWR | O_TRUNC
165  };
166  typedef enum Open Open;
167 
168 /* to be used in future */
169 
170 #ifndef S_IRUSR
171 #define S_IRUSR 0400
172 #define S_IWUSR 0200
173 #define S_IRGRP 0040
174 #define S_IWGRP 0020
175 #define S_IROTH 0004
176 #define S_IWOTH 0002
177 #endif
178 
179 #endif // !WIN32
180 
181 #ifndef _MSWINDOWS_
182  enum Attr {
183  attrInvalid = 0,
184  attrPrivate = S_IRUSR | S_IWUSR,
185  attrGroup = attrPrivate | S_IRGRP | S_IWGRP,
186  attrPublic = attrGroup | S_IROTH | S_IWOTH
187  };
188 #else // defined WIN32
189  enum Attr {
190  attrInvalid=0,
191  attrPrivate,
192  attrGroup,
193  attrPublic
194  };
195 #endif // !WIN32
196  typedef enum Attr Attr;
197 
198 #ifdef _MSWINDOWS_
199  enum Complete {
200  completionImmediate, // = FILE_COMPLETION_IMMEDIATE,
201  completionDelayed, // = FILE_COMPLETION_DELAYED,
202  completionDeferred // = FILE_COMPLETION_DEFERRED
203  };
204 
205  enum Mapping {
206  mappedRead,
207  mappedWrite,
208  mappedReadWrite
209  };
210 #else
211  enum Mapping {
212  mappedRead = accessReadOnly,
213  mappedWrite = accessWriteOnly,
214  mappedReadWrite = accessReadWrite
215  };
216  enum Complete {
217  completionImmediate,
218  completionDelayed,
219  completionDeferred
220  };
221 #endif
222  typedef enum Complete Complete;
223  typedef enum Mapping Mapping;
224 
225 public:
226  static const char *getExtension(const char *path);
227  static const char *getFilename(const char *path);
228  static char *getFilename(const char *path, char *buffer, size_t size = NAME_MAX);
229  static char *getDirname(const char *path, char *buffer, size_t size = PATH_MAX);
230  static char *getRealpath(const char *path, char *buffer, size_t size = PATH_MAX);
231 };
232 
241 class __EXPORT Dir : public File
242 {
243 private:
244 #ifndef _MSWINDOWS_
245  DIR *dir;
246  struct dirent *save;
247  char save_space[sizeof(struct dirent) + PATH_MAX + 1];
248  struct dirent *entry;
249 #else
250  HANDLE hDir;
251  WIN32_FIND_DATA data, fdata;
252  char *name;
253 #endif
254 
255  __DELETE_COPY(Dir);
256 
257 public:
258  Dir(const char *name = NULL);
259 
260  static bool create(const char *path, Attr attr = attrGroup);
261  static bool remove(const char *path);
262  static bool setPrefix(const char *path);
263  static bool getPrefix(char *path, size_t size = PATH_MAX);
264 
265  void open(const char *name);
266  void close(void);
267 
268  virtual ~Dir();
269 
270  const char *getName(void);
271 
272  const char *operator++() {
273  return getName();
274  }
275 
276  const char *operator++(int) {
277  return getName();
278  }
279 
280  const char *operator*();
281 
282  bool rewind(void);
283 
284  bool operator!() const {
285 #ifndef _MSWINDOWS_
286  return !dir;
287 #else
288  return hDir == INVALID_HANDLE_VALUE;
289 #endif
290  }
291 
292  operator bool() const {
293 #ifndef _MSWINDOWS_
294  return dir;
295 #else
296  return hDir != INVALID_HANDLE_VALUE;
297 #endif
298  }
299 
300  bool isValid(void) const;
301 };
302 
309 class __EXPORT DirTree
310 {
311 private:
312  char path[PATH_MAX + 1];
313  Dir *dir;
314  unsigned max, current, prefixpos;
315 
316  __DELETE_COPY(DirTree);
317 
318 protected:
328  virtual bool filter(const char *file, struct stat *ino);
329 
330 public:
338  DirTree(const char *prefix, unsigned maxdepth);
339 
345  DirTree(unsigned maxdepth);
346 
347  virtual ~DirTree();
348 
354  void open(const char *prefix);
355 
359  void close(void);
360 
368  char *getPath(void);
369 
379  unsigned perform(const char *prefix);
380 };
381 
392 class __EXPORT RandomFile : protected Mutex, public File
393 {
394 private:
395  Error errid;
396  char *errstr;
397 
398 protected:
399 #ifndef _MSWINDOWS_
400  int fd;
401  // FIXME: WIN32 as no access member
402  Access access;
403 #else
404  HANDLE fd;
405 #endif
406  char *pathname;
407 
408  struct {
409  unsigned count : 16;
410  bool thrown : 1;
411  bool initial : 1;
412 #ifndef _MSWINDOWS_
413  bool immediate : 1;
414 #endif
415  bool temp : 1;
416  } flags;
417 
421  RandomFile(const char *name = NULL);
422 
426  RandomFile(const RandomFile &rf);
427 
435  Error error(Error errid, char *errstr = NULL);
436 
443  inline Error error(char *err) {
444  return error(errExtended, err);
445  }
446 
453  inline void setError(bool enable) {
454  flags.thrown = !enable;
455  }
456 
457 #ifndef _MSWINDOWS_
458 
465  Error setCompletion(Complete mode);
466 #endif
467 
474  inline void setTemporary(bool enable) {
475  flags.temp = enable;
476  }
477 
489  virtual Attr initialize(void);
490 
494  void final(void);
495 
496 public:
500  virtual ~RandomFile();
501 
510  bool initial(void);
511 
517  off_t getCapacity(void);
518 
524  virtual Error restart(void);
525 
531  inline Error getErrorNumber(void) const {
532  return errid;
533  }
534 
540  inline char *getErrorString(void) const {
541  return errstr;
542  }
543 
544  operator bool() const;
545 
546  bool operator!(void) const;
547 };
548 
563 class __EXPORT SharedFile : public RandomFile
564 {
565 private:
566  fcb_t fcb;
567  Error open(const char *path);
568 
569 public:
576  SharedFile(const char *path);
577 
584  SharedFile(const SharedFile &file);
585 
589  virtual ~SharedFile();
590 
596  Error restart(void) {
597  return open(pathname);
598  }
599 
610  Error fetch(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
611 
622  Error update(caddr_t address = NULL, ccxx_size_t length = 0, off_t position = -1);
623 
632  Error clear(ccxx_size_t length = 0, off_t pos = -1);
633 
640  Error append(caddr_t address = NULL, ccxx_size_t length = 0);
641 
647  off_t getPosition(void);
648 
649  bool operator++(void);
650  bool operator--(void);
651 };
652 
663 class __EXPORT MappedFile : public RandomFile
664 {
665 private:
666  fcb_t fcb;
667  int prot;
668 #ifdef _MSWINDOWS_
669  HANDLE map;
670  char mapname[64];
671 #endif
672 
673  __DELETE_COPY(MappedFile);
674 
675 public:
683  MappedFile(const char *fname, Access mode);
684 
693  MappedFile(const char *fname, Access mode, size_t size);
694 
705  MappedFile(const char *fname, pos_t offset, size_t size, Access mode);
706 
711  virtual ~MappedFile();
712 
713  // FIXME: not use library function in header ??
719  void sync(void);
720 
727  void sync(caddr_t address, size_t len);
728 
737  void update(size_t offset = 0, size_t len = 0);
738 
746  void update(caddr_t address, size_t len);
747 
754  void release(caddr_t address, size_t len);
755 
764  inline caddr_t fetch(size_t offset = 0) {
765  return ((char *)(fcb.address)) + offset;
766  }
767 
776  caddr_t fetch(off_t pos, size_t len);
777 
783  bool lock(void);
784 
788  void unlock(void);
789 
796  size_t pageAligned(size_t size);
797 };
798 
799 
808 class __EXPORT DSO
809 {
810 private:
811  const char *err;
812  static Mutex mutex;
813  static DSO *first;
814  static DSO *last;
815  DSO *next, *prev;
816  const char *id;
817  void *image;
818 
819  typedef ucommon::dso::addr_t addr_t;
820 
821  __DELETE_COPY(DSO);
822 
823 protected:
824  void loader(const char *filename, bool resolve);
825 
826 public:
832  DSO(const char *filename) {
833  loader(filename, true);
834  }
835 
836  DSO(const char *filename, bool resolve) {
837  loader(filename, resolve);
838  }
839 
844  inline const char *getError(void) const {
845  return err;
846  }
847 
851  virtual ~DSO();
852 
856  addr_t operator[](const char *sym);
857 
858  static void dynunload(void);
859 
865  static DSO *getObject(const char *name);
866 
872  bool isValid(void);
873 
877  static void setDebug(void);
878 };
879 
881 bool __EXPORT isDir(const char *path);
883 bool __EXPORT isFile(const char *path);
884 #ifndef WIN32
885 
886 bool __EXPORT isDevice(const char *path);
887 #else
888 
889 inline bool isDevice(const char *path) {
890  return false;
891 }
892 #endif
893 
894 bool __EXPORT canAccess(const char *path);
896 bool __EXPORT canModify(const char *path);
898 time_t __EXPORT lastModified(const char *path);
900 time_t __EXPORT lastAccessed(const char *path);
901 
902 #ifdef COMMON_STD_EXCEPTION
903 
904 class DirException : public IOException
905 {
906 public:
907  DirException(const String &str) : IOException(str) {};
908 };
909 
910 class __EXPORT DSOException : public IOException
911 {
912 public:
913  DSOException(const String &str) : IOException(str) {};
914 };
915 
916 class __EXPORT FileException : public IOException
917 {
918 public:
919  FileException(const String &str) : IOException(str) {};
920 };
921 
922 #endif
923 
924 } // namespace ost
925 
926 #endif
927 
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:445
char * getErrorString(void) const
Return current error string.
Definition: file.h:540
The purpose of this class is to define a base class for low level random file access that is portable...
Definition: file.h:392
void setTemporary(bool enable)
Used to set the temporary attribute for the file.
Definition: file.h:474
This class defines a database I/O file service that can be shared by multiple processes.
Definition: file.h:563
A generic class to walk a hierarchical directory structure.
Definition: file.h:309
Common C++ thread class and sychronization objects.
The DSO dynamic loader class is used to load object files.
Definition: file.h:808
AppLog & error(AppLog &sl)
Manipulator for error level.
Definition: applog.h:536
void setError(bool enable)
Used to enable or disable throwing of exceptions on errors.
Definition: file.h:453
DSO(const char *filename)
Construct and load a DSO object file.
Definition: file.h:832
Error error(char *err)
Post an extended string error message.
Definition: file.h:443
Error restart(void)
Restart an existing database; close and re-open.
Definition: file.h:596
A low level portable directory class.
Definition: file.h:241
Error getErrorNumber(void) const
Return current error id.
Definition: file.h:531
Create and map a disk file into memory.
Definition: file.h:663
GNU Common C++ exception model base classes.
const char * getError(void) const
Retrieve error indicator associated with DSO failure.
Definition: file.h:844