mirror of https://github.com/libAthena/athena.git
Initial API implementation
This commit is contained in:
parent
20e12b86ca
commit
01f989c21c
|
@ -21,7 +21,9 @@ SOURCES += \
|
|||
$$PWD/src/LZ77/LZLookupTable.cpp \
|
||||
$$PWD/src/LZ77/LZType10.cpp \
|
||||
$$PWD/src/LZ77/LZType11.cpp \
|
||||
$$PWD/src/LZ77/LZBase.cpp
|
||||
$$PWD/src/LZ77/LZBase.cpp \
|
||||
$$PWD/src/Athena/FileInfo.cpp \
|
||||
$$PWD/src/Athena/Dir.cpp
|
||||
|
||||
win32:SOURCES += \
|
||||
$$PWD/src/win32_largefilewrapper.c
|
||||
|
@ -56,7 +58,9 @@ HEADERS += \
|
|||
$$PWD/include/utf8.h \
|
||||
$$PWD/include/utf8/checked.h \
|
||||
$$PWD/include/utf8/core.h \
|
||||
$$PWD/include/utf8/unchecked.h
|
||||
$$PWD/include/utf8/unchecked.h \
|
||||
$$PWD/include/Athena/FileInfo.hpp \
|
||||
$$PWD/include/Athena/Dir.hpp
|
||||
|
||||
win32:HEADERS += \
|
||||
$$PWD/include/win32_largefilewrapper.h
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef DIR_HPP
|
||||
#define DIR_HPP
|
||||
|
||||
#include "Athena/FileInfo.hpp"
|
||||
|
||||
namespace Athena
|
||||
{
|
||||
class Dir
|
||||
{
|
||||
public:
|
||||
explicit Dir(const std::string& path);
|
||||
|
||||
std::string absolutePath() const;
|
||||
static inline std::string absolutePath(const std::string& path)
|
||||
{ return Dir(path).absolutePath(); }
|
||||
|
||||
bool isDir() const;
|
||||
static bool isDir(const std::string dir)
|
||||
{ return Dir(dir).isDir(); }
|
||||
|
||||
std::vector<FileInfo> files() const;
|
||||
|
||||
bool cd(const std::string& path);
|
||||
bool rm(const std::string& path);
|
||||
static bool mkdir(const std::string& dir, mode_t mode = 0755);
|
||||
static bool mkpath(const std::string& path, mode_t mode = 0755);
|
||||
private:
|
||||
std::string m_path;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DIR_HPP
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef FILEINFO_HPP
|
||||
#define FILEINFO_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Athena/Global.hpp>
|
||||
|
||||
namespace Athena
|
||||
{
|
||||
class FileInfo
|
||||
{
|
||||
public:
|
||||
explicit FileInfo(const std::string& path = std::string());
|
||||
|
||||
std::string absolutePath() const;
|
||||
static inline std::string absolutePath(const std::string& lnk)
|
||||
{ return FileInfo(lnk).absolutePath(); }
|
||||
|
||||
std::string absoluteFilePath() const;
|
||||
static inline std::string absoluteFilePath(const std::string& path)
|
||||
{ return FileInfo(path).absoluteFilePath(); }
|
||||
|
||||
std::string filename() const;
|
||||
static inline std::string filename(const std::string path)
|
||||
{ return FileInfo(path).filename(); }
|
||||
|
||||
std::string path() const;
|
||||
static inline std::string path(const std::string path)
|
||||
{ return FileInfo(path).path(); }
|
||||
|
||||
std::string extension() const;
|
||||
static inline std::string extension(const std::string path)
|
||||
{ return FileInfo(path).extension(); }
|
||||
|
||||
atUint64 size() const;
|
||||
static inline atUint64 size(const std::string path)
|
||||
{ return FileInfo(path).size(); }
|
||||
|
||||
bool exists() const;
|
||||
static inline bool exists(const std::string& path)
|
||||
{ return FileInfo(path).exists(); }
|
||||
|
||||
bool isLink() const;
|
||||
static inline bool isLink(const std::string& lnk)
|
||||
{ return FileInfo(lnk).isLink(); }
|
||||
bool isFile() const;
|
||||
static inline bool isFile(const std::string& path)
|
||||
{ return FileInfo(path).isFile(); }
|
||||
|
||||
bool touch() const;
|
||||
static inline bool touch(const std::string& path)
|
||||
{ return FileInfo(path).touch(); }
|
||||
|
||||
private:
|
||||
std::string m_path;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // FILEINFO_HPP
|
|
@ -25,14 +25,14 @@ namespace io
|
|||
class FileWriter : public IStreamWriter
|
||||
{
|
||||
public:
|
||||
FileWriter(const std::string& filename);
|
||||
FileWriter(const std::string& filename, bool overwrite = true);
|
||||
virtual ~FileWriter();
|
||||
|
||||
void setEndian(Endian endian);
|
||||
Endian endian() const;
|
||||
bool isBigEndian() const;
|
||||
bool isLittleEndian() const;
|
||||
void open();
|
||||
void open(bool overwrite = true);
|
||||
void close();
|
||||
bool isOpen() const;
|
||||
bool save();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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"))
|
||||
|
|
Loading…
Reference in New Issue