ocarina/include/core/file.h

126 lines
3.3 KiB
C
Raw Normal View History

/**
* Copyright 2013 (c) Anna Schumaker.
*/
#ifndef OCARINA_CORE_FILE_H
#define OCARINA_CORE_FILE_H
#include <fstream>
#include <string>
/**
* Constants defining how files can be opened.
*/
enum OpenMode {
OPEN_READ, /**< File is open for reading. */
OPEN_WRITE, /**< File is open for writing. */
NOT_OPEN, /**< File is not open. */
};
/**
* File data is store in the user's home directory according to the
* XDG / freedesktop.org specification, meaning all of our data will
* be stored in a subdirectory of $XDG_DATA_HOME. The actual subdirectory
* changes based on what configuration values the user has set when Ocarina
* is compiled.
*
* Config Value | Ocarina Directory
* -------------|--------------------
* default | $XDG_DATA_HOME/ocarina/
* CONFIG_DEBUG | $XDG_DATA_HOME/ocarina-debug/
* CONFIG_TEST | $XDG_DATA_HOME/ocarina-test/
*
* Data should be written to files using either a space or newline as a
* delimiter. The beginning of every file is the current file version
* followed by a newline. For example:
*
* 42
* <data> <more data>
* <even more data>
*
* Data should be written to files using either a space or newline as
* a delimiter.
*/
class File : public std::fstream {
private:
OpenMode _mode; /**< The file's current open mode. */
std::string _filename; /**< The file's basename. */
unsigned int _version; /**< The file's current data version. */
unsigned int _prev_version; /**< The file's on-disk data version. */
bool _open_read();
bool _open_write();
public:
/**
* Set up a new file object.
*
* @param name The name of the file.
* @param version The file version of the new file.
*/
File(const std::string &, unsigned int);
/**
* Closes the file stream if it is still open.
*/
~File();
/**
* @return The full filepath of the file or an empty string if
* the filename is not set.
*/
const std::string get_filepath();
/**
* @return The version number of the file. If File::_mode is
* ::OPEN_READ then File::_prev_version is returned.
* File::_version is returned in all other cases.
*/
const unsigned int get_version();
/**
* @return True if the file exists on disk, False otherwise.
*/
bool exists();
/**
* Call to open a file for either reading or writing.
*
* When opening a file for reading:
* -# Check if the file exists.
* -# Open the file stream.
* -# Read in File::_prev_version from the start of the file.
*
* When opening a file for writing:
* -# Create missing directories as needed.
* -# Write File::_version to the start of the file.
*
* @param mode How the file should be opened.
* @return True if the open was successful.
* @return False under the following conditions:
* - File::_filename is unset
* - mode is ::NOT_OPEN
* - The file is already open (File::_mode != NOT_OPEN)
* - The file does not exist (mode == ::OPEN_READ)
*/
bool open(OpenMode);
/**
* Close an open file and set File::mode to ::NOT_OPEN.
*/
void close();
/**
* Read an entire line from the file and return it to the caller.
* In theory a return value optimization will occur so returning
* a string by value won't be a performance problem.
*
* @return A string containing the rest of the line.
*/
std::string getline();
};
#endif /* OCARINA_CORE_FILE_H */