Start proper stream support.

This commit is contained in:
jmsgrogan 2024-01-21 16:27:30 +00:00
parent 5183aa821a
commit e3e03dc31f
34 changed files with 421 additions and 402 deletions

View file

@ -13,9 +13,12 @@ g++ $SOURCE_DIR/main.cpp \
$CORE_SRC_DIR/data_structures/String.cpp \ $CORE_SRC_DIR/data_structures/String.cpp \
$CORE_SRC_DIR/filesystem/FileSystemPath.cpp \ $CORE_SRC_DIR/filesystem/FileSystemPath.cpp \
$CORE_SRC_DIR/filesystem/File.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/filesystem/Directory.cpp \
$CORE_SRC_DIR/logging/ConsoleLogger.cpp \ $CORE_SRC_DIR/logging/ConsoleLogger.cpp \
$CORE_SRC_DIR/logging/Logger.cpp \ $CORE_SRC_DIR/logging/Logger.cpp \
$CORE_SRC_DIR/system/process/Process.cpp \
$CORE_SRC_DIR/time/Time.cpp \ $CORE_SRC_DIR/time/Time.cpp \
-o builder -g -fno-exceptions -fno-rtti \ -o builder -g -fno-exceptions -fno-rtti \
-I$CORE_SRC_DIR/base_types \ -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/data_structures \
-I$CORE_SRC_DIR/encoding \ -I$CORE_SRC_DIR/encoding \
-I$CORE_SRC_DIR/filesystem \ -I$CORE_SRC_DIR/filesystem \
-I$CORE_SRC_DIR/filesystem/posix \
-I$CORE_SRC_DIR/logging \ -I$CORE_SRC_DIR/logging \
-I$CORE_SRC_DIR/memory \ -I$CORE_SRC_DIR/memory \
-I$CORE_SRC_DIR/system/process \ -I$CORE_SRC_DIR/system/process \

View file

@ -10,14 +10,14 @@ public:
BuildLibrary(const FileSystemPath& build_config); BuildLibrary(const FileSystemPath& build_config);
Status scan();
const Vector<FileSystemPath>& get_sources() const; const Vector<FileSystemPath>& get_sources() const;
const Vector<FileSystemPath>& get_include_dirs() const; const Vector<FileSystemPath>& get_include_dirs() const;
const String& get_name() const; const String& get_name() const;
Status scan();
private: private:
FileSystemPath m_build_config; FileSystemPath m_build_config;
Vector<FileSystemPath> m_sources; Vector<FileSystemPath> m_sources;

View file

@ -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) void Status::on_errno(const String& prefix_msg)
{ {
String errno_msg(::strerror(errno)); String errno_msg(::strerror(errno));

View file

@ -48,6 +48,8 @@ public:
Status(const Error& err); Status(const Error& err);
static Status with_errno(const String& prefix_msg);
void on_errno(const String& prefix_msg); void on_errno(const String& prefix_msg);
const Error& error() const; const Error& error() const;

View file

@ -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) void String::append(const Vector<Byte>& data)
{ {
if (data.empty()) if (data.empty())

View file

@ -3,7 +3,7 @@
#include "Vector.h" #include "Vector.h"
#include "Pair.h" #include "Pair.h"
#include "Index.h" #include "Index.h"
#include "ByteTypes.h" #include "Byte.h"
#include <functional> #include <functional>
@ -29,6 +29,8 @@ public:
using erasePredicate = std::function<bool(char)>; using erasePredicate = std::function<bool(char)>;
void eraseIf(erasePredicate func); void eraseIf(erasePredicate func);
static size_t length(const char* arr);
bool is_whitespace() const; bool is_whitespace() const;
void push_back(char c); void push_back(char c);

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "ByteTypes.h" #include "Byte.h"
#include "String.h" #include "String.h"
class Bits class Bits

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "ByteTypes.h" #include "Byte.h"
#include "String.h" #include "String.h"
#include "Vector.h" #include "Vector.h"

View 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 {};
}

View 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);
};

View file

@ -3,148 +3,10 @@
#include "Char.h" #include "Char.h"
#include "Directory.h" #include "Directory.h"
#include "Result.h" #include "Result.h"
#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>
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};
};
File::File(const FileSystemPath& path) File::File(const FileSystemPath& path)
: m_impl(Ptr<FileImpl>::create()), : m_impl(Ptr<FilePosixImpl>::create()),
m_path(path) m_path(path)
{ {
} }
@ -154,23 +16,46 @@ File::~File()
close(); close();
} }
Status File::close()
{
return m_impl->do_close();
}
bool File::exists() const
{
return m_path.exists();
}
String File::getExtension() const String File::getExtension() const
{ {
return m_path.extension(); return m_path.extension();
} }
Status File::readBinary(VecBytes& buffer) FileFormat::Format File::inferFormat() const
{ {
auto status = open(AccessMode::Read, true); const auto extension = getExtension();
if (!status.ok()) 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 (const auto rc = m_impl->update_size(); !rc.ok())
if (!status.ok())
{ {
return status; return rc;
} }
buffer.resize(m_impl->m_size); buffer.resize(m_impl->m_size);
@ -183,17 +68,15 @@ Status File::readBinary(VecBytes& buffer)
return {}; return {};
} }
Status File::readText(String& ret) Status File::read(String& ret)
{ {
auto status = open(AccessMode::Read, true); if (const auto rc = open(AccessMode::Read); !rc.ok())
if (!status.ok())
{ {
return status; return rc;
} }
VecBytes buffer; VecBytes buffer;
status = m_impl->update_size(); if (const auto rc = m_impl->update_size(); rc.ok() && m_impl->m_size > 0)
if (status.ok() && m_impl->m_size > 0)
{ {
buffer.resize(m_impl->m_size); buffer.resize(m_impl->m_size);
const auto result = m_impl->do_read(buffer); const auto result = m_impl->do_read(buffer);
@ -232,85 +115,7 @@ Status File::readText(String& ret)
return {}; return {};
} }
String File::dumpBinary() Status File::write(const String& text)
{
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)
{ {
bool had_to_open{false}; bool had_to_open{false};
Status status; Status status;
@ -335,53 +140,3 @@ Status File::writeText(const String& text)
} }
return status; 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();
}

View file

@ -2,20 +2,18 @@
#include "FileFormats.h" #include "FileFormats.h"
#include "FileSystemPath.h" #include "FileSystemPath.h"
#include "Optional.h"
#include "String.h" #include "String.h"
#include "ByteTypes.h" #include "Byte.h"
#include "Pointer.h" #include "Pointer.h"
class FileImpl; class FilePosixImpl;
class File class File
{ {
public: public:
enum class AccessMode{ enum class AccessMode{
Read, Read,
Write, Write
ReadWrite
}; };
public: public:
@ -25,29 +23,26 @@ public:
Status close(); Status close();
String dumpBinary(); bool exists() const;
bool finished() const;
String getExtension() const; String getExtension() const;
FileFormat::Format inferFormat() 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); Status read(String& buffer);
bool exists() const; Status write(const String& buffer);
Status open(AccessMode mode, bool binary = false); Status write(const VecBytes& bytes);
Status readBinary(VecBytes& bytes);
Optional<Byte> readNextByte();
Status writeText(const String& text);
private: private:
Ptr<FileImpl> m_impl; Ptr<FilePosixImpl> m_impl;
FileSystemPath m_path; FileSystemPath m_path;
bool mGotEndOfFile{false};
}; };

View 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 {};
}

View 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};
};

View file

@ -2,7 +2,6 @@
Ptr<JsonDocument> JsonParser::read(const FileSystemPath& input_file) Ptr<JsonDocument> JsonParser::read(const FileSystemPath& input_file)
{ {
return {}; return {};
} }

View file

