First commit.
This commit is contained in:
307
src/IO/File_UNX.cpp
Normal file
307
src/IO/File_UNX.cpp
Normal file
@@ -0,0 +1,307 @@
|
||||
#include "../../include/IO/File_UNX.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
|
||||
namespace lwe
|
||||
{
|
||||
File::~File()
|
||||
{
|
||||
if (map != MAP_FAILED && munmap(map, mapSize) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
if (hdl >= 0 && close(hdl) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
File::File()
|
||||
: hdl(-1), map(MAP_FAILED), mapSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
File::File(const Str_8 &filePath, const Mode mode, const Disposition disposition)
|
||||
: BaseFile(filePath, mode, disposition), hdl(-1), map(MAP_FAILED), mapSize(0)
|
||||
{
|
||||
int linuxMode = 0;
|
||||
switch (mode)
|
||||
{
|
||||
case Mode::READ:
|
||||
linuxMode = O_RDONLY;
|
||||
break;
|
||||
case Mode::WRITE:
|
||||
linuxMode = O_WRONLY;
|
||||
break;
|
||||
case Mode::READ_WRITE:
|
||||
linuxMode = O_RDWR;
|
||||
break;
|
||||
}
|
||||
|
||||
int linuxDisp = 0;
|
||||
switch (disposition)
|
||||
{
|
||||
case Disposition::CREATE_PERSISTENT:
|
||||
linuxDisp = O_CREAT;
|
||||
break;
|
||||
case Disposition::CREATE:
|
||||
linuxDisp = O_CREAT | O_EXCL;
|
||||
break;
|
||||
case Disposition::OPEN_PERSISTENT:
|
||||
linuxDisp = O_CREAT;
|
||||
break;
|
||||
case Disposition::OPEN:
|
||||
linuxDisp = 0;
|
||||
break;
|
||||
case Disposition::TRUNCATE:
|
||||
linuxDisp = O_TRUNC;
|
||||
break;
|
||||
}
|
||||
|
||||
hdl = open64(path, linuxMode | linuxDisp, S_IRUSR | S_IWUSR);
|
||||
if (hdl == -1)
|
||||
{
|
||||
SInt_32 code = errno;
|
||||
if (code == EEXIST && (disposition == Disposition::CREATE_PERSISTENT || disposition == Disposition::OPEN_PERSISTENT))
|
||||
{
|
||||
hdl = open64(path, linuxMode, S_IRUSR | S_IWUSR);
|
||||
if (hdl == -1)
|
||||
LWE_LOG_INT("Error", 0, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (code == ENOENT)
|
||||
LWE_LOG_INT("Error", 0, "File at filepath, \"" + filePath + "\" not found.");
|
||||
else
|
||||
LWE_LOG_INT("Error", 0, strerror(code));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File::File(File&& file) noexcept
|
||||
: BaseFile(std::move(file)), hdl(file.hdl), map(file.map), mapSize(file.mapSize)
|
||||
{
|
||||
file.hdl = -1;
|
||||
file.map = MAP_FAILED;
|
||||
file.mapSize = 0;
|
||||
}
|
||||
|
||||
File::File(const File &file)
|
||||
: BaseFile(file), hdl(-1), map(MAP_FAILED), mapSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
File& File::operator=(File&& file) noexcept
|
||||
{
|
||||
if (this == &file)
|
||||
return *this;
|
||||
|
||||
BaseFile::operator=(std::move(file));
|
||||
|
||||
hdl = file.hdl;
|
||||
map = file.map;
|
||||
mapSize = file.mapSize;
|
||||
|
||||
file.hdl = -1;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
File& File::operator=(const File &file)
|
||||
{
|
||||
if (this == &file)
|
||||
return *this;
|
||||
|
||||
BaseFile::operator=(file);
|
||||
|
||||
hdl = -1;
|
||||
map = MAP_FAILED;
|
||||
mapSize = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
File::operator const Byte*() const
|
||||
{
|
||||
return (const Byte*)map;
|
||||
}
|
||||
|
||||
File::operator Byte*()
|
||||
{
|
||||
return (Byte*)map;
|
||||
}
|
||||
|
||||
void File::Release()
|
||||
{
|
||||
if (IsMapped() && munmap(map, mapSize) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||
map = MAP_FAILED;
|
||||
mapSize = 0;
|
||||
|
||||
if (IsValid() && close(hdl) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
||||
hdl = -1;
|
||||
}
|
||||
|
||||
bool File::IsMapped() const
|
||||
{
|
||||
return map != MAP_FAILED;
|
||||
}
|
||||
|
||||
UInt_64 File::MapSize() const
|
||||
{
|
||||
return mapSize;
|
||||
}
|
||||
|
||||
void File::Map(const UInt_64 offset, const UInt_64 size)
|
||||
{
|
||||
if (!IsValid() || IsMapped())
|
||||
return;
|
||||
|
||||
int linuxMode = 0;
|
||||
switch (mode)
|
||||
{
|
||||
case Mode::READ:
|
||||
linuxMode = PROT_READ;
|
||||
break;
|
||||
case Mode::WRITE:
|
||||
linuxMode = PROT_WRITE;
|
||||
break;
|
||||
case Mode::READ_WRITE:
|
||||
linuxMode = PROT_READ | PROT_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
map = mmap64(nullptr, size, linuxMode, MAP_SHARED, hdl, (off64_t)offset);
|
||||
if (map == MAP_FAILED)
|
||||
{
|
||||
LWE_LOG_INT("Error", 0, "Failed to map with error #" + Str_8::FromNum(errno) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
mapSize = size;
|
||||
}
|
||||
|
||||
void File::Unmap()
|
||||
{
|
||||
if (!IsValid() || !IsMapped())
|
||||
return;
|
||||
|
||||
if (munmap(map, mapSize) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
map = MAP_FAILED;
|
||||
mapSize = 0;
|
||||
}
|
||||
|
||||
void File::FlushMap()
|
||||
{
|
||||
if (!IsValid() || !IsMapped())
|
||||
return;
|
||||
|
||||
if (msync((void*)map, mapSize, MS_SYNC) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to flush view with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
UInt_64 File::Write(const Byte *const data, const UInt_64 size)
|
||||
{
|
||||
if (!IsValid() || IsMapped())
|
||||
return 0;
|
||||
|
||||
SInt_64 written = 0;
|
||||
written = write(hdl, data, size);
|
||||
if (written == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to write to file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
return (UInt_64)written;
|
||||
}
|
||||
|
||||
UInt_64 File::Read(Byte *const data, const UInt_64 size)
|
||||
{
|
||||
if (!IsValid() || IsMapped())
|
||||
return 0;
|
||||
|
||||
SInt_64 read = 0;
|
||||
read = ::read(hdl, data, (size_t)size);
|
||||
if (read == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to read from file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
return (UInt_64)read;
|
||||
}
|
||||
|
||||
void File::Seek(UInt_64 index)
|
||||
{
|
||||
if (!IsValid() || IsMapped())
|
||||
return;
|
||||
|
||||
if (lseek64(hdl, (off64_t)index, SEEK_SET) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
void File::SeekBeginning()
|
||||
{
|
||||
if (!IsValid() || IsMapped())
|
||||
return;
|
||||
|
||||
if (lseek64(hdl, 0, SEEK_SET) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
void File::SeekEnd()
|
||||
{
|
||||
if (!IsValid() || IsMapped())
|
||||
return;
|
||||
|
||||
if (lseek64(hdl, 0, SEEK_END) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
void File::Truncate(const UInt_64 size)
|
||||
{
|
||||
if (!IsValid() || IsMapped())
|
||||
return;
|
||||
|
||||
if (ftruncate64(hdl, (off64_t)size) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to truncate with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
UInt_64 File::Size() const
|
||||
{
|
||||
struct stat64 info = {};
|
||||
|
||||
if (fstat64(hdl, &info) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to retrieve file size with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
return info.st_size;
|
||||
}
|
||||
|
||||
bool File::IsValid() const
|
||||
{
|
||||
return hdl >= 0;
|
||||
}
|
||||
|
||||
void File::Rename_32(const Str_32& filePath, const Str_32& newName)
|
||||
{
|
||||
Rename_8(UTF::To_8(filePath), UTF::To_8(newName));
|
||||
}
|
||||
|
||||
void File::Rename_16(const Str_16& filePath, const Str_16& newName)
|
||||
{
|
||||
Rename_8(UTF::To_8(filePath), UTF::To_8(newName));
|
||||
}
|
||||
|
||||
void File::Rename_8(const Str_8& filePath, const Str_8& newName)
|
||||
{
|
||||
UInt_64 index = 0;
|
||||
Str_8 path;
|
||||
|
||||
if (filePath.Find("/", &index, SearchPattern::RIGHT_LEFT) || filePath.Find("\\", &index, SearchPattern::RIGHT_LEFT))
|
||||
path = filePath.Sub(0, index);
|
||||
|
||||
if (rename(filePath, path + newName) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to rename file with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user