Blame src/filestorage.h

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