file: Update documentation and various cleanups

I add more detailed documentation matching what was in my DESIGN file.
In addition, I also prefix private File members with an underscore like
I do in other Ocarina classes.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2014-11-01 21:30:06 -04:00
parent 23cc27c3ef
commit 47f6684923
4 changed files with 93 additions and 154 deletions

98
DESIGN
View File

@ -44,104 +44,6 @@ Callbacks:
On-disk files:
Data will be stored in the user's home directory according to the
XDG / freedesktop.org specification. This means data will be stored
in a subdirectory of $XDG_DATA_HOME.
The filse class will support reading and writing files in the users
$XDG_CONFIG_HOME/ocarina{-debug|test}.
Items should be written to a file with either a space or new line
separating multiple values.
- Notation:
"File << aaaaa << bbbbb << endl" is translated into "aaaaa bbbbb\n"
- Open mode:
enum OpenMode {
OPEN_READ,
OPEN_WRITE,
NOT_OPEN,
}
- File:
class File : public std::fstream {
private:
unsigned int version;
unsigned int prev_version;
OpenMode mode;
string filename;
public:
File(const std::string &, unsigned int);
~File();
const std::string get_filepath();
const unsigned int get_version();
bool exists();
void open(OpenMode);
void close();
string getline();
}
- File format:
File << FILE_VERSION << endl;
File << <OTHER_DATA>;
- API:
File :: File(const std::string &filename, unsigned int version);
Store the name of the file and the file version.
File :: ~File();
Close the file stream if it is open.
const std::string File :: get_filepath();
If filename == "":
return ""
Otherwise, resolve filepath to one of:
XDG_DATA_HOME/ocarina/filepath
XDG_DATA_HOME/ocarina-debug/filepath
XDG_DATA_HOME/ocarina-test/filepath
and return the result.
const unsigned int File :: get_version();
if mode == OPEN_READ:
return prev_version
return version
bool File :: exists();
Return true if the file exists in the filesystem.
Return false otherwise.
bool File :: open(OpenMode mode);
Return false if:
- filename == ""
- mode == NOT_OPEN
- The file is already open
When opening a file for reading (mode == OPEN_READ),
- Return false if the file does not exist
- Open the file
- Read in prev_version from the start of the file
When opening a file for writing (mode == OPEN_WRITE),
- Create missing directories as needed
- Write version information to the start of the file
Return true on success.
void File :: close();
Close a file after IO.
string File :: getline();
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 problem.
Database Entry: Database Entry:
The database entry class is a base class used for storing data inside The database entry class is a base class used for storing data inside
a database (below). The valid flag and id counter will be managed by a database (below). The valid flag and id counter will be managed by

View File

@ -216,7 +216,7 @@ SEPARATE_MEMBER_PAGES = NO
# uses this value to replace tabs by spaces in code fragments. # uses this value to replace tabs by spaces in code fragments.
# Minimum value: 1, maximum value: 16, default value: 4. # Minimum value: 1, maximum value: 16, default value: 4.
TAB_SIZE = 4 TAB_SIZE = 8
# This tag can be used to specify a number of aliases that act as commands in # This tag can be used to specify a number of aliases that act as commands in
# the documentation. An alias has the form: # the documentation. An alias has the form:
@ -415,7 +415,7 @@ EXTRACT_ALL = NO
# be included in the documentation. # be included in the documentation.
# The default value is: NO. # The default value is: NO.
EXTRACT_PRIVATE = NO EXTRACT_PRIVATE = Yes
# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
# scope will be included in the documentation. # scope will be included in the documentation.
@ -460,7 +460,7 @@ EXTRACT_ANON_NSPACES = NO
# section is generated. This option has no effect if EXTRACT_ALL is enabled. # section is generated. This option has no effect if EXTRACT_ALL is enabled.
# The default value is: NO. # The default value is: NO.
HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_MEMBERS = YES
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy. If set # undocumented classes that are normally visible in the class hierarchy. If set

View File

