Initial API implementation

This commit is contained in:
Phillip Stephens 2015-05-18 14:03:13 -07:00
parent 20e12b86ca
commit 01f989c21c
9 changed files with 372 additions and 11 deletions

View File

@ -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

32
include/Athena/Dir.hpp Normal file
View File

@ -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

View File

@ -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

View File

@ -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();

82
src/Athena/Dir.cpp Normal file
View 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
View 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;
}
}

View File

@ -41,7 +41,8 @@ FileReader::FileReader(const std::string& filename)
FileReader::~FileReader()
{
close();
if (isOpen())
close();
}
std::string FileReader::filename() const

View File

@ -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);

View File

@ -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"))