summaryrefslogtreecommitdiffstats
path: root/src/filestorage.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/filestorage.h')
-rw-r--r--src/filestorage.h135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/filestorage.h b/src/filestorage.h
new file mode 100644
index 0000000..17d4498
--- /dev/null
+++ b/src/filestorage.h
@@ -0,0 +1,135 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2011 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qfile.h>
+#include <assert.h>
+#include "store.h"
+
+
+#ifndef FILESTORAGE_H
+#define FILESTORAGE_H
+
+/** @brief Store implementation based on a file.
+ Writing is linear, after that the file is re-opened for reading.
+ Reading is random (seek+read).
+ */
+class FileStorage : public StorageIntf
+{
+ public:
+ FileStorage() : m_readOnly(FALSE) {}
+ FileStorage( const QString &name) :
+ m_readOnly(FALSE) { m_file.setName(name); }
+ int read(char *buf,uint size) { return m_file.readBlock(buf,size); }
+ int write(const char *buf,uint size) { assert(m_readOnly==FALSE); return m_file.writeBlock(buf,size); }
+ bool open( int m ) { m_readOnly = m==IO_ReadOnly; return m_file.open(m); }
+ bool seek(int64 pos) { return m_file.seek(pos); }
+ int64 pos() const { return m_file.pos(); }
+ void close() { m_file.close(); }
+ void setName( const char *name ) { m_file.setName(name); }
+ private:
+ bool m_readOnly;
+ QFile m_file;
+};
+
+#if 0 // experimental version using mmap after opening the file as read only.
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+class FileStorage : public StorageIntf
+{
+ public:
+ FileStorage() : m_readOnly(FALSE), m_map(0), m_off(0), m_size(0) {}
+ FileStorage( const QString &name) :
+ m_readOnly(FALSE) { m_file.setName(name); }
+ void setName( const char *name ) { m_file.setName(name); }
+ bool open( int m )
+ {
+ if (m==IO_ReadOnly)
+ {
+ m_readOnly=TRUE;
+ QString name = m_file.name();
+ m_file.close();
+ m_fd = ::open(name.data(),O_RDONLY);
+ struct stat stat;
+ fstat(m_fd,&stat);
+ m_size = stat.st_size;
+ m_map = mmap(NULL,m_size,PROT_READ,MAP_SHARED,m_fd,0);
+ if (m_map==MAP_FAILED) perror("mmap failed");
+ assert(m_map!=MAP_FAILED);
+ m_off = 0;
+ return TRUE;
+ }
+ else
+ {
+ m_readOnly = FALSE;
+ return m_file.open(m);
+ }
+ }
+ int write(const char *buf,uint size)
+ {
+ assert(m_map==0);
+ return m_file.writeBlock(buf,size);
+ }
+ int read(char *buf,uint size)
+ {
+ assert(m_map!=0);
+ memcpy(buf,((char *)m_map)+m_off,size);
+ m_off+=size;
+ return size;
+ }
+ bool seek(int64 pos)
+ {
+ m_off=pos;
+ return TRUE;
+ }
+ int64 pos() const
+ {
+ if (m_readOnly)
+ {
+ return m_off;
+ }
+ else
+ {
+ return m_file.pos();
+ }
+ }
+ void close()
+ {
+ if (m_readOnly)
+ {
+ munmap(m_map,m_size);
+ ::close(m_fd);
+ exit(1);
+ }
+ else
+ {
+ m_file.close();
+ }
+ }
+ private:
+ bool m_readOnly;
+ QFile m_file;
+ int m_fd;
+ void *m_map;
+ off_t m_off;
+ off_t m_size;
+};
+#endif
+
+#endif