@ -13,8 +13,16 @@ const std::string OCARINA_DIR = "ocarina-debug";
const std::string OCARINA_DIR = "ocarina"; const std::string OCARINA_DIR = "ocarina";
#endif #endif
File :: File(const std::string &name, unsigned int vers) static const std::string find_ocarina_dir()
: mode(NOT_OPEN), filename(name), version(vers), prev_version(0) {
std::string res(g_get_user_data_dir());
res += "/" + OCARINA_DIR;
return res;
}
File :: File(const std::string &name, unsigned int version)
: _mode(NOT_OPEN), _filename(name), _version(version), _prev_version(0)
{ {
} }
@ -23,29 +31,22 @@ File :: ~File()
close(); close();
} }
const std::string File :: find_dir()
{
std::string res(g_get_user_data_dir());
res += "/" + OCARINA_DIR;
return res;
}
const std::string File :: get_filepath() const std::string File :: get_filepath()
{ {
std::string res = ""; std::string res = "";
if (filename != "") { if (_filename != "") {
res = find_dir(); res = find_ocarina_dir();
res += "/" + filename; res += "/" + _filename;
} }
return res; return res;
} }
const unsigned int File :: get_version() const unsigned int File :: get_version()
{ {
if (mode == OPEN_READ) if (_mode == OPEN_READ)
return prev_version; return _prev_version;
return version; return _version;
} }
bool File :: exists() bool File :: exists()
@ -53,7 +54,7 @@ bool File :: exists()
return g_file_test(get_filepath().c_str(), G_FILE_TEST_EXISTS); return g_file_test(get_filepath().c_str(), G_FILE_TEST_EXISTS);
} }
bool File :: open_read() bool File :: _open_read()
{ {
if (!exists()) if (!exists())
return false; return false;
@ -62,42 +63,42 @@ bool File :: open_read()
if (std::fstream::fail()) if (std::fstream::fail())
return false; return false;
mode = OPEN_READ; _mode = OPEN_READ;
std::fstream::operator>>(prev_version); std::fstream::operator>>(_prev_version);
getline(); getline();
return true; return true;
} }
bool File :: open_write() bool File :: _open_write()
{ {
if (g_mkdir_with_parents(find_dir().c_str(), 0755) != 0) if (g_mkdir_with_parents(find_ocarina_dir().c_str(), 0755) != 0)
return false; return false;
std::fstream::open(get_filepath().c_str(), std::fstream::out); std::fstream::open(get_filepath().c_str(), std::fstream::out);
if (std::fstream::fail()) if (std::fstream::fail())
return false; return false;
mode = OPEN_WRITE; _mode = OPEN_WRITE;
std::fstream::operator<<(version) << std::endl; std::fstream::operator<<(_version) << std::endl;
return true; return true;
} }
bool File :: open(OpenMode m) bool File :: open(OpenMode mode)
{ {
if ((filename == "") || (m == NOT_OPEN) || (mode != NOT_OPEN)) if ((_filename == "") || (mode == NOT_OPEN) || (_mode != NOT_OPEN))
return false; return false;
else if (m == OPEN_READ) else if (mode == OPEN_READ)
return open_read(); return _open_read();
else /* m == OPEN_WRITE */ else /* mode == OPEN_WRITE */
return open_write(); return _open_write();
} }
void File :: close() void File :: close()
{ {
if (mode != NOT_OPEN) if (_mode != NOT_OPEN)
std::fstream::close(); std::fstream::close();
mode = NOT_OPEN; _mode = NOT_OPEN;
} }
std::string File :: getline() std::string File :: getline()

View File

@ -10,33 +10,48 @@
/** /**
* Enum for how files could be open. * Constants defining how files can be opened.
*/ */
enum OpenMode { enum OpenMode {
/** File is open for reading. */ OPEN_READ, /**< File is open for reading. */
OPEN_READ, OPEN_WRITE, /**< File is open for writing. */
NOT_OPEN, /**< File is not open. */
/** File is open for writing. */
OPEN_WRITE,
/** File is not open. */
NOT_OPEN,
}; };
/** /**
* Class for modifying files in the Ocarina directory. * 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 { class File : public std::fstream {
private: private:
OpenMode mode; OpenMode _mode; /**< The file's current open mode. */
std::string filename; std::string _filename; /**< The file's basename. */
unsigned int version; unsigned int _version; /**< The file's current data version. */
unsigned int prev_version; unsigned int _prev_version; /**< The file's on-disk data version. */
const std::string find_dir(); bool _open_read();
bool open_read(); bool _open_write();
bool open_write();
public: public:
@ -49,17 +64,20 @@ public:
File(const std::string &, unsigned int); File(const std::string &, unsigned int);
/** /**
* File class destructor. * Closes the file stream if it is still open.
*/ */
~File(); ~File();
/** /**
* @return The full filepath of the file. * @return The full filepath of the file or an empty string if
* the filename is not set.
*/ */
const std::string get_filepath(); const std::string get_filepath();
/** /**
* @return The version number of the file. * @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(); const unsigned int get_version();
@ -69,19 +87,37 @@ public:
bool exists(); bool exists();
/** /**
* Open a file. * 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. * @param mode How the file should be opened.
* @return True if the open succeeded, False otherwise. * @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); bool open(OpenMode);
/** /**
* Close an open file. * Close an open file and set File::mode to ::NOT_OPEN.
*/ */
void close(); 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. * @return A string containing the rest of the line.
*/ */
std::string getline(); std::string getline();