stuff-from-scratch/src/core/file_utilities/File.cpp
2022-12-01 10:52:48 +00:00

225 lines
4 KiB
C++

#include "File.h"
#include "FileLogger.h"
#include "ByteUtils.h"
#include <streambuf>
#include <sstream>
File::File(std::filesystem::path path)
: mFullPath(path),
mInHandle(),
mOutHandle()
{
}
File::~File()
{
close();
}
std::string File::getExtension() const
{
return mFullPath.extension().string();
}
std::string File::dumpBinary()
{
open(AccessMode::Read);
std::stringstream sstr;
sstr << "Count | Binary | Decimal | ASCII \n";
unsigned count = 0;
while(mInHandle->peek() != EOF)
{
const unsigned char val = static_cast<unsigned char>(mInHandle->get());
const unsigned char ascii_val = std::isalpha(val) ? val : '.';
sstr << count << " | " << ByteUtils::toString(val) << " | " << static_cast<int>(val) << " | " << ascii_val << '\n';
if (count < 0 && count % 10 == 0)
{
sstr << "\n";
}
count++;
}
const auto out = sstr.str();
close();
return out;
}
std::ifstream* File::getInHandle() const
{
return mInHandle.get();
}
std::ofstream* File::getOutHandle() const
{
return mOutHandle.get();
}
std::optional<unsigned char> File::readNextByte()
{
if (!mInHandle)
{
if (!open(AccessMode::Read))
{
return std::nullopt;
}
}
if (mInHandle->good())
{
if (auto val = mInHandle->get(); val == EOF)
{
return std::nullopt;
}
else
{
return val;
}
}
else
{
return std::nullopt;
}
}
bool File::open(AccessMode accessMode)
{
if (mFullPath.is_absolute() && !std::filesystem::exists(mFullPath.parent_path()))
{
std::filesystem::create_directories(mFullPath.parent_path());
}
if(accessMode == AccessMode::Read)
{
auto flags = std::ifstream::in;
mInHandle = std::make_unique<std::ifstream>();
mInHandle->open(mFullPath, flags);
if (!mInHandle->is_open())
{
MLOG_ERROR("Failed to open file at :" << mFullPath);
return false;
}
}
else
{
auto flags = std::ofstream::out;
mOutHandle = std::make_unique<std::ofstream>();
mOutHandle->open(mFullPath, flags);
if (!mOutHandle->is_open())
{
MLOG_ERROR("Failed to open file at :" << mFullPath);
return false;
}
}
return true;
}
void File::close()
{
if(mOutHandle)
{
mOutHandle->close();
}
if(mInHandle)
{
mInHandle->close();
}
}
FileFormat::Format File::inferFormat() const
{
const auto extension = getExtension();
return FileFormat::InferFormat(extension);
}
void File::writeText(const std::string& text)
{
bool had_to_open{false};
if (!mOutHandle)
{
had_to_open = true;
if (!open(File::AccessMode::Write))
{
return;
}
}
(*mOutHandle) << text;
if (had_to_open)
{
close();
}
}
std::vector<std::string> File::readLines()
{
std::vector<std::string> content;
if (!pathExists())
{
return {};
}
if(!open(AccessMode::Read))
{
return {};
}
std::string str;
while(std::getline(*mInHandle, str))
{
content.push_back(str);
}
close();
return content;
}
std::string File::read()
{
if (!pathExists())
{
return {};
}
if(!open(AccessMode::Read))
{
return {};
}
std::stringstream buffer;
buffer << mInHandle->rdbuf();
close();
return buffer.str();
}
std::string File::getBaseFilename(const Path& path)
{
return path.stem().string();
}
std::string File::readText()
{
if (!pathExists())
{
return {};
}
if(!open(AccessMode::Read))
{
return {};
}
std::string str((std::istreambuf_iterator<char>(*mInHandle)),
std::istreambuf_iterator<char>());
return str;
}
bool File::pathExists() const
{
return std::filesystem::exists(mFullPath);
}