view src/core/filesystem.cc @ 101:c537996cf67b

*: multitude of config changes 1. theme is now configurable from the settings menu (but you have to restart for it to apply) 2. config is now stored in an INI file, with no method of conversion from json (this repo is private-ish anyway)
author Paper <mrpapersonic@gmail.com>
date Fri, 03 Nov 2023 14:06:02 -0400
parents 9b2b41f83a5e
children c8c72278f6fd
line wrap: on
line source

#ifdef WIN32
#	include <shlobj.h>
#elif defined(MACOSX)
#	include "sys/osx/filesystem.h"
#elif defined(__linux__)
#	include <pwd.h>
#	include <sys/types.h>
#endif

#ifdef WIN32
#	define DELIM "\\"
#else
#	define DELIM "/"
#	include <errno.h>
#	include <unistd.h>
#	include <sys/stat.h>
#endif

#include "core/filesystem.h"
#include "core/config.h"
#include "core/strings.h"
#include <limits.h>

namespace Filesystem {

Path::Path() {
	_path = "";
}
Path::Path(const std::string& path) {
	_path = path;
}
Path::Path(const Path& path) {
	_path = path.GetPath();
}

bool Path::CreateDirectories() const {
	std::string temp = "";
	size_t start;
	size_t end = 0;
	temp.append(_path.substr(0, _path.find_first_not_of(DELIM, end)));

	while ((start = _path.find_first_not_of(DELIM, end)) != std::string::npos) {
		end = _path.find(DELIM, start);
		temp.append(_path.substr(start, end - start));
#ifdef WIN32
		if (!CreateDirectoryW(Strings::ToWstring(temp).c_str(), NULL) && GetLastError() == ERROR_PATH_NOT_FOUND)
			/* ERROR_PATH_NOT_FOUND should NOT happen here */
			return false;
#else
		struct stat st;
		if (stat(temp.c_str(), &st) == -1)
			mkdir(temp.c_str(), 0755);
#endif
		temp.append(DELIM);
	}
	return true;
}

bool Path::Exists() const {
#if WIN32
	std::wstring buf = Strings::ToWstring(_path);
	return GetFileAttributesW(buf.c_str()) != INVALID_FILE_ATTRIBUTES;
#else
	struct stat st;
	return stat(_path.c_str(), &st) == 0;
#endif
}

std::string Path::Basename() const {
	unsigned long long pos = _path.find_last_of(DELIM);
	return pos != std::string::npos ? _path.substr(pos + 1, _path.length()) : "";
}

std::string Path::Stem() const {
	std::string basename = Basename();
	unsigned long long pos = basename.find_last_of(".");
	return pos != std::string::npos ? basename.substr(0, pos) : "";
}

std::string Path::Extension() const {
	std::string basename = Basename();
	unsigned long long pos = basename.find_last_of(".");
	return pos != std::string::npos ? basename.substr(pos + 1, basename.length()) : "";
}

Path Path::GetParent() const {
	return _path.substr(0, _path.find_last_of(DELIM));
}

void Path::SetPath(const std::string& path) {
	_path = path;
}

std::string Path::GetPath() const {
	return _path;
}

Path GetDotPath(void) {
	std::string ret = "";
#ifdef WIN32
	std::wstring buf(MAX_PATH, '\0');
	if (SHGetFolderPathAndSubDirW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, CONFIG_WDIR, &buf.front()) ==
	    S_OK) {
		buf.resize(buf.find('\0'));
		ret += Strings::ToUtf8String(buf);
	}
#elif defined(MACOSX)
	ret += osx::GetApplicationSupportDirectory();
	ret += DELIM CONFIG_DIR;
#else // just assume POSIX
	if (getenv("HOME") != NULL)
		ret += getenv("HOME");
#	ifdef __linux__
	else
		ret += getpwuid(getuid())->pw_dir;
#	endif // __linux__
	if (!ret.empty())
		ret += DELIM ".config" DELIM CONFIG_DIR;
#endif     // !WIN32 && !MACOSX
	return ret;
}

Path GetConfigPath(void) {
	std::string ret = "";
	ret += GetDotPath().GetPath();
	if (!ret.empty())
		ret += DELIM CONFIG_NAME;
	return ret;
}

Path GetAnimeDBPath(void) {
	std::string ret = "";
	ret += GetDotPath().GetPath();
	if (!ret.empty())
		ret += DELIM "anime" DELIM "db.json";
	return ret;
}

} // namespace Filesystem