2013-07-27 11:40:16 -04:00
|
|
|
/*
|
2013-08-07 21:00:09 -04:00
|
|
|
* Copyright 2013 (c) Anna Schumaker.
|
2013-07-27 11:40:16 -04:00
|
|
|
*/
|
2013-12-29 21:12:32 -05:00
|
|
|
#include <error.h>
|
2013-07-27 11:40:16 -04:00
|
|
|
#include <file.h>
|
2013-07-28 19:57:07 -04:00
|
|
|
#include <print.h>
|
2013-07-27 11:40:16 -04:00
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
#ifdef CONFIG_TEST
|
|
|
|
#define OCARINA_DIR "ocarina-test"
|
|
|
|
#elif CONFIG_DEBUG
|
|
|
|
#define OCARINA_DIR "ocarina-debug"
|
|
|
|
#else
|
|
|
|
#define OCARINA_DIR "ocarina"
|
|
|
|
#endif
|
|
|
|
|
2013-12-29 21:12:32 -05:00
|
|
|
File :: File(const std::string &path, FileLocHint file_hint)
|
2014-03-02 14:44:24 -05:00
|
|
|
: mode(NOT_OPEN), hint(file_hint), version(FILE_VERSION)
|
2013-07-28 19:57:07 -04:00
|
|
|
{
|
2014-03-02 14:44:24 -05:00
|
|
|
if (path.size() == 0)
|
2013-08-10 23:52:52 -04:00
|
|
|
hint = FILE_TYPE_INVALID;
|
|
|
|
|
2014-03-02 14:44:24 -05:00
|
|
|
if (hint == FILE_TYPE_INVALID)
|
|
|
|
filepath = "INVALID";
|
|
|
|
else
|
|
|
|
filepath = find_dir() + "/" + path;
|
2013-07-27 11:40:16 -04:00
|
|
|
}
|
|
|
|
|
2013-07-28 19:57:07 -04:00
|
|
|
File :: ~File()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
2013-07-27 11:40:16 -04:00
|
|
|
const char *File :: get_filepath()
|
|
|
|
{
|
|
|
|
return filepath.c_str();
|
|
|
|
}
|
2013-07-28 19:57:07 -04:00
|
|
|
|
2013-07-28 22:33:40 -04:00
|
|
|
const unsigned int File :: get_version()
|
|
|
|
{
|
|
|
|
return version;
|
|
|
|
}
|
|
|
|
|
2013-07-28 19:57:07 -04:00
|
|
|
bool File :: exists()
|
|
|
|
{
|
|
|
|
return g_file_test(filepath.c_str(), G_FILE_TEST_EXISTS);
|
|
|
|
}
|
|
|
|
|
2014-03-02 14:44:24 -05:00
|
|
|
std::string File :: find_dir()
|
|
|
|
{
|
|
|
|
std::string res;
|
|
|
|
|
|
|
|
if (hint == FILE_TYPE_DATA) {
|
|
|
|
res = g_get_user_data_dir();
|
|
|
|
res += "/";
|
|
|
|
res += OCARINA_DIR;
|
|
|
|
} else /* FILE_TYPE_LEGACY */ {
|
|
|
|
res = g_get_home_dir();
|
|
|
|
res += "/.";
|
|
|
|
res += OCARINA_DIR;
|
|
|
|
res += "/library";
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-12-29 21:12:32 -05:00
|
|
|
void File :: open_read()
|
2013-07-28 19:57:07 -04:00
|
|
|
{
|
|
|
|
if (!exists()) {
|
2014-03-02 14:44:24 -05:00
|
|
|
dprint("ERROR: File does not exist\n");
|
2014-01-04 11:55:52 -05:00
|
|
|
throw -E_EXIST;
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|
|
|
|
|
2013-07-28 22:33:40 -04:00
|
|
|
std::fstream::open(filepath.c_str(), std::fstream::in);
|
|
|
|
if (std::fstream::fail()) {
|
2014-03-02 14:44:24 -05:00
|
|
|
dprint("ERROR: File could not be opened for reading\n");
|
2014-01-04 11:55:52 -05:00
|
|
|
throw -E_IO;
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
mode = OPEN_READ;
|
2013-07-28 22:33:40 -04:00
|
|
|
std::fstream::operator>>(version);
|
|
|
|
getline();
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|
|
|
|
|
2013-12-29 21:12:32 -05:00
|
|
|
void File :: open_write()
|
2013-07-28 19:57:07 -04:00
|
|
|
{
|
|
|
|
if (hint == FILE_TYPE_LEGACY) {
|
2014-03-02 14:44:24 -05:00
|
|
|
dprint("ERROR: Cannot write to legacy files\n");
|
2014-01-04 11:55:52 -05:00
|
|
|
throw -E_IO;
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|
|
|
|
|
2014-03-02 14:44:24 -05:00
|
|
|
std::string dir = find_dir();
|
2013-07-28 19:57:07 -04:00
|
|
|
if (g_mkdir_with_parents(dir.c_str(), 0755) != 0) {
|
2014-03-02 14:44:24 -05:00
|
|
|
dprint("ERROR: Could not make directory\n");
|
2014-01-04 11:55:52 -05:00
|
|
|
throw -E_IO;
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|
|
|
|
|
2013-07-28 22:33:40 -04:00
|
|
|
std::fstream::open(filepath.c_str(), std::fstream::out);
|
|
|
|
if (std::fstream::fail()) {
|
2014-03-02 14:44:24 -05:00
|
|
|
dprint("ERROR: Could not open file for writing\n");
|
2014-01-04 11:55:52 -05:00
|
|
|
throw -E_IO;
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
mode = OPEN_WRITE;
|
2013-07-28 22:33:40 -04:00
|
|
|
std::fstream::operator<<(FILE_VERSION) << std::endl;
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|
|
|
|
|
2013-12-29 21:12:32 -05:00
|
|
|
void File :: open(OpenMode m)
|
2013-07-28 19:57:07 -04:00
|
|
|
{
|
2014-03-02 14:44:24 -05:00
|
|
|
if (hint == FILE_TYPE_INVALID) {
|
|
|
|
dprint("ERROR: A file with hint = FILE_TYPE_INVALID cannot be opened\n");
|
|
|
|
throw -E_INVAL;
|
|
|
|
} else if (m == NOT_OPEN) {
|
|
|
|
dprint("ERROR: NOT_OPEN is not a legal OpenMode\n");
|
|
|
|
throw -E_INVAL;
|
|
|
|
} else if (mode != NOT_OPEN) {
|
|
|
|
dprint("ERROR: File is already open\n");
|
2014-01-04 11:55:52 -05:00
|
|
|
throw -E_IO;
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|
|
|
|
|
2014-03-02 14:44:24 -05:00
|
|
|
else if (m == OPEN_READ)
|
2013-12-29 21:12:32 -05:00
|
|
|
open_read();
|
2013-07-28 19:57:07 -04:00
|
|
|
else /* m == OPEN_WRITE */
|
2013-12-29 21:12:32 -05:00
|
|
|
open_write();
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|
|
|
|
|
2013-12-29 21:12:32 -05:00
|
|
|
void File :: close()
|
2013-07-28 19:57:07 -04:00
|
|
|
{
|
|
|
|
if (mode != NOT_OPEN)
|
2013-07-28 22:33:40 -04:00
|
|
|
std::fstream::close();
|
2013-07-28 19:57:07 -04:00
|
|
|
mode = NOT_OPEN;
|
2013-07-28 22:33:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string File :: getline()
|
|
|
|
{
|
2014-01-22 19:21:11 -05:00
|
|
|
char c;
|
2013-07-28 22:33:40 -04:00
|
|
|
std::string res;
|
2014-01-22 19:21:11 -05:00
|
|
|
|
|
|
|
/* Ignore leading whitespace */
|
|
|
|
while (peek() == ' ')
|
|
|
|
read(&c, 1);
|
|
|
|
|
2013-07-28 22:33:40 -04:00
|
|
|
std::getline(*static_cast<std::fstream *>(this), res);
|
|
|
|
return res;
|
2013-07-28 19:57:07 -04:00
|
|
|
}
|