/** * Copyright 2013 (c) Anna Schumaker. */ #ifndef OCARINA_CORE_FILE_H #define OCARINA_CORE_FILE_H #include #include /** * 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_TESTING | $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 should be written to files using either a space or newline as * a delimiter. */ struct file : public std::fstream { OpenMode f_mode; /* The file's current open mode. */ unsigned int f_version; /* The file's current data version. */ unsigned int f_prev; /* The file's on-disk data version. */ std::string f_name; /* The file's basename. */ /** * 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); /** * 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(); }; /* Returns the full path of the file or an empty string if filename is not set. */ const std::string file_path(struct file *); /* Returns the version number of the file. */ const unsigned int file_version(struct file *); /* Returns true if the file exists on disk and false otherwise. */ bool file_exists(struct file *); /* * Call to open a file for either reading or writing. Callers * are expected to call file_close() when IO is completed. * * When opening a file for reading (OPEN_READ): * - Check if the file exists. * - Read in file->_prev_version from the start of the file. * * When opening a file for writing (OPEN_WRITE): * - Create missing directories as needed. * - Write file->_version to the start of the file. * * Returns true if the open was successful and false otherwise. */ bool file_open(struct file *, OpenMode); /* Close an open file, setting file->mode to NOT_OPEN. */ void file_close(struct file *); #endif /* OCARINA_CORE_FILE_H */