aa21ab5602
This was a bug I discovered when double clicking on paths in the collection manager to change the path in the FileChooserWidget. Before this patch, strings could be read as: <string> /home/anna/Music</string> Now, the same string will be read as: <string>/home/anna/Music</string> Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
163 lines
3.0 KiB
C++
163 lines
3.0 KiB
C++
/*
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
*/
|
|
#include <error.h>
|
|
#include <file.h>
|
|
#include <print.h>
|
|
|
|
#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
|
|
|
|
void File :: find_dir(std::string &res)
|
|
{
|
|
if (hint == FILE_TYPE_INVALID)
|
|
return;
|
|
|
|
switch (hint) {
|
|
case FILE_TYPE_CONFIG:
|
|
res = g_get_user_config_dir();
|
|
break;
|
|
case FILE_TYPE_DATA:
|
|
res = g_get_user_data_dir();
|
|
break;
|
|
default: /* FILE_TYPE_LEGACY */
|
|
res = g_get_home_dir();
|
|
break;
|
|
}
|
|
|
|
res += "/";
|
|
switch (hint) {
|
|
case FILE_TYPE_CONFIG:
|
|
case FILE_TYPE_DATA:
|
|
res += OCARINA_DIR;
|
|
break;
|
|
default: /* FILE_TYPE_LEGACY */
|
|
res += ".";
|
|
res += OCARINA_DIR;
|
|
res += "/library";
|
|
}
|
|
}
|
|
|
|
File :: File(const std::string &path, FileLocHint file_hint)
|
|
: mode(NOT_OPEN), hint(file_hint)
|
|
{
|
|
std::string dir;
|
|
|
|
if (path == "") {
|
|
hint = FILE_TYPE_INVALID;
|
|
filepath = "INVALID";
|
|
return;
|
|
}
|
|
|
|
find_dir(dir);
|
|
filepath = dir + "/" + path;
|
|
}
|
|
|
|
File :: ~File()
|
|
{
|
|
close();
|
|
}
|
|
|
|
const char *File :: get_filepath()
|
|
{
|
|
return filepath.c_str();
|
|
}
|
|
|
|
const unsigned int File :: get_version()
|
|
{
|
|
return version;
|
|
}
|
|
|
|
bool File :: exists()
|
|
{
|
|
return g_file_test(filepath.c_str(), G_FILE_TEST_EXISTS);
|
|
}
|
|
|
|
void File :: open_read()
|
|
{
|
|
if (!exists()) {
|
|
dprint("ERROR: File does not exist (%s)\n", filepath.c_str());
|
|
throw -E_EXIST;
|
|
}
|
|
|
|
std::fstream::open(filepath.c_str(), std::fstream::in);
|
|
if (std::fstream::fail()) {
|
|
dprint("ERROR: Could not open file for reading (%s)\n", filepath.c_str());
|
|
throw -E_IO;
|
|
}
|
|
|
|
mode = OPEN_READ;
|
|
std::fstream::operator>>(version);
|
|
getline();
|
|
}
|
|
|
|
void File :: open_write()
|
|
{
|
|
std::string dir;
|
|
if (hint == FILE_TYPE_LEGACY) {
|
|
dprint("ERROR: Cannot write to legacy files (%s)\n", filepath.c_str());
|
|
throw -E_IO;
|
|
}
|
|
|
|
find_dir(dir);
|
|
if (g_mkdir_with_parents(dir.c_str(), 0755) != 0) {
|
|
dprint("ERROR: Could not make directory (%s)\n", dir.c_str());
|
|
throw -E_IO;
|
|
}
|
|
|
|
std::fstream::open(filepath.c_str(), std::fstream::out);
|
|
if (std::fstream::fail()) {
|
|
dprint("ERROR: Could not open file for writing (%s)\n", filepath.c_str());
|
|
throw -E_IO;
|
|
}
|
|
|
|
mode = OPEN_WRITE;
|
|
std::fstream::operator<<(FILE_VERSION) << std::endl;
|
|
}
|
|
|
|
void File :: open(OpenMode m)
|
|
{
|
|
if (mode != NOT_OPEN) {
|
|
dprint("ERROR: File is already open (%s)\n", filepath.c_str());
|
|
throw -E_IO;
|
|
}
|
|
|
|
if (m == NOT_OPEN) {
|
|
dprint("ERROR: NOT_OPEN is not a legal OpenMode (%s)\n", filepath.c_str());
|
|
throw -E_INVAL;
|
|
} else if (hint == FILE_TYPE_INVALID) {
|
|
dprint("ERROR: A file with hint = FILE_TYPE_INVALID cannot be opened\n");
|
|
throw -E_INVAL;
|
|
} else if (m == OPEN_READ)
|
|
open_read();
|
|
else /* m == OPEN_WRITE */
|
|
open_write();
|
|
}
|
|
|
|
void File :: close()
|
|
{
|
|
if (mode != NOT_OPEN)
|
|
std::fstream::close();
|
|
mode = NOT_OPEN;
|
|
}
|
|
|
|
std::string File :: getline()
|
|
{
|
|
char c;
|
|
std::string res;
|
|
|
|
/* Ignore leading whitespace */
|
|
while (peek() == ' ')
|
|
read(&c, 1);
|
|
|
|
std::getline(*static_cast<std::fstream *>(this), res);
|
|
return res;
|
|
}
|