Start proper stream support.
This commit is contained in:
parent
5183aa821a
commit
e3e03dc31f
34 changed files with 421 additions and 402 deletions
|
@ -13,9 +13,12 @@ g++ $SOURCE_DIR/main.cpp \
|
|||
$CORE_SRC_DIR/data_structures/String.cpp \
|
||||
$CORE_SRC_DIR/filesystem/FileSystemPath.cpp \
|
||||
$CORE_SRC_DIR/filesystem/File.cpp \
|
||||
$CORE_SRC_DIR/filesystem/FileFormats.cpp \
|
||||
$CORE_SRC_DIR/filesystem/posix/FilePosixImpl.cpp \
|
||||
$CORE_SRC_DIR/filesystem/Directory.cpp \
|
||||
$CORE_SRC_DIR/logging/ConsoleLogger.cpp \
|
||||
$CORE_SRC_DIR/logging/Logger.cpp \
|
||||
$CORE_SRC_DIR/system/process/Process.cpp \
|
||||
$CORE_SRC_DIR/time/Time.cpp \
|
||||
-o builder -g -fno-exceptions -fno-rtti \
|
||||
-I$CORE_SRC_DIR/base_types \
|
||||
|
@ -23,6 +26,7 @@ g++ $SOURCE_DIR/main.cpp \
|
|||
-I$CORE_SRC_DIR/data_structures \
|
||||
-I$CORE_SRC_DIR/encoding \
|
||||
-I$CORE_SRC_DIR/filesystem \
|
||||
-I$CORE_SRC_DIR/filesystem/posix \
|
||||
-I$CORE_SRC_DIR/logging \
|
||||
-I$CORE_SRC_DIR/memory \
|
||||
-I$CORE_SRC_DIR/system/process \
|
||||
|
|
|
@ -10,14 +10,14 @@ public:
|
|||
|
||||
BuildLibrary(const FileSystemPath& build_config);
|
||||
|
||||
Status scan();
|
||||
|
||||
const Vector<FileSystemPath>& get_sources() const;
|
||||
|
||||
const Vector<FileSystemPath>& get_include_dirs() const;
|
||||
|
||||
const String& get_name() const;
|
||||
|
||||
Status scan();
|
||||
|
||||
private:
|
||||
FileSystemPath m_build_config;
|
||||
Vector<FileSystemPath> m_sources;
|
||||
|
|
|
@ -25,6 +25,13 @@ Status::Status(const Error& err)
|
|||
|
||||
}
|
||||
|
||||
Status Status::with_errno(const String& prefix_msg)
|
||||
{
|
||||
Status ret;
|
||||
ret.on_errno(prefix_msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Status::on_errno(const String& prefix_msg)
|
||||
{
|
||||
String errno_msg(::strerror(errno));
|
||||
|
|
|
@ -48,6 +48,8 @@ public:
|
|||
|
||||
Status(const Error& err);
|
||||
|
||||
static Status with_errno(const String& prefix_msg);
|
||||
|
||||
void on_errno(const String& prefix_msg);
|
||||
|
||||
const Error& error() const;
|
||||
|
|
|
@ -146,6 +146,17 @@ void String::to_bytes(Vector<Byte>& bytes) const
|
|||
}
|
||||
}
|
||||
|
||||
size_t String::length(const char* arr)
|
||||
{
|
||||
size_t len{0};
|
||||
while(*arr != '\0')
|
||||
{
|
||||
arr++;
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void String::append(const Vector<Byte>& data)
|
||||
{
|
||||
if (data.empty())
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "Vector.h"
|
||||
#include "Pair.h"
|
||||
#include "Index.h"
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
@ -29,6 +29,8 @@ public:
|
|||
using erasePredicate = std::function<bool(char)>;
|
||||
void eraseIf(erasePredicate func);
|
||||
|
||||
static size_t length(const char* arr);
|
||||
|
||||
bool is_whitespace() const;
|
||||
|
||||
void push_back(char c);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
#include "String.h"
|
||||
|
||||
class Bits
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
|
||||
#include "String.h"
|
||||
#include "Vector.h"
|
||||
|
|
31
src/base/core/filesystem/BinaryFile.cpp
Normal file
31
src/base/core/filesystem/BinaryFile.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "BinaryFile.h"
|
||||
|
||||
Status BinaryFile::to_readable(InputStream<Byte>& input,
|
||||
OutputStream<Byte>& output)
|
||||
{
|
||||
String sstr;
|
||||
sstr << "Count | Binary | Decimal | Hex | ASCII \n";
|
||||
|
||||
Byte b{0};
|
||||
while(input.get(b))
|
||||
{
|
||||
unsigned count = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
for(const auto byte : buffer)
|
||||
{
|
||||
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 << " | " << Bits::toString(byte) << " | " << static_cast<int>(byte) << " | " << hex_sstr.str() << " | " << ascii_val << '\n';
|
||||
if (count % 10 == 0)
|
||||
{
|
||||
sstr << "\n";
|
||||
}
|
||||
count++;
|
||||
}
|
||||
*/
|
||||
return {};
|
||||
}
|
12
src/base/core/filesystem/BinaryFile.h
Normal file
12
src/base/core/filesystem/BinaryFile.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "Byte.h"
|
||||
#include "Error.h"
|
||||
|
||||
class BinaryFile
|
||||
{
|
||||
public:
|
||||
static Status to_readable(InputStream<Byte>& input,
|
||||
OutputStream<Byte>& output);
|
||||
};
|
|
@ -3,148 +3,10 @@
|
|||
#include "Char.h"
|
||||
#include "Directory.h"
|
||||
#include "Result.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
class FileImpl
|
||||
{
|
||||
public:
|
||||
Status 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;
|
||||
}
|
||||
errno = 0;
|
||||
m_fd = ::open(path.str().raw(), flags);
|
||||
if (m_fd < 0)
|
||||
{
|
||||
Status ret;
|
||||
ret.on_errno("Failed to open file with");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (accessMode == File::AccessMode::Read)
|
||||
{
|
||||
m_open_for_read = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_open_for_write = true;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Status do_close()
|
||||
{
|
||||
errno = 0;
|
||||
const auto rc = ::close(m_fd);
|
||||
if (rc < 0)
|
||||
{
|
||||
Status ret;
|
||||
ret.on_errno("Failed to close file with");
|
||||
return ret;
|
||||
}
|
||||
m_open_for_read = false;
|
||||
m_open_for_write = false;
|
||||
return {};
|
||||
}
|
||||
|
||||
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<size_t> do_read(VecBytes& bytes)
|
||||
{
|
||||
errno = 0;
|
||||
const auto rc = ::read(m_fd, bytes.data(), bytes.capacity());
|
||||
if (rc < 0)
|
||||
{
|
||||
const auto msg = _s("Error in read impl | ") + Error::from_errno();
|
||||
return Result<size_t>(Error(msg));
|
||||
}
|
||||
return Result<size_t>(rc);
|
||||
}
|
||||
|
||||
Result<size_t> do_write(const VecBytes& bytes)
|
||||
{
|
||||
errno = 0;
|
||||
const auto rc = ::write(m_fd, bytes.data(), bytes.size());
|
||||
if (rc < 0)
|
||||
{
|
||||
const auto msg = _s("Error in write impl | ") + Error::from_errno();
|
||||
return Result<size_t>(Error(msg));
|
||||
}
|
||||
return Result<size_t>(rc);
|
||||
}
|
||||
|
||||
Result<size_t> do_write(const Vector<char>& bytes, int size = -1)
|
||||
{
|
||||
errno = 0;
|
||||
int rc = 0;
|
||||
if (size > -1)
|
||||
{
|
||||
rc = ::write(m_fd, bytes.data(), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = ::write(m_fd, bytes.data(), bytes.size());
|
||||
}
|
||||
if (rc < 0)
|
||||
{
|
||||
const auto msg = _s("Error in write impl | ") + Error::from_errno();
|
||||
return Result<size_t>(Error(msg));
|
||||
}
|
||||
return Result<size_t>(rc);
|
||||
}
|
||||
|
||||
Status update_size()
|
||||
{
|
||||
struct stat buf;
|
||||
const auto rc = ::fstat(m_fd, &buf);
|
||||
if (rc != 0)
|
||||
{
|
||||
Status ret;
|
||||
ret.on_errno("Failed to get size with fstat");
|
||||
return ret;
|
||||
}
|
||||
m_size = buf.st_size;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool m_open_for_write{false};
|
||||
bool m_open_for_read{false};
|
||||
bool m_valid{false};
|
||||
size_t m_size{0};
|
||||
bool m_is_open{false};
|
||||
int m_fd{-1};
|
||||
};
|
||||
#include "FilePosixImpl.h"
|
||||
|
||||
File::File(const FileSystemPath& path)
|
||||
: m_impl(Ptr<FileImpl>::create()),
|
||||
: m_impl(Ptr<FilePosixImpl>::create()),
|
||||
m_path(path)
|
||||
{
|
||||
}
|
||||
|
@ -154,23 +16,46 @@ File::~File()
|
|||
close();
|
||||
}
|
||||
|
||||
Status File::close()
|
||||
{
|
||||
return m_impl->do_close();
|
||||
}
|
||||
|
||||
bool File::exists() const
|
||||
{
|
||||
return m_path.exists();
|
||||
}
|
||||
|
||||
String File::getExtension() const
|
||||
{
|
||||
return m_path.extension();
|
||||
}
|
||||
|
||||
Status File::readBinary(VecBytes& buffer)
|
||||
FileFormat::Format File::inferFormat() const
|
||||
{
|
||||
auto status = open(AccessMode::Read, true);
|
||||
if (!status.ok())
|
||||
const auto extension = getExtension();
|
||||
return FileFormat::inferFormat(extension);
|
||||
}
|
||||
|
||||
Status File::open(AccessMode accessMode)
|
||||
{
|
||||
if (m_path.is_absolute() && !m_path.parent_path().exists())
|
||||
{
|
||||
return status;
|
||||
Directory::create(m_path.parent_path(), true);
|
||||
}
|
||||
return m_impl->do_open(m_path, accessMode);
|
||||
}
|
||||
|
||||
Status File::read(VecBytes& buffer)
|
||||
{
|
||||
if (const auto rc = open(AccessMode::Read); !rc.ok())
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
status = m_impl->update_size();
|
||||
if (!status.ok())
|
||||
if (const auto rc = m_impl->update_size(); !rc.ok())
|
||||
{
|
||||
return status;
|
||||
return rc;
|
||||
}
|
||||
|
||||
buffer.resize(m_impl->m_size);
|
||||
|
@ -183,17 +68,15 @@ Status File::readBinary(VecBytes& buffer)
|
|||
return {};
|
||||
}
|
||||
|
||||
Status File::readText(String& ret)
|
||||
Status File::read(String& ret)
|
||||
{
|
||||
auto status = open(AccessMode::Read, true);
|
||||
if (!status.ok())
|
||||
if (const auto rc = open(AccessMode::Read); !rc.ok())
|
||||
{
|
||||
return status;
|
||||
return rc;
|
||||
}
|
||||
|
||||
VecBytes buffer;
|
||||
status = m_impl->update_size();
|
||||
if (status.ok() && m_impl->m_size > 0)
|
||||
if (const auto rc = m_impl->update_size(); rc.ok() && m_impl->m_size > 0)
|
||||
{
|
||||
buffer.resize(m_impl->m_size);
|
||||
const auto result = m_impl->do_read(buffer);
|
||||
|
@ -232,85 +115,7 @@ Status File::readText(String& ret)
|
|||
return {};
|
||||
}
|
||||
|
||||
String File::dumpBinary()
|
||||
{
|
||||
open(AccessMode::Read);
|
||||
|
||||
String sstr;
|
||||
sstr << "Count | Binary | Decimal | Hex | ASCII \n";
|
||||
|
||||
VecBytes buffer;
|
||||
readBinary(buffer);
|
||||
|
||||
unsigned count = 0;
|
||||
/*
|
||||
for(const auto byte : buffer)
|
||||
{
|
||||
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 << " | " << Bits::toString(byte) << " | " << static_cast<int>(byte) << " | " << hex_sstr.str() << " | " << ascii_val << '\n';
|
||||
if (count % 10 == 0)
|
||||
{
|
||||
sstr << "\n";
|
||||
}
|
||||
count++;
|
||||
}
|
||||
*/
|
||||
close();
|
||||
return sstr;
|
||||
}
|
||||
|
||||
Optional<Byte> File::readNextByte()
|
||||
{
|
||||
if (!open(AccessMode::Read).ok())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (m_impl->is_ok())
|
||||
{
|
||||
VecBytes buffer(1);
|
||||
m_impl->do_read(buffer);
|
||||
if (buffer[0] == EOF)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
else
|
||||
{
|
||||
return buffer[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
Status File::open(AccessMode accessMode, bool binary)
|
||||
{
|
||||
if (m_path.is_absolute() && !m_path.parent_path().exists())
|
||||
{
|
||||
Directory::create(m_path.parent_path(), true);
|
||||
}
|
||||
|
||||
return m_impl->do_open(m_path, accessMode);
|
||||
}
|
||||
|
||||
Status File::close()
|
||||
{
|
||||
return m_impl->do_close();
|
||||
}
|
||||
|
||||
FileFormat::Format File::inferFormat() const
|
||||
{
|
||||
//const auto extension = getExtension();
|
||||
//return FileFormat::inferFormat(extension);
|
||||
return {};
|
||||
}
|
||||
|
||||
Status File::writeText(const String& text)
|
||||
Status File::write(const String& text)
|
||||
{
|
||||
bool had_to_open{false};
|
||||
Status status;
|
||||
|
@ -334,54 +139,4 @@ Status File::writeText(const String& text)
|
|||
status = m_impl->do_close();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
Status File::readLines(Vector<String>& lines)
|
||||
{
|
||||
/*
|
||||
if (!pathExists())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if(!open(AccessMode::Read))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
String str;
|
||||
while(std::getline(*mInHandle, str))
|
||||
{
|
||||
content.push_back(str);
|
||||
}
|
||||
|
||||
close();
|
||||
*/
|
||||
return {};
|
||||
}
|
||||
|
||||
Status File::read(String& ret)
|
||||
{
|
||||
/*
|
||||
if (!pathExists())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if(!open(AccessMode::Read))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
String buffer;
|
||||
buffer << mInHandle->rdbuf();
|
||||
|
||||
close();
|
||||
*/
|
||||
return {};
|
||||
}
|
||||
|
||||
bool File::exists() const
|
||||
{
|
||||
return m_path.exists();
|
||||
}
|
||||
}
|
|
@ -2,20 +2,18 @@
|
|||
|
||||
#include "FileFormats.h"
|
||||
#include "FileSystemPath.h"
|
||||
#include "Optional.h"
|
||||
#include "String.h"
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
#include "Pointer.h"
|
||||
|
||||
class FileImpl;
|
||||
class FilePosixImpl;
|
||||
|
||||
class File
|
||||
{
|
||||
public:
|
||||
enum class AccessMode{
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite
|
||||
Write
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -25,29 +23,26 @@ public:
|
|||
|
||||
Status close();
|
||||
|
||||
String dumpBinary();
|
||||
bool exists() const;
|
||||
|
||||
bool finished() const;
|
||||
|
||||
String getExtension() const;
|
||||
|
||||
FileFormat::Format inferFormat() const;
|
||||
|
||||
Status readText(String& buffer);
|
||||
Status open(AccessMode mode);
|
||||
|
||||
Status readLines(Vector<String>& lines);
|
||||
Status read(VecBytes& bytes);
|
||||
|
||||
Status read(String& buffer);
|
||||
|
||||
bool exists() const;
|
||||
Status write(const String& buffer);
|
||||
|
||||
Status open(AccessMode mode, bool binary = false);
|
||||
|
||||
Status readBinary(VecBytes& bytes);
|
||||
|
||||
Optional<Byte> readNextByte();
|
||||
|
||||
Status writeText(const String& text);
|
||||
Status write(const VecBytes& bytes);
|
||||
|
||||
private:
|
||||
Ptr<FileImpl> m_impl;
|
||||
Ptr<FilePosixImpl> m_impl;
|
||||
FileSystemPath m_path;
|
||||
bool mGotEndOfFile{false};
|
||||
};
|
||||
|
|
121
src/base/core/filesystem/posix/FilePosixImpl.cpp
Normal file
121
src/base/core/filesystem/posix/FilePosixImpl.cpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include "FilePosixImpl.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
Status FilePosixImpl::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;
|
||||
}
|
||||
errno = 0;
|
||||
m_fd = ::open(path.str().raw(), flags);
|
||||
if (m_fd < 0)
|
||||
{
|
||||
return Status::with_errno("Failed to open file with");
|
||||
}
|
||||
|
||||
if (accessMode == File::AccessMode::Read)
|
||||
{
|
||||
m_open_for_read = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_open_for_write = true;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Status FilePosixImpl::do_close()
|
||||
{
|
||||
errno = 0;
|
||||
if (const auto rc = ::close(m_fd); rc < 0)
|
||||
{
|
||||
Status::with_errno("Failed to close file with");
|
||||
}
|
||||
m_open_for_read = false;
|
||||
m_open_for_write = false;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool FilePosixImpl::is_ok() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
bool FilePosixImpl::is_open_for_read() const
|
||||
{
|
||||
return m_open_for_read;
|
||||
}
|
||||
|
||||
bool FilePosixImpl::is_open_for_write() const
|
||||
{
|
||||
return m_open_for_write;
|
||||
}
|
||||
|
||||
Result<size_t> FilePosixImpl::do_read(VecBytes& bytes)
|
||||
{
|
||||
errno = 0;
|
||||
const auto rc = ::read(m_fd, bytes.data(), bytes.capacity());
|
||||
if (rc < 0)
|
||||
{
|
||||
const auto msg = _s("Error in read impl | ") + Error::from_errno();
|
||||
return Result<size_t>(Error(msg));
|
||||
}
|
||||
return Result<size_t>(rc);
|
||||
}
|
||||
|
||||
Result<size_t> FilePosixImpl::do_write(const VecBytes& bytes)
|
||||
{
|
||||
errno = 0;
|
||||
const auto rc = ::write(m_fd, bytes.data(), bytes.size());
|
||||
if (rc < 0)
|
||||
{
|
||||
const auto msg = _s("Error in write impl | ") + Error::from_errno();
|
||||
return Result<size_t>(Error(msg));
|
||||
}
|
||||
return Result<size_t>(rc);
|
||||
}
|
||||
|
||||
Result<size_t> FilePosixImpl::do_write(const Vector<char>& bytes, int size)
|
||||
{
|
||||
errno = 0;
|
||||
int rc = 0;
|
||||
if (size > -1)
|
||||
{
|
||||
rc = ::write(m_fd, bytes.data(), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = ::write(m_fd, bytes.data(), bytes.size());
|
||||
}
|
||||
if (rc < 0)
|
||||
{
|
||||
const auto msg = _s("Error in write impl | ") + Error::from_errno();
|
||||
return Result<size_t>(Error(msg));
|
||||
}
|
||||
return Result<size_t>(rc);
|
||||
}
|
||||
|
||||
Status FilePosixImpl::update_size()
|
||||
{
|
||||
struct stat buf;
|
||||
if (const auto rc = ::fstat(m_fd, &buf); rc != 0)
|
||||
{
|
||||
return Status::with_errno("Failed to get size with fstat");
|
||||
}
|
||||
m_size = buf.st_size;
|
||||
return {};
|
||||
}
|
34
src/base/core/filesystem/posix/FilePosixImpl.h
Normal file
34
src/base/core/filesystem/posix/FilePosixImpl.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include "FileSystemPath.h"
|
||||
#include "File.h"
|
||||
|
||||
class FilePosixImpl
|
||||
{
|
||||
public:
|
||||
Status do_open(const FileSystemPath& path,
|
||||
File::AccessMode accessMode);
|
||||
|
||||
Status do_close();
|
||||
|
||||
bool is_ok() const;
|
||||
|
||||
bool is_open_for_read() const;
|
||||
|
||||
bool is_open_for_write() const;
|
||||
|
||||
Result<size_t> do_read(VecBytes& bytes);
|
||||
|
||||
Result<size_t> do_write(const VecBytes& bytes);
|
||||
|
||||
Result<size_t> do_write(const Vector<char>& bytes, int size = -1);
|
||||
|
||||
Status update_size();
|
||||
|
||||
bool m_open_for_write{false};
|
||||
bool m_open_for_read{false};
|
||||
bool m_valid{false};
|
||||
size_t m_size{0};
|
||||
bool m_is_open{false};
|
||||
int m_fd{-1};
|
||||
};
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
Ptr<JsonDocument> JsonParser::read(const FileSystemPath& input_file)
|
||||
{
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,12 @@ TomlContent* TomlReader::getContent() const
|
|||
void TomlReader::read(const FileSystemPath& input_path)
|
||||
{
|
||||
Vector<String> lines;
|
||||
File(input_path).readLines(lines);
|
||||
File input_file(input_path);
|
||||
|
||||
String buffer;
|
||||
input_file.read(buffer);
|
||||
buffer.split(lines, '\n');
|
||||
|
||||
mLastSectionOffset = 0;
|
||||
mWorkingTable = mContent->getRootTable();
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "Stream.h"
|
||||
#include "String.h"
|
||||
#include "Optional.h"
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
|
||||
class BinaryStream
|
||||
{
|
||||
|
|
|
@ -11,7 +11,8 @@ Byte BitStream::getCurrentByte()
|
|||
{
|
||||
if (mByteOffset < 0)
|
||||
{
|
||||
readNextByte();
|
||||
Byte buffer;
|
||||
readNextByte(buffer);
|
||||
}
|
||||
return mCurrentByte;
|
||||
}
|
||||
|
@ -109,9 +110,10 @@ void BitStream::writeNBits(DWord data, size_t length)
|
|||
|
||||
bool BitStream::readNextNBits(size_t n, Byte& buffer)
|
||||
{
|
||||
Byte internal_buffer;
|
||||
if (mByteOffset < 0)
|
||||
{
|
||||
if (!readNextByte())
|
||||
if (!readNextByte(internal_buffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -121,7 +123,7 @@ bool BitStream::readNextNBits(size_t n, Byte& buffer)
|
|||
if (overshoot > 0)
|
||||
{
|
||||
const auto last_byte = mCurrentByte;
|
||||
if (!readNextByte())
|
||||
if (!readNextByte(internal_buffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "AbstractChecksumCalculator.h"
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
#include "String.h"
|
||||
#include "Optional.h"
|
||||
#include "Pair.h"
|
||||
|
@ -27,7 +27,7 @@ public:
|
|||
|
||||
virtual bool readNextNBits(size_t n, Byte& buffer);
|
||||
|
||||
virtual Optional<Byte> readNextByte() = 0;
|
||||
virtual bool readNextByte(Byte& ret) = 0;
|
||||
|
||||
virtual void writeNBits(DWord data, size_t length);
|
||||
|
||||
|
|
|
@ -30,17 +30,18 @@ void BufferBitStream::peekNextNBytes(size_t n, VecBytes& ret) const
|
|||
}
|
||||
}
|
||||
|
||||
Optional<uint8_t> BufferBitStream::readNextByte()
|
||||
bool BufferBitStream::readNextByte(Byte& byte)
|
||||
{
|
||||
if (mByteOffset + 1 == static_cast<int>(mBuffer.size()))
|
||||
{
|
||||
return {};
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mByteOffset++;
|
||||
mCurrentByte = mBuffer[mByteOffset];
|
||||
return mCurrentByte;
|
||||
byte = mCurrentByte;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,9 +50,9 @@ void BufferBitStream::setBuffer(const VecBytes& data)
|
|||
mBuffer = data;
|
||||
}
|
||||
|
||||
void BufferBitStream::writeByte(uint8_t data, bool checkOverflow)
|
||||
void BufferBitStream::writeByte(Byte data, bool checkOverflow)
|
||||
{
|
||||
uint8_t out_byte{0};
|
||||
Byte out_byte{0};
|
||||
if (checkOverflow && mBitOffset > 0)
|
||||
{
|
||||
out_byte = Bits::getLowerNBits(mCurrentByte, mBitOffset);
|
||||
|
|
|
@ -11,13 +11,13 @@ public:
|
|||
|
||||
void peekNextNBytes(size_t n, VecBytes& bytes) const override;
|
||||
|
||||
Optional<uint8_t> readNextByte() override;
|
||||
bool readNextByte(Byte& byte) override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
void setBuffer(const VecBytes& data);
|
||||
|
||||
void writeByte(uint8_t data, bool checkOverflow = true) override;
|
||||
void writeByte(Byte data, bool checkOverflow = true) override;
|
||||
|
||||
void writeBytes(const VecBytes& data) override;
|
||||
|
||||
|
|
0
src/base/core/streams/ByteStream.cpp
Normal file
0
src/base/core/streams/ByteStream.cpp
Normal file
11
src/base/core/streams/ByteStream.h
Normal file
11
src/base/core/streams/ByteStream.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "String.h"
|
||||
|
||||
using OutputByteStream = OutputByteStream<Byte>;
|
||||
|
||||
inline void operator<<(OutputByteStream& stream, const char* string)
|
||||
{
|
||||
|
||||
}
|
|
@ -1,11 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
#include "Stream.h"
|
||||
#include "FileSystemPath.h"
|
||||
#include "File.h"
|
||||
|
||||
class InputFileStream : public InputStream<Byte>
|
||||
{
|
||||
public:
|
||||
|
||||
InputFileStream(const FileSystemPath& path)
|
||||
: File(path)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool good() const override
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
bool get(T& item) = 0;
|
||||
|
||||
private:
|
||||
void finished()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
File mFile;
|
||||
Status mStatus;
|
||||
};
|
|
@ -16,15 +16,16 @@ void InputBitStream::peekNextNBytes(size_t, VecBytes&) const
|
|||
{
|
||||
}
|
||||
|
||||
Optional<Byte> InputBitStream::readNextByte()
|
||||
bool InputBitStream::readNextByte(Byte& buffer)
|
||||
{
|
||||
if (mStream->good())
|
||||
{
|
||||
return static_cast<Byte>(mStream->get());
|
||||
buffer = static_cast<Byte>(mStream->get());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "BitStream.h"
|
||||
#include "Stream.h"
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
|
||||
class InputBitStream : public BitStream
|
||||
{
|
||||
|
@ -12,13 +12,12 @@ class InputBitStream : public BitStream
|
|||
|
||||
void peekNextNBytes(size_t n, VecBytes& bytes) const override;
|
||||
|
||||
Optional<Byte> readNextByte() override;
|
||||
bool readNextByte(Byte& buffer) override;
|
||||
|
||||
void writeByte(Byte data, bool checkOverflow = true) override;
|
||||
|
||||
void writeBytes(const VecBytes&) override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -17,12 +17,12 @@ void OutputBitStream::peekNextNBytes(size_t, VecBytes&) const
|
|||
|
||||
}
|
||||
|
||||
Optional<uint8_t> OutputBitStream::readNextByte()
|
||||
bool OutputBitStream::readNextByte(Byte& buffer)
|
||||
{
|
||||
return {};
|
||||
return false;
|
||||
}
|
||||
|
||||
void OutputBitStream::writeByte(uint8_t data, bool)
|
||||
void OutputBitStream::writeByte(Byte data, bool)
|
||||
{
|
||||
//(*mStream) << data;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "BitStream.h"
|
||||
#include "Stream.h"
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
|
||||
class OutputBitStream : public BitStream
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ public:
|
|||
|
||||
void peekNextNBytes(size_t n, VecBytes& bytes) const override;
|
||||
|
||||
Optional<Byte> readNextByte() override;
|
||||
bool readNextByte(Byte& buffer) override;
|
||||
|
||||
void writeByte(Byte data, bool checkOverflow = true) override;
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ public:
|
|||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual bool get(T& item) = 0;
|
||||
};
|
||||
|
||||
|
|
70
src/base/core/system/process/Process.cpp
Normal file
70
src/base/core/system/process/Process.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "Process.h"
|
||||
|
||||
#include "Logger.h"
|
||||
#include "File.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
|
||||
Status Process::launch(const String& command,
|
||||
const Vector<String>& args)
|
||||
{
|
||||
const auto pid = fork();
|
||||
if (pid < 0)
|
||||
{
|
||||
ON_ERRNO("Failed to fork");
|
||||
}
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
char* exe_args[args.size()+2];
|
||||
exe_args[0] = const_cast<char*>(command.raw());
|
||||
for(size_t idx = 1; idx<args.size()+1; idx++)
|
||||
{
|
||||
//LOG_INFO(args[idx-1]);
|
||||
exe_args[idx] = const_cast<char*>(args[idx-1].raw());
|
||||
}
|
||||
exe_args[args.size()+1] = nullptr;
|
||||
errno = 0;
|
||||
auto rc = execv(command.raw(), exe_args);
|
||||
if (rc != 0)
|
||||
{
|
||||
LOG_ERROR("External proc failed: " << Error::from_errno());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
int status;
|
||||
auto rc = wait(&status);
|
||||
if (rc < 0)
|
||||
{
|
||||
ON_ERRNO("Failed to wait");
|
||||
}
|
||||
if (!WIFEXITED(status))
|
||||
{
|
||||
return Status(Error("Process child did not termintate normally"));
|
||||
}
|
||||
if (WEXITSTATUS(status) != EXIT_SUCCESS)
|
||||
{
|
||||
return Status(Error("Process child terminated with failure"));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<String> Process::get_self_name()
|
||||
{
|
||||
FileSystemPath path(String("/proc/self/cmdline"));
|
||||
File sys_file(path);
|
||||
|
||||
Result<String> ret;
|
||||
const auto rc = sys_file.read(ret.value());
|
||||
if (!rc.ok())
|
||||
{
|
||||
ret.on_error(rc.error());
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -1,77 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
|
||||
#include "File.h"
|
||||
#include "Result.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
|
||||
class Process
|
||||
{
|
||||
public:
|
||||
static Result<String> get_self_name();
|
||||
|
||||
static Status launch(const String& command,
|
||||
const Vector<String>& args)
|
||||
{
|
||||
const auto pid = fork();
|
||||
if (pid < 0)
|
||||
{
|
||||
ON_ERRNO("Failed to fork");
|
||||
}
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
char* exe_args[args.size()+2];
|
||||
exe_args[0] = const_cast<char*>(command.raw());
|
||||
for(size_t idx = 1; idx<args.size()+1; idx++)
|
||||
{
|
||||
//LOG_INFO(args[idx-1]);
|
||||
exe_args[idx] = const_cast<char*>(args[idx-1].raw());
|
||||
}
|
||||
exe_args[args.size()+1] = nullptr;
|
||||
errno = 0;
|
||||
auto rc = execv(command.raw(), exe_args);
|
||||
if (rc != 0)
|
||||
{
|
||||
LOG_ERROR("External proc failed: " << Error::from_errno());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
int status;
|
||||
auto rc = wait(&status);
|
||||
if (rc < 0)
|
||||
{
|
||||
ON_ERRNO("Failed to wait");
|
||||
}
|
||||
if (!WIFEXITED(status))
|
||||
{
|
||||
return Status(Error("Process child did not termintate normally"));
|
||||
}
|
||||
if (WEXITSTATUS(status) != EXIT_SUCCESS)
|
||||
{
|
||||
return Status(Error("Process child terminated with failure"));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static Result<String> get_self_name()
|
||||
{
|
||||
FileSystemPath path(String("/proc/self/cmdline"));
|
||||
File sys_file(path);
|
||||
|
||||
Result<String> ret;
|
||||
const auto rc = sys_file.readText(ret.value());
|
||||
if (!rc.ok())
|
||||
{
|
||||
ret.on_error(rc.error());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
const Vector<String>& args);
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "ByteTypes.h"
|
||||
#include "Byte.h"
|
||||
|
||||
#include "String.h"
|
||||
#include <sstream>
|
||||
|
|
|
@ -6,6 +6,7 @@ g++ $SCRIPT_DIR/test_runner.cpp \
|
|||
$CORE_SRC_DIR/system/process/CommandLineArgs.cpp \
|
||||
$CORE_SRC_DIR/base_types/Error.cpp \
|
||||
$CORE_SRC_DIR/base_types/Index.cpp \
|
||||
$CORE_SRC_DIR/base_types/Char.cpp \
|
||||
$CORE_SRC_DIR/data_structures/String.cpp \
|
||||
$CORE_SRC_DIR/filesystem/FileSystemPath.cpp \
|
||||
$CORE_SRC_DIR/logging/Logger.cpp \
|
||||
|
|
Loading…
Reference in a new issue