Initial test bootstrap.
This commit is contained in:
parent
6c618749f1
commit
4b308f6c32
94 changed files with 2543 additions and 681 deletions
|
@ -1,17 +1,116 @@
|
|||
#include "File.h"
|
||||
|
||||
#include "FileLogger.h"
|
||||
//#include "FileLogger.h"
|
||||
#include "ByteUtils.h"
|
||||
#include "Directory.h"
|
||||
#include "Result.h"
|
||||
|
||||
#include <streambuf>
|
||||
#include <sstream>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
File::File(std::filesystem::path path)
|
||||
: mFullPath(path),
|
||||
mInHandle(),
|
||||
mOutHandle()
|
||||
class FileImpl
|
||||
{
|
||||
public:
|
||||
void do_open(const FileSystemPath& path, File::AccessMode accessMode)
|
||||
{
|
||||
int flags{0};
|
||||
if (accessMode == File::AccessMode::Read)
|
||||
{
|
||||
flags |= O_RDONLY;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= O_WRONLY;
|
||||
flags |= O_CREAT;
|
||||
}
|
||||
|
||||
m_fd = ::open(path.as_string().raw(), flags);
|
||||
if (accessMode == File::AccessMode::Read)
|
||||
{
|
||||
m_open_for_read = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_open_for_write = true;
|
||||
}
|
||||
}
|
||||
|
||||
void do_close()
|
||||
{
|
||||
::close(m_fd);
|
||||
m_open_for_read = false;
|
||||
m_open_for_write = false;
|
||||
}
|
||||
|
||||
bool is_ok() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
bool is_open_for_read() const
|
||||
{
|
||||
return m_open_for_read;
|
||||
}
|
||||
|
||||
bool is_open_for_write() const
|
||||
{
|
||||
return m_open_for_write;
|
||||
}
|
||||
|
||||
Result<std::size_t> do_read(VecBytes& bytes)
|
||||
{
|
||||
errno = 0;
|
||||
const auto rc = ::read(m_fd, bytes.data(), bytes.capacity());
|
||||
if (rc < 0)
|
||||
{
|
||||
const auto last_err = errno;
|
||||
String msg(::strerror(last_err));
|
||||
return Result<std::size_t>(Error(msg));
|
||||
}
|
||||
return Result<std::size_t>(rc);
|
||||
}
|
||||
|
||||
std::size_t do_write(const VecBytes& bytes)
|
||||
{
|
||||
return ::write(m_fd, bytes.data(), bytes.size());
|
||||
}
|
||||
|
||||
std::size_t do_write(const Vector<char>& bytes, int size = -1)
|
||||
{
|
||||
if (size > -1)
|
||||
{
|
||||
return ::write(m_fd, bytes.data(), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ::write(m_fd, bytes.data(), bytes.size());
|
||||
}
|
||||
}
|
||||
|
||||
void update_size()
|
||||
{
|
||||
struct stat buf;
|
||||
::fstat(m_fd, &buf);
|
||||
m_size = buf.st_size;
|
||||
}
|
||||
|
||||
bool m_open_for_write{false};
|
||||
bool m_open_for_read{false};
|
||||
bool m_valid{false};
|
||||
std::size_t m_size{0};
|
||||
bool m_is_open{false};
|
||||
int m_fd{-1};
|
||||
};
|
||||
|
||||
File::File(const FileSystemPath& path)
|
||||
: m_impl(Ptr<FileImpl>::create()),
|
||||
m_path(path)
|
||||
{
|
||||
}
|
||||
|
||||
File::~File()
|
||||
|
@ -19,145 +118,149 @@ File::~File()
|
|||
close();
|
||||
}
|
||||
|
||||
std::string File::getExtension() const
|
||||
String File::getExtension() const
|
||||
{
|
||||
return mFullPath.extension().string();
|
||||
return m_path.extension();
|
||||
}
|
||||
|
||||
std::string File::dumpBinary()
|
||||
bool File::readBinary(VecBytes& buffer)
|
||||
{
|
||||
auto ok = open(AccessMode::Read, true);
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl->update_size();
|
||||
buffer.resize(m_impl->m_size);
|
||||
const auto result = m_impl->do_read(buffer);
|
||||
buffer.resize(result.value());
|
||||
return true;
|
||||
}
|
||||
|
||||
String File::readText()
|
||||
{
|
||||
VecBytes buffer;
|
||||
auto ok = open(AccessMode::Read, true);
|
||||
if (!ok)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
m_impl->update_size();
|
||||
buffer.resize(m_impl->m_size);
|
||||
const auto result = m_impl->do_read(buffer);
|
||||
if (!result.ok())
|
||||
{
|
||||
printf("Got error: %s\n", result.error().msg());
|
||||
return {};
|
||||
}
|
||||
|
||||
buffer.resize(result.value());
|
||||
return String(buffer);
|
||||
}
|
||||
|
||||
String File::dumpBinary()
|
||||
{
|
||||
open(AccessMode::Read);
|
||||
|
||||
std::stringstream sstr;
|
||||
sstr << "Count | Binary | Decimal | ASCII \n";
|
||||
String sstr;
|
||||
sstr << "Count | Binary | Decimal | Hex | ASCII \n";
|
||||
|
||||
VecBytes buffer;
|
||||
readBinary(buffer);
|
||||
|
||||
unsigned count = 0;
|
||||
while(mInHandle->peek() != EOF)
|
||||
/*
|
||||
for(const auto byte : buffer)
|
||||
{
|
||||
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';
|
||||
const auto ascii_val = std::isalpha(byte) ? byte : '.';
|
||||
String hex_sstr;
|
||||
hex_sstr << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(byte);
|
||||
|
||||
sstr << count << " | " << ByteUtils::toString(byte) << " | " << static_cast<int>(byte) << " | " << hex_sstr.str() << " | " << ascii_val << '\n';
|
||||
if (count % 10 == 0)
|
||||
{
|
||||
sstr << "\n";
|
||||
}
|
||||
count++;
|
||||
}
|
||||
const auto out = sstr.str();
|
||||
*/
|
||||
close();
|
||||
return out;
|
||||
return sstr;
|
||||
}
|
||||
|
||||
std::ifstream* File::getInHandle() const
|
||||
Optional<Byte> File::readNextByte()
|
||||
{
|
||||
return mInHandle.get();
|
||||
}
|
||||
|
||||
std::ofstream* File::getOutHandle() const
|
||||
{
|
||||
return mOutHandle.get();
|
||||
}
|
||||
|
||||
std::optional<unsigned char> File::readNextByte()
|
||||
{
|
||||
if (!mInHandle)
|
||||
if (!open(AccessMode::Read))
|
||||
{
|
||||
if (!open(AccessMode::Read))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (mInHandle->good())
|
||||
if (m_impl->is_ok())
|
||||
{
|
||||
if (auto val = mInHandle->get(); val == EOF)
|
||||
VecBytes buffer(1);
|
||||
m_impl->do_read(buffer);
|
||||
if (buffer[0] == EOF)
|
||||
{
|
||||
return std::nullopt;
|
||||
return {};
|
||||
}
|
||||
else
|
||||
{
|
||||
return val;
|
||||
return buffer[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::nullopt;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
bool File::open(AccessMode accessMode)
|
||||
bool File::open(AccessMode accessMode, bool binary)
|
||||
{
|
||||
if (mFullPath.is_absolute() && !std::filesystem::exists(mFullPath.parent_path()))
|
||||
if (m_path.is_absolute() && !m_path.parent_path().exists())
|
||||
{
|
||||
std::filesystem::create_directories(mFullPath.parent_path());
|
||||
Directory::create(m_path.parent_path(), true);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
m_impl->do_open(m_path, accessMode);
|
||||
return true;
|
||||
}
|
||||
|
||||
void File::close()
|
||||
{
|
||||
if(mOutHandle)
|
||||
{
|
||||
mOutHandle->close();
|
||||
}
|
||||
if(mInHandle)
|
||||
{
|
||||
mInHandle->close();
|
||||
}
|
||||
m_impl->do_close();
|
||||
}
|
||||
|
||||
FileFormat::Format File::inferFormat() const
|
||||
{
|
||||
const auto extension = getExtension();
|
||||
return FileFormat::inferFormat(extension);
|
||||
//const auto extension = getExtension();
|
||||
//return FileFormat::inferFormat(extension);
|
||||
return {};
|
||||
}
|
||||
|
||||
void File::writeText(const std::string& text)
|
||||
void File::writeText(const String& text)
|
||||
{
|
||||
bool had_to_open{false};
|
||||
if (!mOutHandle)
|
||||
if (!m_impl->is_open_for_write())
|
||||
{
|
||||
had_to_open = true;
|
||||
if (!open(File::AccessMode::Write))
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_impl->do_open(m_path, File::AccessMode::Write);
|
||||
}
|
||||
|
||||
(*mOutHandle) << text;
|
||||
m_impl->do_write(text.data(), text.data().size() - 1);
|
||||
|
||||
if (had_to_open)
|
||||
{
|
||||
close();
|
||||
m_impl->do_close();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> File::readLines()
|
||||
Vector<String> File::readLines()
|
||||
{
|
||||
std::vector<std::string> content;
|
||||
Vector<String> content;
|
||||
|
||||
/*
|
||||
if (!pathExists())
|
||||
{
|
||||
return {};
|
||||
|
@ -168,18 +271,20 @@ std::vector<std::string> File::readLines()
|
|||
return {};
|
||||
}
|
||||
|
||||
std::string str;
|
||||
String str;
|
||||
while(std::getline(*mInHandle, str))
|
||||
{
|
||||
content.push_back(str);
|
||||
}
|
||||
|
||||
close();
|
||||
*/
|
||||
return content;
|
||||
}
|
||||
|
||||
std::string File::read()
|
||||
String File::read()
|
||||
{
|
||||
/*
|
||||
if (!pathExists())
|
||||
{
|
||||
return {};
|
||||
|
@ -190,31 +295,16 @@ std::string File::read()
|
|||
return {};
|
||||
}
|
||||
|
||||
std::stringstream buffer;
|
||||
String buffer;
|
||||
buffer << mInHandle->rdbuf();
|
||||
|
||||
close();
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
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;
|
||||
*/
|
||||
String buffer;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool File::pathExists() const
|
||||
{
|
||||
return std::filesystem::exists(mFullPath);
|
||||
return m_path.exists();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue