240 lines
5.4 KiB
C++
240 lines
5.4 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: FileStream.Generic.cpp
|
|
Date: 2021-6-12
|
|
Author: Reece
|
|
***/
|
|
// TODO: 64
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "FS.hpp"
|
|
#include "FileStream.Generic.hpp"
|
|
|
|
#if defined(_AURUNTIME_GENERICFILESTREAM)
|
|
|
|
namespace Aurora::IO::FS
|
|
{
|
|
static const AuUInt64 kFileCopyBlock = 0x4000; // 16KiB
|
|
|
|
template<typename T>
|
|
class StdFS : public IFileStream
|
|
{
|
|
public:
|
|
void Close() override
|
|
{
|
|
try
|
|
{
|
|
if (stream_.is_open())
|
|
{
|
|
stream_.close();
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
SysPanic("Critical File IO error");
|
|
}
|
|
}
|
|
|
|
bool Open(const AuString &str)
|
|
{
|
|
try
|
|
{
|
|
#if defined(NO_STD_FS)
|
|
stream_.open(NormalizePathRet(str), std::ios_base::binary)
|
|
#else
|
|
stream_.open(std::filesystem::u8path(NormalizePathRet(str)), std::ios_base::binary);
|
|
#endif
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
return stream_.is_open();
|
|
}
|
|
|
|
AuUInt64 GetOffset() override
|
|
{
|
|
return offset_;
|
|
}
|
|
|
|
AuUInt64 GetLength() override
|
|
{
|
|
auto startingOffset = GetOffset();
|
|
GoToEof();
|
|
auto ret = GetOffset();
|
|
SetOffset(startingOffset);
|
|
return startingOffset;
|
|
}
|
|
|
|
virtual void Flush()
|
|
{
|
|
};
|
|
|
|
virtual void GoToEof() = 0;
|
|
protected:
|
|
AuUInt64 offset_ = 0;
|
|
T stream_;
|
|
};
|
|
|
|
class StdReadFS : public StdFS<std::ifstream>
|
|
{
|
|
public:
|
|
void GoToEof() override
|
|
{
|
|
stream_.seekg(0, std::ios_base::end);
|
|
offset_ = stream_.tellg();
|
|
}
|
|
|
|
bool SetOffset(AuUInt64 offset) override
|
|
{
|
|
try
|
|
{
|
|
stream_.seekg(offset, std::ios_base::beg);
|
|
offset_ = offset;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Read(const Memory::MemoryViewStreamWrite ¶meters) override
|
|
{
|
|
try
|
|
{
|
|
if (!stream_.is_open())
|
|
{
|
|
return false;
|
|
}
|
|
stream_.read(reinterpret_cast<char *>(parameters.ptr), parameters.length);
|
|
parameters.outVariable = stream_.gcount();
|
|
offset_ += parameters.outVariable;
|
|
return true;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool Write(const Memory::MemoryViewStreamRead & parameters) override
|
|
{
|
|
return false;
|
|
}
|
|
};
|
|
|
|
class StdWriteFS : public StdFS<std::ofstream>
|
|
{
|
|
public:
|
|
void GoToEof() override
|
|
{
|
|
stream_.seekp(0, std::ios_base::end);
|
|
offset_ = stream_.tellp();
|
|
}
|
|
|
|
bool Read(const Memory::MemoryViewStreamWrite ¶meters) override
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool Write(const Memory::MemoryViewStreamRead & parameters) override
|
|
{
|
|
try
|
|
{
|
|
if (!stream_.is_open())
|
|
{
|
|
return false;
|
|
}
|
|
auto start = stream_.tellp();
|
|
stream_.write(reinterpret_cast<const char *>(parameters.ptr), parameters.length);
|
|
parameters.outVariable = stream_.tellp() - start;
|
|
offset_ += parameters.outVariable;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool SetOffset(AuUInt64 offset) override
|
|
{
|
|
try
|
|
{
|
|
stream_.seekp(offset, std::ios_base::beg);
|
|
offset_ = offset;
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void Flush() override
|
|
{
|
|
try
|
|
{
|
|
stream_.flush();
|
|
}
|
|
catch (...)
|
|
{
|
|
LogWarn("Couldn't flush file stream");
|
|
}
|
|
}
|
|
};
|
|
|
|
AUKN_SYM IFileStream *OpenReadNew(const AuString &path)
|
|
{
|
|
auto stream = _new StdReadFS();
|
|
if (!stream)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
if (!stream->Open(NormalizePathRet(path)))
|
|
{
|
|
delete stream;
|
|
return nullptr;
|
|
}
|
|
|
|
return stream;
|
|
}
|
|
|
|
AUKN_SYM void OpenReadRelease(IFileStream * that)
|
|
{
|
|
SafeDelete<StdReadFS *>(that);
|
|
}
|
|
|
|
AUKN_SYM IFileStream *OpenWriteNew(const AuString &path)
|
|
{
|
|
auto pathex = NormalizePathRet(path);
|
|
|
|
auto stream = _new StdWriteFS();
|
|
if (!stream)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
CreateDirectories(pathex, true);
|
|
|
|
if (!stream->Open(pathex))
|
|
{
|
|
delete stream;
|
|
return nullptr;
|
|
}
|
|
|
|
return stream;
|
|
}
|
|
|
|
AUKN_SYM void OpenWriteRelease(IFileStream * that)
|
|
{
|
|
SafeDelete<StdWriteFS *>(that);
|
|
}
|
|
}
|
|
#endif
|