/** * Copyright 2013 (c) Anna Schumaker. */ #include #include #include #ifdef CONFIG_TESTING const std::string OCARINA_DIR = "ocarina-test"; #elif CONFIG_DEBUG const std::string OCARINA_DIR = "ocarina-debug"; #else const std::string OCARINA_DIR = "ocarina"; #endif #define REPORT_ERROR() \ printf("%s (%s:%d): %s\n", __func__, __FILE__, __LINE__, strerror(errno)) static const std::string find_ocarina_dir() { std::string res(g_get_user_data_dir()); res += "/" + OCARINA_DIR; return res; } static bool __file_mkdir() { return g_mkdir_with_parents(find_ocarina_dir().c_str(), 0755) == 0; } void file_init(struct file *file, const std::string &name, unsigned int version) { file->f_mode = NOT_OPEN; file->f_version = version; file->f_prev = 0; file->f_file = NULL; file->f_name = name; } const std::string file_path(struct file *file) { std::string res = ""; if (file->f_name != "") { res = find_ocarina_dir(); res += "/" + file->f_name; } return res; } const unsigned int file_version(struct file *file) { if (file->f_mode == OPEN_READ) return file->f_prev; return file->f_version; } bool file_exists(struct file *file) { return g_file_test(file_path(file).c_str(), G_FILE_TEST_EXISTS); } static bool __file_open_common(struct file *file, OpenMode mode) { if (mode == OPEN_READ) { ((std::fstream *)file)->open(file_path(file).c_str(), std::fstream::in); if (file->fail()) return false; } else { file->f_file = g_fopen(file_path(file).c_str(), "w"); if (!file->f_file) { REPORT_ERROR(); return false; } } file->f_mode = mode; return true; } static bool __file_open_read(struct file *file) { if (!file_exists(file)) return false; if (!__file_open_common(file, OPEN_READ)) return false; *file >> file->f_prev; file_readl(file); return true; } static bool __file_open_write(struct file *file) { if (!__file_mkdir()) return false; if (!__file_open_common(file, OPEN_WRITE)) return false; return file_writef(file, "%d\n", file->f_version) > 0; } bool file_open(struct file *file, OpenMode mode) { if ((file->f_name == "") || (mode == NOT_OPEN) || (file->f_mode != NOT_OPEN)) return false; if (mode == OPEN_READ) return __file_open_read(file); return __file_open_write(file); } void file_close(struct file *file) { if (file->f_mode != NOT_OPEN) { file->close(); if (file->f_file) fclose(file->f_file); file->f_file = NULL; } file->f_mode = NOT_OPEN; } std::string file_readl(struct file *file) { char c; std::string res; /* Ignore leading whitespace */ while (file->peek() == ' ') file->read(&c, 1); std::getline(*static_cast(file), res); return res; } int file_writef(struct file *file, const char *fmt, ...) { va_list argp; int ret; va_start(argp, fmt); ret = g_vfprintf(file->f_file, fmt, argp); va_end(argp); if (ret < 0) REPORT_ERROR(); return ret; }