ocarina/design/file.txt

119 lines
3.2 KiB
Plaintext

== Files ==
ocarina/include/
file.h
ocarina/lib/
file.cpp
== Depends ==
version print
On-disk files: (lib/file.cpp)
Data will be stored in the user's home directory according to the
XDG / freedesktop.org specification. This means storing data in
$XDG_DATA_HOME/ocarina{-debug|-test}/ and storing configuration in
$XDG_CONFIG_HOME/ocarina{-debug|-test}/. In addition, I will support
importing data from Ocarina 5.10 for conversion to the new format.
In theory my file format will not change often, so it should be
possible to use multiple Ocarina versions with the same data. However,
should the format need to change I will only support forward
compatibility. This means that downgrades will not be possible after
a file format change. To keep the code even cleaner, I will only
support updating from the previous file format version. This means
that legacy support will be removed after the first file format change.
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"
- File version:
#define FILE_VERSION 0
- Hint where the file is located:
enum FileLocHint {
FILE_TYPE_CONFIG,
FILE_TYPE_DATA,
FILE_TYPE_LEGACY,
FILE_TYPE_INVALID,
}
- Open mode:
enum OpenMode {
OPEN_READ,
OPEN_WRITE,
NOT_OPEN,
}
- File:
class File : std::fstream {
private:
unsigned int version;
OpenMode mode;
FileLocHint hint;
string filepath;
public:
File(string, FileLocHint);
~File();
const char *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(string filepath, FileLocHint hint);
Resolve filepath to one of:
XDG_{CONFIG|DATA}_HOME/ocarina/filepath
XDG_{CONFIG|DATA}_HOME/ocarina-debug/filepath
XDG_{CONFIG|DATA}_HOME/ocarina-test/filepath
$HOME/.ocarina/
$HOME/.ocarina-debug/
$HOME/.ocarina-test/
If filepath is an empty string, set the file hint to
FILE_TYPE_INVALID and do not set the filepath field.
File :: ~File();
Close the file stream if it is open.
const char *File :: get_filepath();
Return the full filepath to the file.
const unsigned int File :: get_version();
Return the file version number.
bool File :: exists();
Return true if the file exists in the filesystem.
Return false otherwise.
void File :: open(OpenMode mode);
When opening a file for reading (mode == OPEN_READ),
- Throw -EEXIST if the file does not exist
- Open the file
- Read in version from the start of the file
When opening a file for writing (mode == OPEN_WRITE),
- Throw -ELEGACY if the file has FILE_TYPE_LEGACY set
- Create missing directories as needed
- Write version information to the start of the file
Throw -EINVAL if hint == FILE_TYPE_INVALID.
Throw -EOPEN if the file is already open.
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.