|
Packit |
1c1d7e |
/******************************************************************************
|
|
Packit |
1c1d7e |
*
|
|
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 |
#ifndef STORE_H
|
|
Packit |
1c1d7e |
#define STORE_H
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#include <qglobal.h>
|
|
Packit |
1c1d7e |
#include <stdio.h>
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#include "portable.h"
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! @brief Abstract interface for file based memory storage operations */
|
|
Packit |
1c1d7e |
class StorageIntf
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
/*! Required by gcc */
|
|
Packit |
1c1d7e |
virtual ~StorageIntf() {}
|
|
Packit |
1c1d7e |
/*! Read \a size bytes from the store into \a buf. */
|
|
Packit |
1c1d7e |
virtual int read(char *buf,uint size) = 0;
|
|
Packit |
1c1d7e |
/*! Write \a size bytes from \a buf into the store. */
|
|
Packit |
1c1d7e |
virtual int write(const char *buf,uint size) = 0;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! @brief The Store is a file based memory manager.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* You can open the store using open(). Then obtain a handle via alloc()
|
|
Packit |
1c1d7e |
* followed by a sequence of write() commands to store information,
|
|
Packit |
1c1d7e |
* and finalize it using end().
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Later on you locate the information
|
|
Packit |
1c1d7e |
* with seek() using the handle obtained with alloc(), and then use a
|
|
Packit |
1c1d7e |
* sequence of read() calls to read the information back.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* If no longer needed the storage space can be freed using release().
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* The store will dynamically grow the file on disk if needed.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
class Store : public StorageIntf
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
/*! Creates a store. */
|
|
Packit |
1c1d7e |
Store();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Releases the store object. Will close the underlying file if opened. */
|
|
Packit |
1c1d7e |
~Store();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Opens the file underlying the store using \a name as the file name.
|
|
Packit |
1c1d7e |
* Returns 0 upon success, or -1 otherwise.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
int open(const char *name);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Allocates a handle to write to and read from. */
|
|
Packit |
1c1d7e |
portable_off_t alloc();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Writes \a size bytes in array \a buf to the store.
|
|
Packit |
1c1d7e |
* First alloc() has to be called.
|
|
Packit |
1c1d7e |
* \note The information can only be read after end() has been called.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
int write(const char *buf,uint size);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Ends the sequence of writes.
|
|
Packit |
1c1d7e |
* \note After this call, first alloc() has to be called
|
|
Packit |
1c1d7e |
* before new writes can be done.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
void end();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Releases the memory corresponding to the handle returned with alloc() */
|
|
Packit |
1c1d7e |
void release(portable_off_t handle);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Closes the store */
|
|
Packit |
1c1d7e |
void close();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Goes to the start of information corresponding to handle \a pos */
|
|
Packit |
1c1d7e |
void seek(portable_off_t handle);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Reads \a size bytes from the store into the array pointed to be \a buf.
|
|
Packit |
1c1d7e |
* \note Before reading seek() has to be called to set the right start of the store.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
int read(char *buf,uint size);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void printStats();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
portable_off_t pos() const { return m_cur; }
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void dumpBlock(portable_off_t start,portable_off_t end);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
private:
|
|
Packit |
1c1d7e |
enum State
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Init,
|
|
Packit |
1c1d7e |
Reading,
|
|
Packit |
1c1d7e |
Writing
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
struct Node
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
portable_off_t pos;
|
|
Packit |
1c1d7e |
struct Node *next;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
void printFreeList();
|
|
Packit |
1c1d7e |
FILE *m_file;
|
|
Packit |
1c1d7e |
portable_off_t m_front;
|
|
Packit |
1c1d7e |
portable_off_t m_cur;
|
|
Packit |
1c1d7e |
Node *m_head;
|
|
Packit |
1c1d7e |
State m_state;
|
|
Packit |
1c1d7e |
int m_reads;
|
|
Packit |
1c1d7e |
int m_writes;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#endif
|