Blame src/filestorage.h

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