@ -69,7 +69,12 @@ TomlContent* TomlReader::getContent() const
void TomlReader::read(const FileSystemPath& input_path) void TomlReader::read(const FileSystemPath& input_path)
{ {
Vector<String> lines; 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; mLastSectionOffset = 0;
mWorkingTable = mContent->getRootTable(); mWorkingTable = mContent->getRootTable();

View file

@ -3,7 +3,7 @@
#include "Stream.h" #include "Stream.h"
#include "String.h" #include "String.h"
#include "Optional.h" #include "Optional.h"
#include "ByteTypes.h" #include "Byte.h"
class BinaryStream class BinaryStream
{ {

View file

@ -11,7 +11,8 @@ Byte BitStream::getCurrentByte()
{ {
if (mByteOffset < 0) if (mByteOffset < 0)
{ {
readNextByte(); Byte buffer;
readNextByte(buffer);
} }
return mCurrentByte; return mCurrentByte;
} }
@ -109,9 +110,10 @@ void BitStream::writeNBits(DWord data, size_t length)
bool BitStream::readNextNBits(size_t n, Byte& buffer) bool BitStream::readNextNBits(size_t n, Byte& buffer)
{ {
Byte internal_buffer;
if (mByteOffset < 0) if (mByteOffset < 0)
{ {
if (!readNextByte()) if (!readNextByte(internal_buffer))
{ {
return false; return false;
} }
@ -121,7 +123,7 @@ bool BitStream::readNextNBits(size_t n, Byte& buffer)
if (overshoot > 0) if (overshoot > 0)
{ {
const auto last_byte = mCurrentByte; const auto last_byte = mCurrentByte;
if (!readNextByte()) if (!readNextByte(internal_buffer))
{ {
return false; return false;
} }

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "AbstractChecksumCalculator.h" #include "AbstractChecksumCalculator.h"
#include "ByteTypes.h" #include "Byte.h"
#include "String.h" #include "String.h"
#include "Optional.h" #include "Optional.h"
#include "Pair.h" #include "Pair.h"
@ -27,7 +27,7 @@ public:
virtual bool readNextNBits(size_t n, Byte& buffer); 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); virtual void writeNBits(DWord data, size_t length);

View file

@ -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())) if (mByteOffset + 1 == static_cast<int>(mBuffer.size()))
{ {
return {}; return false;
} }
else else
{ {
mByteOffset++; mByteOffset++;
mCurrentByte = mBuffer[mByteOffset]; mCurrentByte = mBuffer[mByteOffset];
return mCurrentByte; byte = mCurrentByte;
return true;
} }
} }
@ -49,9 +50,9 @@ void BufferBitStream::setBuffer(const VecBytes& data)
mBuffer = 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) if (checkOverflow && mBitOffset > 0)
{ {
out_byte = Bits::getLowerNBits(mCurrentByte, mBitOffset); out_byte = Bits::getLowerNBits(mCurrentByte, mBitOffset);

View file

@ -11,13 +11,13 @@ public:
void peekNextNBytes(size_t n, VecBytes& bytes) const override; void peekNextNBytes(size_t n, VecBytes& bytes) const override;
Optional<uint8_t> readNextByte() override; bool readNextByte(Byte& byte) override;
void reset() override; void reset() override;
void setBuffer(const VecBytes& data); 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; void writeBytes(const VecBytes& data) override;

View file

View 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)
{
}

View file

@ -1,11 +1,32 @@
#pragma once #pragma once
#include "ByteTypes.h" #include "Byte.h"
#include "Stream.h" #include "Stream.h"
#include "FileSystemPath.h" #include "FileSystemPath.h"
#include "File.h"
class InputFileStream : public InputStream<Byte> class InputFileStream : public InputStream<Byte>
{ {
public: public:
InputFileStream(const FileSystemPath& path)
: File(path)
{
}
bool good() const override
{
return
}
bool get(T& item) = 0;
private:
void finished()
{
}
File mFile;
Status mStatus;
}; };

View file

@ -16,15 +16,16 @@ void InputBitStream::peekNextNBytes(size_t, VecBytes&) const
{ {
} }
Optional<Byte> InputBitStream::readNextByte() bool InputBitStream::readNextByte(Byte& buffer)
{ {
if (mStream->good()) if (mStream->good())
{ {
return static_cast<Byte>(mStream->get()); buffer = static_cast<Byte>(mStream->get());
return true;
} }
else else
{ {
return {}; return false;
} }
} }

View file

@ -2,7 +2,7 @@
#include "BitStream.h" #include "BitStream.h"
#include "Stream.h" #include "Stream.h"
#include "ByteTypes.h" #include "Byte.h"
class InputBitStream : public BitStream class InputBitStream : public BitStream
{ {
@ -12,13 +12,12 @@ class InputBitStream : public BitStream
void peekNextNBytes(size_t n, VecBytes& bytes) const override; 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 writeByte(Byte data, bool checkOverflow = true) override;
void writeBytes(const VecBytes&) override void writeBytes(const VecBytes&) override
{ {
} }
private: private:

View file

@ -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; //(*mStream) << data;
} }

View file

@ -2,7 +2,7 @@
#include "BitStream.h" #include "BitStream.h"
#include "Stream.h" #include "Stream.h"
#include "ByteTypes.h" #include "Byte.h"
class OutputBitStream : public BitStream class OutputBitStream : public BitStream
{ {
@ -13,7 +13,7 @@ public:
void peekNextNBytes(size_t n, VecBytes& bytes) const override; 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 writeByte(Byte data, bool checkOverflow = true) override;

View file

@ -23,7 +23,6 @@ public:
} }
return {}; return {};
} }
virtual bool get(T& item) = 0; virtual bool get(T& item) = 0;
}; };

View 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;
}

View file

@ -1,77 +1,13 @@
#pragma once #pragma once
#include "String.h" #include "String.h"
#include "File.h"
#include "Result.h" #include "Result.h"
#include "Logger.h"
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
class Process class Process
{ {
public: public:
static Result<String> get_self_name();
static Status launch(const String& command, static Status launch(const String& command,
const Vector<String>& args) 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;
}
}; };

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "ByteTypes.h" #include "Byte.h"
#include "String.h" #include "String.h"
#include <sstream> #include <sstream>

View file

@ -6,6 +6,7 @@ g++ $SCRIPT_DIR/test_runner.cpp \
$CORE_SRC_DIR/system/process/CommandLineArgs.cpp \ $CORE_SRC_DIR/system/process/CommandLineArgs.cpp \
$CORE_SRC_DIR/base_types/Error.cpp \ $CORE_SRC_DIR/base_types/Error.cpp \
$CORE_SRC_DIR/base_types/Index.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/data_structures/String.cpp \
$CORE_SRC_DIR/filesystem/FileSystemPath.cpp \ $CORE_SRC_DIR/filesystem/FileSystemPath.cpp \
$CORE_SRC_DIR/logging/Logger.cpp \ $CORE_SRC_DIR/logging/Logger.cpp \