My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
filestorage.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2015 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 
16 #include <qfile.h>
17 #include <assert.h>
18 #include "store.h"
19 
20 
21 #ifndef FILESTORAGE_H
22 #define FILESTORAGE_H
23 
28 class FileStorage : public StorageIntf
29 {
30  public:
31  FileStorage() : m_readOnly(FALSE) {}
32  FileStorage( const QString &name) :
33  m_readOnly(FALSE) { m_file.setName(name); }
34  int read(char *buf,uint size) { return m_file.readBlock(buf,size); }
35  int write(const char *buf,uint size) { assert(m_readOnly==FALSE); return m_file.writeBlock(buf,size); }
36  bool open( int m ) { m_readOnly = m==IO_ReadOnly; return m_file.open(m); }
37  bool seek(int64 pos) { return m_file.seek(pos); }
38  int64 pos() const { return m_file.pos(); }
39  void close() { m_file.close(); }
40  void setName( const char *name ) { m_file.setName(name); }
41  private:
42  bool m_readOnly;
43  QFile m_file;
44 };
45 
46 #if 0 // experimental version using mmap after opening the file as read only.
47 #include <sys/mman.h>
48 #include <sys/stat.h>
49 #include <fcntl.h>
50 #include <string.h>
51 #include <unistd.h>
52 #include <stdio.h>
53 
54 class FileStorage : public StorageIntf
55 {
56  public:
57  FileStorage() : m_readOnly(FALSE), m_map(0), m_off(0), m_size(0) {}
58  FileStorage( const QString &name) :
59  m_readOnly(FALSE) { m_file.setName(name); }
60  void setName( const char *name ) { m_file.setName(name); }
61  bool open( int m )
62  {
63  if (m==IO_ReadOnly)
64  {
65  m_readOnly=TRUE;
66  QString name = m_file.name();
67  m_file.close();
68  m_fd = ::open(name.data(),O_RDONLY);
69  struct stat stat;
70  fstat(m_fd,&stat);
71  m_size = stat.st_size;
72  m_map = mmap(NULL,m_size,PROT_READ,MAP_SHARED,m_fd,0);
73  if (m_map==MAP_FAILED) perror("mmap failed");
74  assert(m_map!=MAP_FAILED);
75  m_off = 0;
76  return TRUE;
77  }
78  else
79  {
80  m_readOnly = FALSE;
81  return m_file.open(m);
82  }
83  }
84  int write(const char *buf,uint size)
85  {
86  assert(m_map==0);
87  return m_file.writeBlock(buf,size);
88  }
89  int read(char *buf,uint size)
90  {
91  assert(m_map!=0);
92  memcpy(buf,((char *)m_map)+m_off,size);
93  m_off+=size;
94  return size;
95  }
96  bool seek(int64 pos)
97  {
98  m_off=pos;
99  return TRUE;
100  }
101  int64 pos() const
102  {
103  if (m_readOnly)
104  {
105  return m_off;
106  }
107  else
108  {
109  return m_file.pos();
110  }
111  }
112  void close()
113  {
114  if (m_readOnly)
115  {
116  munmap(m_map,m_size);
117  ::close(m_fd);
118  exit(1);
119  }
120  else
121  {
122  m_file.close();
123  }
124  }
125  private:
126  bool m_readOnly;
127  QFile m_file;
128  int m_fd;
129  void *m_map;
130  off_t m_off;
131  off_t m_size;
132 };
133 #endif
134 
135 #endif