mirror of
https://github.com/libAthena/athena.git
synced 2025-12-20 18:29:15 +00:00
Initial API implementation
This commit is contained in:
82
src/Athena/Dir.cpp
Normal file
82
src/Athena/Dir.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "Athena/Dir.hpp"
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define stat64 __stat64
|
||||
#define realpath(__name, __resolved) _fullpath((__name), (__resolved), 4096)
|
||||
#endif
|
||||
|
||||
namespace Athena
|
||||
{
|
||||
Dir::Dir(const std::string &path)
|
||||
: m_path(path)
|
||||
{
|
||||
}
|
||||
|
||||
std::string Dir::absolutePath() const
|
||||
{
|
||||
return FileInfo(m_path).absoluteFilePath();
|
||||
}
|
||||
|
||||
bool Dir::isDir() const
|
||||
{
|
||||
struct stat64 st;
|
||||
int e = stat64(m_path.c_str(), &st);
|
||||
if (e < 0)
|
||||
return false;
|
||||
|
||||
return (S_ISDIR(st.st_mode));
|
||||
}
|
||||
|
||||
bool Dir::cd(const std::string& path)
|
||||
{
|
||||
Dir tmp(path);
|
||||
if (tmp.isDir())
|
||||
{
|
||||
m_path = path;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Dir::rm(const std::string& path)
|
||||
{
|
||||
return !(remove((m_path + "/" + path).c_str()) < 0);
|
||||
}
|
||||
|
||||
bool Dir::mkdir(const std::string& dir, mode_t mode)
|
||||
{
|
||||
return !(::mkdir(dir.c_str(), mode) < 0);
|
||||
}
|
||||
|
||||
bool Dir::mkpath(const std::string& path, mode_t mode)
|
||||
{
|
||||
std::vector<std::string> dirs = utility::split(path, '/');
|
||||
if (dirs.empty())
|
||||
dirs = utility::split(path, '\\');
|
||||
if (dirs.empty())
|
||||
return false;
|
||||
|
||||
bool ret = false;
|
||||
std::string newPath;
|
||||
for (const std::string& dir : dirs)
|
||||
{
|
||||
if (dir.size() == 2 && dir[1] == ':')
|
||||
{
|
||||
newPath += dir + "//";
|
||||
continue;
|
||||
}
|
||||
newPath += "/" + dir;
|
||||
ret = mkdir(newPath, mode);
|
||||
}
|
||||
|
||||
// we only care if the last directory was created
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
178
src/Athena/FileInfo.cpp
Normal file
178
src/Athena/FileInfo.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "Athena/FileInfo.hpp"
|
||||
#include "Athena/Utility.hpp"
|
||||
#include "Athena/FileWriter.hpp"
|
||||
#include "Athena/FileReader.hpp"
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <functional>
|
||||
#include <locale>
|
||||
#define stat64 __stat64
|
||||
#define realpath(__name, __resolved) _fullpath((__name), (__resolved), 4096)
|
||||
#endif
|
||||
|
||||
namespace Athena
|
||||
{
|
||||
|
||||
FileInfo::FileInfo(const std::string& path)
|
||||
: m_path(path)
|
||||
{
|
||||
}
|
||||
|
||||
std::string FileInfo::absolutePath() const
|
||||
{
|
||||
std::string path = absoluteFilePath();
|
||||
size_t pos = path.find_last_of('/');
|
||||
if (pos == std::string::npos)
|
||||
pos = path.find_last_of('\\');
|
||||
if (pos == std::string::npos)
|
||||
return path;
|
||||
|
||||
return path.substr(0, pos+1);
|
||||
}
|
||||
|
||||
std::string FileInfo::absoluteFilePath() const
|
||||
{
|
||||
char ret[4096];
|
||||
realpath(m_path.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string FileInfo::filename() const
|
||||
{
|
||||
size_t pos = m_path.find_last_of('/');
|
||||
if (pos == std::string::npos)
|
||||
pos = m_path.find_last_of('\\');
|
||||
if (pos == std::string::npos)
|
||||
return m_path;
|
||||
return m_path.substr(pos + 1);
|
||||
}
|
||||
|
||||
std::string FileInfo::extension() const
|
||||
{
|
||||
size_t pos = m_path.find_last_of('.');
|
||||
if (pos == std::string::npos)
|
||||
return std::string();
|
||||
|
||||
return m_path.substr(pos + 1);
|
||||
}
|
||||
|
||||
atUint64 FileInfo::size() const
|
||||
{
|
||||
return utility::fileSize(m_path);
|
||||
}
|
||||
|
||||
bool FileInfo::exists() const
|
||||
{
|
||||
struct stat64 st;
|
||||
int e = stat64(m_path.c_str(), &st);
|
||||
if (e < 0)
|
||||
return false;
|
||||
|
||||
return (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode));
|
||||
}
|
||||
|
||||
bool FileInfo::isLink() const
|
||||
{
|
||||
struct stat64 st;
|
||||
int e = stat64(m_path.c_str(), &st);
|
||||
if (e < 0)
|
||||
return false;
|
||||
|
||||
return (S_ISLNK(st.st_mode));
|
||||
}
|
||||
|
||||
bool FileInfo::isFile() const
|
||||
{
|
||||
struct stat64 st;
|
||||
int e = stat64(m_path.c_str(), &st);
|
||||
if (e < 0)
|
||||
return false;
|
||||
|
||||
return (S_ISREG(st.st_mode));
|
||||
}
|
||||
|
||||
bool FileInfo::touch() const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct stat st;
|
||||
struct timespec newTimes[2];
|
||||
|
||||
if (stat(m_path.c_str(), &st) < 0) {
|
||||
(void)Athena::io::FileWriter(m_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* keep atime unchanged */
|
||||
newTimes[0] = st.st_atim;
|
||||
|
||||
/* set mtime to current time */
|
||||
clock_gettime(CLOCK_REALTIME, &newTimes[1]);
|
||||
|
||||
if (utimensat(AT_FDCWD, m_path.c_str(), newTimes, 0) < 0) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
FILETIME modtime;
|
||||
SYSTEMTIME st;
|
||||
HANDLE fh;
|
||||
wchar_t date[80], time[80];
|
||||
|
||||
fh = CreateFileW(path, GENERIC_READ | FILE_WRITE_ATTRIBUTES, 0, NULL, CREATE_NEW, 0, NULL);
|
||||
if (fh == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Use GetFileTime() to get the file modification time.
|
||||
*/
|
||||
if (GetFileTime(fh, NULL, NULL, &modtime) == 0)
|
||||
{
|
||||
CloseHandle(fh);
|
||||
return false;
|
||||
}
|
||||
|
||||
FileTimeToSystemTime(&modtime, &st);
|
||||
if (GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, date, sizeof date / sizeof date[0]) == 0 ||
|
||||
GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, time, sizeof time / sizeof time[0]) == 0)
|
||||
{
|
||||
CloseHandle(fh);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use SetFileTime() to change the file modification time
|
||||
* to the current time.
|
||||
*/
|
||||
GetSystemTime(&st);
|
||||
if (GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, date, sizeof date / sizeof date[0]) == 0 ||
|
||||
GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, time, sizeof time / sizeof time[0]) == 0)
|
||||
{
|
||||
CloseHandle(fh);
|
||||
return false;
|
||||
}
|
||||
SystemTimeToFileTime(&st, &modtime);
|
||||
if (SetFileTime(fh, NULL, NULL, &modtime) == 0)
|
||||
{
|
||||
CloseHandle(fh);
|
||||
return false;
|
||||
}
|
||||
|
||||
CloseHandle(fh);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -41,7 +41,8 @@ FileReader::FileReader(const std::string& filename)
|
||||
|
||||
FileReader::~FileReader()
|
||||
{
|
||||
close();
|
||||
if (isOpen())
|
||||
close();
|
||||
}
|
||||
|
||||
std::string FileReader::filename() const
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Athena
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
FileWriter::FileWriter(const std::string& filename)
|
||||
FileWriter::FileWriter(const std::string& filename, bool overwrite)
|
||||
: m_filename(filename),
|
||||
m_fileHandle(NULL),
|
||||
m_endian(Endian::LittleEndian),
|
||||
@@ -39,7 +39,7 @@ FileWriter::FileWriter(const std::string& filename)
|
||||
m_bitShift(0),
|
||||
m_bitValid(false)
|
||||
{
|
||||
open();
|
||||
open(overwrite);
|
||||
}
|
||||
|
||||
FileWriter::~FileWriter()
|
||||
@@ -68,9 +68,13 @@ bool FileWriter::isLittleEndian() const
|
||||
return (m_endian == Endian::LittleEndian);
|
||||
}
|
||||
|
||||
void FileWriter::open()
|
||||
void FileWriter::open(bool overwrite)
|
||||
{
|
||||
m_fileHandle = fopen(m_filename.c_str(), "w+b");
|
||||
if (overwrite)
|
||||
m_fileHandle = fopen(m_filename.c_str(), "w+b");
|
||||
else
|
||||
m_fileHandle = fopen(m_filename.c_str(), "r+b");
|
||||
|
||||
if (!m_fileHandle)
|
||||
THROW_FILE_NOT_FOUND_EXCEPTION(m_filename);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <iterator>
|
||||
#include <cstdio>
|
||||
#include <sys/stat.h>
|
||||
#include <Athena/Exception.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <functional>
|
||||
@@ -37,7 +38,7 @@ namespace utility
|
||||
|
||||
bool isSystemBigEndian()
|
||||
{
|
||||
static atUint8* test = (atUint8*)"\xFE\xFF";
|
||||
static const atUint8* test = (atUint8*)"\xFE\xFF";
|
||||
return (*(atUint16*)test == 0xFEFF);
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ bool parseBool(const std::string& boolean, bool* valid)
|
||||
std::string val = boolean;
|
||||
// compare must be case insensitive
|
||||
// This is the cleanest solution since I only need to do it once
|
||||
std::transform(val.begin(), val.end(), val.begin(), ::tolower);
|
||||
tolower(val);
|
||||
|
||||
// Check for true first
|
||||
if (!val.compare("true") || !val.compare("1") || !val.compare("yes") || !val.compare("on"))
|
||||
|
||||
Reference in New Issue
Block a user