store.h 3.42 KB
Newer Older
1 2
/******************************************************************************
 *
3
 * 
4
 *
Dimitri van Heesch's avatar
Dimitri van Heesch committed
5
 * Copyright (C) 1997-2013 by Dimitri van Heesch.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * 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.
 *
 */

#ifndef STORE_H
#define STORE_H

#include <qglobal.h>
#include <stdio.h>
23 24

#include "portable.h"
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

/*! @brief Abstract interface for file based memory storage operations */
class StorageIntf
{
  public:
    /*! Required by gcc */
    virtual ~StorageIntf() {}
    /*! Read \a size bytes from the store into \a buf. */
    virtual int read(char *buf,uint size) = 0;
    /*! Write \a size bytes from \a buf into the store. */
    virtual int write(const char *buf,uint size) = 0;
};

/*! @brief The Store is a file based memory manager.
 *
 *  You can open the store using open(). Then obtain a handle via alloc()
 *  followed by a sequence of write() commands to store information,
 *  and finalize it using end(). 
 *  
 *  Later on you locate the information
 *  with seek() using the handle obtained with alloc(), and then use a
 *  sequence of read() calls to read the information back. 
 *
 *  If no longer needed the storage space can be freed using release().
 *  
 *  The store will dynamically grow the file on disk if needed.
 */
class Store : public StorageIntf
{
  public:
    /*! Creates a store. */
    Store();

    /*! Releases the store object. Will close the underlying file if opened. */
   ~Store();

    /*! Opens the file underlying the store using \a name as the file name. 
     *  Returns 0 upon success, or -1 otherwise.
     */
    int open(const char *name);

    /*! Allocates a handle to write to and read from. */
67
    portable_off_t alloc();
68 69 70 71 72 73 74 75 76 77 78 79 80 81

    /*! Writes \a size bytes in array \a buf to the store. 
     *  First alloc() has to be called.
     *  \note The information can only be read after end() has been called.
     */
    int write(const char *buf,uint size);

    /*! Ends the sequence of writes. 
     *  \note After this call, first alloc() has to be called
     *  before new writes can be done.
     */
    void end();

    /*! Releases the memory corresponding to the handle returned with alloc() */
82
    void release(portable_off_t handle);
83 84 85 86 87

    /*! Closes the store */
    void close();

    /*! Goes to the start of information corresponding to handle \a pos */
88
    void seek(portable_off_t handle);
89 90 91 92 93 94 95 96

    /*! Reads \a size bytes from the store into the array pointed to be \a buf.
     *  \note Before reading seek() has to be called to set the right start of the store.
     */
    int read(char *buf,uint size);

    void printStats();

Dimitri van Heesch's avatar
Dimitri van Heesch committed
97 98 99 100
    portable_off_t pos() const { return m_cur; }

    void dumpBlock(portable_off_t start,portable_off_t end);

101 102 103 104 105 106 107 108 109
  private:
    enum State
    {
      Init,
      Reading,
      Writing
    };
    struct Node
    {
110
      portable_off_t pos;
111 112 113 114
      struct Node *next;
    };
    void printFreeList();
    FILE *m_file;
115
    portable_off_t m_front;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
116
    portable_off_t m_cur;
117 118 119 120 121 122 123
    Node *m_head;
    State m_state;
    int m_reads;
    int m_writes;
};

#endif