Initial test bootstrap.

This commit is contained in:
jmsgrogan 2023-12-18 10:16:31 +00:00
parent 6c618749f1
commit 4b308f6c32
94 changed files with 2543 additions and 681 deletions

View file

@ -0,0 +1,78 @@
#include "KScope.h"
#include <stdio.h>
void KScopeLexer::run(const FileSystemPath& path)
{
printf("Before read");
File f(path);
const auto content = f<.readText();
printf("Content is: %s\n", content);
fflush(stdout);
Vector<Token> tokens;
for(const auto c : content.data())
{
printf("Char is: %c\n", c);
if (CharUtils::is_space(c))
{
if (m_working_token.is_identifier() || m_working_token.is_number())
{
on_token_finished(tokens);
}
}
else if (CharUtils::is_alpha(c))
{
if (m_working_token.is_number())
{
on_token_finished(tokens);
m_working_token = Token();
m_working_token.set_is_identifier();
}
else if (!m_working_token.is_identifier())
{
m_working_token = Token();
m_working_token.set_is_identifier();
}
m_working_token.m_value += c;
}
else if (CharUtils::is_digit(c))
{
if (m_working_token.is_number() || m_working_token.is_identifier())
{
m_working_token.m_value += c;
}
else
{
m_working_token = Token();
m_working_token.set_is_number();
m_working_token.m_value += c;
}
}
else
{
if (m_working_token.is_identifier() || m_working_token.is_number())
{
on_token_finished(tokens);
}
m_working_token.set_is_literal();
m_working_token.m_value += c;
on_token_finished(tokens);
}
}
on_token_finished(tokens);
}
void KScopeLexer::on_token_finished(Vector<Token>& tokens)
{
if (m_working_token.m_type == TokenT::NONE)
{
return;
}
m_working_token.on_finished();
tokens.push_back(m_working_token);
m_working_token = Token();
}

View file

@ -0,0 +1,86 @@
#pragma once
#include "String.h"
#include "File.h"
#include "Vector.h"
#include "CharUtils.h"
class KScopeLexer
{
public:
enum class TokenT
{
NONE,
DEF, // LANG COMMANDS
EXTERN,
IDENTIFIER ,// GENERAL
LITERAL,
NUMBER
};
struct Token
{
bool is_identifier() const
{
return m_type == TokenT::IDENTIFIER;
}
bool is_number() const
{
return m_type == TokenT::NUMBER;
}
void set_is_identifier()
{
m_type = TokenT::IDENTIFIER;
}
void set_is_number()
{
m_type = TokenT::NUMBER;
}
void set_is_literal()
{
m_type = TokenT::LITERAL;
}
void on_identifier_finished()
{
if (m_value == "def")
{
m_type = TokenT::DEF;
}
else if (m_value == "extern")
{
m_type = TokenT::EXTERN;
}
}
void on_number_finished()
{
}
void on_finished()
{
if (is_identifier())
{
on_identifier_finished();
}
else if(is_number())
{
on_number_finished();
}
}
TokenT m_type{TokenT::NONE};
String m_value;
};
void run(const FileSystemPath& path);
void on_token_finished(Vector<Token>& tokens);
Token m_working_token;
};

View file

@ -33,8 +33,8 @@ public:
bool hitBufferFull() const;
private:
bool lookAheadSourceEmpty() const;
unsigned char getSearchBufferItem(unsigned index) const;
unsigned lookAheadForMatchingChars(unsigned searchIndex);

View file

@ -40,8 +40,11 @@ list(APPEND SOURCES
Dictionary.cpp
Color.cpp
CommandLineArgs.cpp
memory/Allocator.cpp
data_structures/RawTree.cpp
data_structures/Tree.cpp
data_structures/Vector.cpp
data_structures/String.cpp
loggers/FileLogger.cpp
file_utilities/Directory.cpp
file_utilities/File.cpp
@ -81,6 +84,7 @@ target_include_directories(${MODULE_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/memory
${CMAKE_CURRENT_SOURCE_DIR}/streams
${CMAKE_CURRENT_SOURCE_DIR}/http
${CMAKE_CURRENT_SOURCE_DIR}/base_types
${CMAKE_CURRENT_SOURCE_DIR}/data_structures
${CMAKE_CURRENT_SOURCE_DIR}/serializers
${CMAKE_CURRENT_SOURCE_DIR}/xml

View file

@ -34,6 +34,77 @@ std::unique_ptr<Color> Color::Create(unsigned char r, unsigned char g, unsigned
return std::make_unique<Color>(r, g, b, a);
}
std::size_t Color::getSize() const
{
return getSize(mFormat, mBitDepth);
}
std::size_t Color::getSize(Format format, unsigned bitDepth)
{
return getNumChannels(format) * bitDepth / 8;
}
std::size_t Color::getNumChannels(Format format)
{
if (format == Format::GRAYSCALE || format == Format::LUT)
{
return 1;
}
else
{
return 4;
}
}
uint8_t Color::getByte(std::size_t index) const
{
if (mFormat == Format::GRAYSCALE || mFormat == Format::LUT)
{
if (index > 0)
{
throw std::range_error("Color index out of range in getByte()");
}
return mValue;
}
else if (mFormat == Format::ARGB)
{
switch(index)
{
case 0:
return mAlpha * 255;
case 1:
return mR;
case 2:
return mG;
case 3:
return mB;
default:
throw std::range_error("Color index out of range in getByte()");
}
}
else
{
switch(index)
{
case 0:
return mR;
case 1:
return mG;
case 2:
return mB;
case 3:
return mAlpha * 255;
default:
throw std::range_error("Color index out of range in getByte()");
}
}
}
void Color::setAlpha(float alpha)
{
mAlpha = static_cast<double>(alpha);
}
std::unique_ptr<Color> Color::Create(const Color& color)
{
return std::make_unique<Color>(color);

View file

@ -3,10 +3,20 @@
#include <memory>
#include <vector>
#include <string>
#include <stdexcept>
class Color
{
public:
enum class Format
{
GRAYSCALE,
GRAYSCALE_ALPHA,
LUT,
RGB,
ARGB,
RGBA
};
Color(const std::string& hexString);
Color(unsigned char r = 0, unsigned char g = 0, unsigned char b = 0, double a = 1.0);
@ -25,10 +35,15 @@ public:
std::string toString() const;
void setAlpha(float alpha)
{
mAlpha = static_cast<double>(alpha);
}
std::size_t getSize() const;
static std::size_t getNumChannels(Format format);
static std::size_t getSize(Format format, unsigned bitDepth);
uint8_t getByte(std::size_t index) const;
void setAlpha(float alpha);
bool operator==(const Color& rhs) const
{
@ -49,7 +64,10 @@ private:
unsigned char mR{0};
unsigned char mG{0};
unsigned char mB{0};
unsigned char mValue{0};
double mAlpha{0.0};
unsigned mBitDepth{8};
Format mFormat{Format::RGBA};
};
using ColorPtr = std::shared_ptr<Color>;

View file

@ -34,37 +34,37 @@ void CommandLineArgs::initialize(CommandLineArgs* args)
#endif
}
std::unique_ptr<CommandLineArgs> CommandLineArgs::Create()
Ptr<CommandLineArgs> CommandLineArgs::Create()
{
return std::make_unique<CommandLineArgs>();
return Ptr<CommandLineArgs>::create();
}
std::filesystem::path CommandLineArgs::getLaunchPath()
FileSystemPath CommandLineArgs::getLaunchPath()
{
return mLaunchPath;
}
void CommandLineArgs::recordLaunchPath()
{
mLaunchPath = std::filesystem::current_path();
mLaunchPath = FileSystemPath::current_dir();
}
void CommandLineArgs::process(int argc, char *argv[])
{
for(int idx=0; idx<argc; idx++)
{
mArugments.push_back(std::string(argv[idx]));
mArugments.push_back(String(argv[idx]));
}
}
void CommandLineArgs::process(const std::vector<std::string>& args)
void CommandLineArgs::process(const Vector<String>& args)
{
mArugments = args;
}
std::vector<std::string> CommandLineArgs::getUserArgs() const
Vector<String> CommandLineArgs::getUserArgs() const
{
std::vector<std::string> user_args;
Vector<String> user_args;
for(unsigned idx=1; idx<mArugments.size(); idx++)
{
user_args.push_back(mArugments[idx]);
@ -72,7 +72,7 @@ std::vector<std::string> CommandLineArgs::getUserArgs() const
return user_args;
}
const std::vector<std::string> CommandLineArgs::getArgs() const
const Vector<String> CommandLineArgs::getArgs() const
{
return mArugments;
}

View file

@ -1,33 +1,31 @@
#pragma once
#include <memory>
#include <vector>
#include <string>
#include <filesystem>
#include "Pointer.h"
#include "Vector.h"
#include "String.h"
#include "FileSystemPath.h"
class CommandLineArgs
{
public:
CommandLineArgs();
static std::unique_ptr<CommandLineArgs> Create();
static Ptr<CommandLineArgs> Create();
std::filesystem::path getLaunchPath();
FileSystemPath getLaunchPath();
const std::vector<std::string> getArgs() const;
const Vector<String> getArgs() const;
std::vector<std::string> getUserArgs() const;
Vector<String> getUserArgs() const;
static void initialize(CommandLineArgs* args);
void process(int argc, char *argv[]);
void process(const std::vector<std::string>& args);
void process(const Vector<String>& args);
void recordLaunchPath();
private:
std::vector<std::string> mArugments;
std::filesystem::path mLaunchPath;
};
using CommandLineArgsUPtr = std::unique_ptr<CommandLineArgs>;
Vector<String> mArugments;
FileSystemPath mLaunchPath;
};

View file

@ -0,0 +1,11 @@
#pragma once
#include <cstdint>
class Serializeable
{
public:
virtual std::size_t getSize() const = 0;
virtual uint8_t getByte(std::size_t index) const = 0;
};

View file

@ -0,0 +1,12 @@
#pragma once
#include "Vector.h"
#include <cstdint>
using Byte = uint8_t;
using VecBytes = Vector<Byte>;
using Word = uint16_t;
using DWord = uint32_t;
using QWord = uint64_t;

View file

@ -0,0 +1,11 @@
#include "Error.h"
Error::Error(const String& msg)
: m_message(msg)
{
}
const String& Error::msg() const
{
return m_message;
}

View file

@ -0,0 +1,15 @@
#pragma once
#include "String.h"
class Error
{
public:
Error(const String& msg);
Error() = default;
const String& msg() const;
private:
String m_message;
};

View file

@ -0,0 +1,17 @@
#include "Index.h"
Index::Index(std::size_t value)
: m_value(value),
m_valid(true)
{
}
bool Index::valid() const
{
return m_valid;
}
std::size_t Index::value() const
{
return m_value;
}

View file

@ -0,0 +1,19 @@
#pragma once
#include <cstdlib>
class Index
{
public:
Index() = default;
Index(std::size_t value);
bool valid() const;
std::size_t value() const;
private:
std::size_t m_value{0};
bool m_valid{false};
};

View file

@ -0,0 +1,41 @@
#pragma once
#include "Error.h"
template<typename T>
class Result
{
public:
Result(const T& val)
: m_value(val)
{
}
Result(const Error& error)
: m_error(error),
m_ok(false)
{
}
const Error& error() const
{
return m_error;
}
bool ok() const
{
return m_ok;
}
const T& value() const
{
return m_value;
}
private:
T m_value;
Error m_error;
bool m_ok{true};
};

0
src/base/core/build.toml Normal file
View file

View file

@ -1,8 +1,6 @@
#pragma once
#include <vector>
#include <iostream>
#include "Vector.h"
template<typename T>
class CircleBuffer
@ -60,5 +58,5 @@ public:
private:
std::size_t mStartPointer{0};
std::size_t mEndPointer{0};
std::vector<T> mData;
Vector<T> mData;
};

View file

@ -1,8 +1,7 @@
#pragma once
#include <vector>
#include <string>
#include <stdexcept>
#include "Error.h"
#include "Vector.h"
class AbstractList
{
@ -20,7 +19,7 @@ public:
void initializeTo(std::size_t size, T value)
{
mData = std::vector<T>(size, value);
mData = Vector<T>(size, value);
}
const T* getDataPtr() const
@ -28,7 +27,7 @@ public:
return mData.data();
}
const std::vector<T>& getData() const
const Vector<T>& getData() const
{
return mData;
}
@ -46,7 +45,7 @@ public:
}
}
void setData(const std::vector<T>& data)
void setData(const Vector<T>& data)
{
mData = data;
}
@ -65,5 +64,5 @@ public:
}
private:
std::vector<T> mData;
Vector<T> mData;
};

View file

@ -0,0 +1,6 @@
#pragma once
template<typename T, typename U>
class Map{
};

View file

@ -0,0 +1,29 @@
#pragma once
template<typename T>
class Optional{
public:
Optional() = default;
Optional(const T& value)
: m_is_set(true),
m_value(value)
{
}
const T& value() const
{
return m_value;
}
bool is_set() const
{
return m_is_set;
}
private:
bool m_is_set{false};
T m_value;
};

View file

@ -0,0 +1,27 @@
#pragma once
template<typename T, typename U>
class Pair
{
public:
Pair(const T& t, const U& u)
: m_first(t),
m_second(u)
{
}
const T& first() const
{
return m_first;
}
const U& second() const
{
return m_second;
}
private:
T m_first;
U m_second;
};

View file

@ -1,7 +1,5 @@
#pragma once
#include <memory>
template<typename T>
class RawNode
{

View file

@ -0,0 +1,232 @@
#include "String.h"
#include <stdio.h>
String::String()
{
m_data.push_back('\0');
}
String::String(const Vector<Byte>& data)
{
append(data);
}
String::String(const char* data)
{
append(data);
}
void String::append(const char* data)
{
if (data == nullptr)
{
m_data.push_back('\0');
return;
}
auto loc = data;
while(*loc != '\0')
{
m_data.push_back(*loc);
loc++;
}
m_data.push_back('\0');
}
const Vector<char>& String::data() const
{
return m_data;
}
bool String::empty() const
{
return m_data.empty() || m_data[0] == '\0';
}
void String::append(const Vector<Byte>& data)
{
if (data.capacity() == 0)
{
m_data.push_back('\0');
return;
}
if (m_data.size() == 1 && m_data[0] == '\0')
{
m_data.clear();
}
for(const auto c : data)
{
if(c == '\0')
{
break;
}
else
{
m_data.push_back(static_cast<char>(c));
}
}
m_data.push_back('\0');
}
Pair<String, String> String::rsplit(char c) const
{
if (const auto index = rindex(c); index.valid())
{
String left;
slice(0, index.value(), left);
String right;
slice(index.value(), size(), right);
return {left, right};
}
return {*this, {}};
}
bool String::slice(std::size_t idx, String& out) const
{
if (idx >= m_data.size() - 1)
{
return false;
}
auto ok = m_data.slice(idx, out.m_data);
if (!ok)
{
return ok;
}
out.m_data.push_back('\0');
return true;
}
bool String::slice(std::size_t start, std::size_t end, String& out) const
{
if (end >= m_data.size() - 1)
{
return false;
}
auto ok = m_data.slice(start, end, out.m_data);
if (!ok)
{
return ok;
}
out.m_data.push_back('\0');
return true;
}
Index String::rindex(char c) const
{
if (m_data.size() <= 2)
{
return {};
}
for(std::size_t idx=m_data.size()-2; idx >= 0; idx--)
{
if (m_data[idx] == c)
{
return Index(idx);
}
}
return {};
}
const char* String::raw() const
{
return m_data.data();
}
std::size_t String::size() const
{
return m_data.size() - 1;
}
void String::reverse()
{
if (m_data.size() == 1)
{
return;
}
for(size_t idx=0; idx<(m_data.size()-1)/2; idx++)
{
const auto ridx = m_data.size() - 2 - idx;
const auto tmp0 = m_data[idx];
m_data[idx] = m_data[ridx];
m_data[ridx] = tmp0;
}
}
String String::to_string(size_t input)
{
String conv;
auto input_cpy = input;
while(input_cpy > 0)
{
const auto rem = input_cpy % 10;
conv += static_cast<char>(48 + rem);
input_cpy /= 10;
}
conv.reverse();
return conv;
}
char String::operator[](std::size_t idx) const
{
return m_data[idx];
}
String& String::operator<<(const char* body)
{
append(body);
return *this;
}
bool String::operator==(const String& other) const
{
return m_data == other.m_data;
}
bool String::operator!=(const String& other) const
{
return !(*this == other);
}
String& String::operator<<(size_t idx)
{
/*
const auto num_digits = static_cast<unsigned>(log10(double(idx))) + 1;
char body[num_digits+1];
snprintf(body, num_digits+1, "%d", static_cast<int>(idx));
append(body);
*/
return *this;
}
String& String::operator+=(const String& str)
{
if (m_data.empty())
{
m_data = str.m_data;
}
else
{
m_data.pop_back();
m_data.extend(str.m_data);
}
return *this;
}
String String::operator+(const String& str) const
{
auto ret = *this;
ret += str;
return ret;
}
String& String::operator+=(char c)
{
m_data.push_back('\0');
m_data[m_data.size()-2] = c;
return *this;
}

View file

@ -0,0 +1,59 @@
#pragma once
#include "Vector.h"
#include "Pair.h"
#include "Index.h"
#include "ByteTypes.h"
class String
{
public:
String();
String(const Vector<Byte>& data);
String(const char* data);
const Vector<char>& data() const;
bool empty() const;
const char* raw() const;
Pair<String, String> rsplit(char c) const;
Index rindex(char c) const;
void reverse();
std::size_t size() const;
bool slice(std::size_t idx, String& out) const;
bool slice(std::size_t start, std::size_t end, String& out) const;
static String to_string(size_t input);
char operator[](std::size_t idx) const;
String& operator<<(const char* body);
String& operator<<(size_t idx);
String& operator+=(const String& str);
String& operator+=(char c);
String operator+(const String& str) const;
bool operator==(const String& other) const;
bool operator!=(const String& other) const;
private:
void append(const Vector<Byte>& data);
void append(const char* data);
Vector<char> m_data;
};

View file

@ -1,6 +1,6 @@
#pragma once
#include <memory>
#include "Pointer.h"
template<typename T>
class Node
@ -10,7 +10,7 @@ public:
: mData(data)
{}
void addChild(std::unique_ptr<Node> child)
void addChild(Ptr<Node> child)
{
if(!mLeftChild)
{
@ -45,12 +45,12 @@ public:
private:
T mData;
unsigned char mTag{0};
std::unique_ptr<Node> mLeftChild;
std::unique_ptr<Node> mRightChild;
Ptr<Node> mLeftChild;
Ptr<Node> mRightChild;
};
template<typename T>
using NodePtr = std::unique_ptr<Node<T> >;
using NodePtr = Ptr<Node<T> >;
template<typename T>
class Tree

View file

View file

@ -0,0 +1,233 @@
#pragma once
#include "Allocator.h"
#include <stdio.h>
template<typename T>
class Vector
{
public:
Vector() = default;
Vector(std::size_t size)
{
resize(size);
m_size = size;
}
Vector(const Vector& v)
{
*this = v;
}
~Vector()
{
clear();
}
T* begin() const
{
return m_data;
}
T* end() const
{
return m_data + m_size;
}
const T* data() const
{
return m_data;
}
T* data()
{
return m_data;
}
bool slice(std::size_t slice_idx, Vector& v) const
{
if (slice_idx >= m_size)
{
return false;
}
v.resize(slice_idx);
for(std::size_t idx=0; idx<slice_idx;idx++)
{
v.m_data[idx] = m_data[idx];
}
v.m_size = slice_idx;
return true;
}
bool slice(std::size_t slice_start, std::size_t slice_end, Vector& v) const
{
if (slice_end >= m_size)
{
return false;
}
v.resize(slice_end - slice_start);
for(std::size_t idx=slice_start; idx<slice_end;idx++)
{
v.m_data[idx] = m_data[idx];
}
v.m_size = slice_end;
return true;
}
std::size_t size() const
{
return m_size;
}
std::size_t capacity() const
{
return m_capacity;
}
bool empty() const
{
return m_size == 0;
}
void clear()
{
if (has_allocated())
{
m_allocator.delete_array(m_data);
m_data = nullptr;
m_capacity = 0;
m_size = 0;
}
}
void resize(std::size_t size)
{
resize_capacity(size);
}
void resize(std::size_t size, const T& value)
{
resize_capacity(size);
fill_with(value);
}
void extend(const Vector& other)
{
resize(m_size + other.m_size);
for(std::size_t idx=0;idx<other.m_size;idx++)
{
m_data[idx + m_size] = other[idx];
}
m_size = m_size + other.m_size;
}
T pop_back()
{
const auto last = m_data[size() - 1];
m_data[size() - 1] = T();
m_size--;
return last;
}
void push_back(const T& item)
{
if (!has_allocated())
{
resize_capacity(10);
}
else if (m_size >= m_capacity)
{
const std::size_t new_size = 1.5*m_size;
resize_capacity(new_size);
}
m_data[m_size] = item;
m_size++;
}
const T& operator[] (const std::size_t idx) const
{
return m_data[idx];
}
T& operator[] (const std::size_t idx)
{
return m_data[idx];
}
Vector<T>& operator=(const Vector<T>& v)
{
resize(v.size());
for(std::size_t idx=0; idx<v.size(); idx++)
{
m_data[idx] = v.m_data[idx];
}
m_size = v.size();
return *this;
}
bool operator ==(const Vector<T>& other) const
{
if (m_size != other.m_size)
{
return false;
}
for(std::size_t idx=0; idx<m_size; idx++)
{
if (m_data[idx] != other[idx])
{
return false;
}
}
return true;
}
private:
void fill_with(const T& value)
{
for(std::size_t idx = 0; idx<m_size; idx++)
{
m_data[idx] = value;
}
}
bool has_allocated() const
{
return m_capacity > 0;
}
void resize_capacity(std::size_t new_capacity)
{
if (!has_allocated())
{
m_data = m_allocator.alloc_array(new_capacity);
m_capacity = new_capacity;
}
else if (new_capacity != m_capacity)
{
auto temp = m_allocator.alloc_array(new_capacity);
for(std::size_t idx=0; idx<new_capacity; idx++)
{
temp[idx] = m_data[idx];
}
auto old_size = m_size;
clear();
m_data = temp;
m_capacity = new_capacity;
m_size = old_size;
if (old_size > m_capacity)
{
m_size = m_capacity;
}
}
else if(m_size != m_capacity)
{
m_size = m_capacity;
}
}
T* m_data{nullptr};
Allocator<T> m_allocator;
std::size_t m_size{0};
std::size_t m_capacity{0};
};

View file

@ -1,44 +1,40 @@
#pragma once
#include "ByteTypes.h"
#include "String.h"
#include <cstring>
#include <stdint.h>
#include <string>
class ByteUtils
{
public:
using Word = int16_t;
using DWord = int32_t;
using QWord = int64_t;
static bool MostSignificantBitIsOne(char c);
static bool MostSignificantBitIsOne(Byte c);
static Word GetWordFirstBit(const Word word);
static Word GetWordLastByte(const Word word);
static unsigned char getByteN(uint32_t input, unsigned n);
static Byte getByteN(DWord input, std::size_t n);
static unsigned char getHigherNBits(unsigned char input, unsigned num);
static Byte getHigherNBits(Byte input, std::size_t num);
static unsigned char getLowerNBits(uint32_t input, unsigned num);
static Byte getLowerNBits(DWord input, std::size_t num);
static unsigned char getTwoBitsAtN(unsigned char input, unsigned n);
static Byte getTwoBitsAtN(Byte input, std::size_t n);
static unsigned char getMBitsAtN(unsigned char input, unsigned m, unsigned n);
static Byte getMBitsAtN(Byte input, std::size_t m, std::size_t n);
static bool getBitN(uint32_t input, unsigned n);
static bool getBitN(DWord input, std::size_t n);
static unsigned char getFromString(const std::string& string);
static Byte getFromString(const String& string);
static std::string toString(uint32_t input, unsigned length = 8);
static String toString(DWord input, std::size_t length = 8);
static uint32_t mirror(uint32_t input, unsigned length=0);
static DWord mirror(DWord input, std::size_t length=0);
static void ReverseBuffer(char* buffer, char* reverse, unsigned size, unsigned targetSize);
static void ReverseBuffer(Byte* buffer, Byte* reverse, std::size_t size, std::size_t targetSize);
template<typename T>
static T ToType(char* buffer, bool reverse = true)
static T ToType(Byte* buffer, bool reverse = true)
{
T result {0};
if(reverse)
@ -54,17 +50,17 @@ public:
return result;
}
static Word ToWord(char* buffer, bool reverse = true);
static Word ToWord(Byte* buffer, bool reverse = true);
static DWord ToDWord(char* buffer, bool reverse = true);
static DWord ToDWord(Byte* buffer, bool reverse = true);
static QWord ToQWord(char* buffer, bool reverse = true);
static QWord ToQWord(Byte* buffer, bool reverse = true);
static bool Compare(char* buffer, const char* tag, unsigned size);
static bool Compare(Byte* buffer, const char* tag, std::size_t size);
static bool CompareDWords(char* buffer, const char* tag);
static bool CompareDWords(Byte* buffer, const char* tag);
static bool CompareWords(char* buffer, const char* tag);
static bool CompareWords(Byte* buffer, const char* tag);
static const int BYTE_FIRST_BIT = 0x40; // 1000 0000
static const Word WORD_FIRST_BIT = static_cast<Word>(0x8000); // 1000 0000 - 0000 0000

View file

@ -0,0 +1,35 @@
#include "CharUtils.h"
bool CharUtils::is_alpha_upper(char c)
{
const auto unsigned_c = static_cast<unsigned char>(c);
return unsigned_c >= 65 && unsigned_c <= 90;
}
bool CharUtils::is_alpha_lower(char c)
{
const auto unsigned_c = static_cast<unsigned char>(c);
return unsigned_c >= 97 && unsigned_c <= 122;
}
bool CharUtils::is_alpha(char c)
{
return is_alpha_upper(c) || is_alpha_lower(c);
}
bool CharUtils::is_alnum(char c)
{
return is_alpha(c) || is_digit(c);
}
bool CharUtils::is_digit(char c)
{
const auto unsigned_c = static_cast<unsigned char>(c);
return unsigned_c >= 48 && unsigned_c <= 57;
}
bool CharUtils::is_space(char c)
{
return c == ' ' || c == '\f' || c == '\n'
|| c == '\r' || c == '\t' || c == '\v';
}

View file

@ -0,0 +1,17 @@
#pragma once
class CharUtils
{
public:
static bool is_alpha_upper(char c);
static bool is_alpha_lower(char c);
static bool is_alpha(char c);
static bool is_alnum(char c);
static bool is_digit(char c);
static bool is_space(char c);
};

View file

@ -1,5 +1,7 @@
#pragma once
#include "ByteTypes.h"
#include <string>
#include <vector>

View file

@ -1,30 +1,84 @@
#include "Directory.h"
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
std::vector<Path> Directory::getFilesWithExtension(const Path& path, const std::string& extension, bool recursive)
Vector<FileSystemPath> Directory::getSubdirectories(const FileSystemPath& path)
{
std::vector<Path> paths;
if (std::filesystem::is_directory(path))
Vector<FileSystemPath> ret;
auto dirp = ::opendir(path.as_string().raw());
while(auto ep = ::readdir(dirp))
{
for (const auto& entry : std::filesystem::directory_iterator(path))
auto rel_path = String(ep->d_name);
if (rel_path == "." || rel_path == "..")
{
if (std::filesystem::is_regular_file(entry) && entry.path().extension() == extension)
continue;
}
auto full_path = path.join(rel_path);
struct stat sb;
auto rc = lstat(full_path.as_string().raw(), &sb);
if (rc == -1)
{
printf("Got error");
}
if (S_ISDIR(sb.st_mode))
{
printf("Adding full path: %s\n", full_path.as_string().raw());
ret.push_back(full_path);
}
}
::closedir(dirp);
return ret;
}
Vector<FileSystemPath> Directory::getFiles(const FileSystemPath& path, bool recursive)
{
Vector<FileSystemPath> paths;
if (path.is_directory())
{
for (const auto& entry : getSubdirectories(path))
{
if (entry.is_regular_file())
{
paths.push_back(entry.path());
paths.push_back(entry);
}
else if(recursive && std::filesystem::is_directory(entry))
else if(recursive && entry.is_directory())
{
const auto child_paths = getFilesWithExtension(entry, extension, recursive);
paths.insert(paths.end(), child_paths.begin(), child_paths.end());
const auto child_paths = getFiles(entry, recursive);
paths.extend(child_paths);
}
}
}
return paths;
}
void Directory::createIfNotExisting(const Path& path)
Vector<FileSystemPath> Directory::getFilesWithExtension(const FileSystemPath& path, const String& extension, bool recursive)
{
Path working_path;
if (std::filesystem::is_directory(path))
Vector<FileSystemPath> paths;
if (path.is_directory())
{
for (const auto& entry : getSubdirectories(path))
{
if (entry.is_regular_file() && entry.extension() == extension)
{
paths.push_back(entry);
}
else if(recursive && entry.is_directory())
{
const auto child_paths = getFilesWithExtension(entry, extension, recursive);
paths.extend(child_paths);
}
}
}
return paths;
}
void Directory::create(const FileSystemPath& path, bool existsOk)
{
(void)existsOk;
FileSystemPath working_path;
if (path.is_directory())
{
working_path = path;
}
@ -33,8 +87,8 @@ void Directory::createIfNotExisting(const Path& path)
working_path = path.parent_path();
}
if (!std::filesystem::exists(working_path))
if (!working_path.exists())
{
std::filesystem::create_directories(working_path);
//std::filesystem::create_directories(working_path);
}
}

View file

@ -1,14 +1,16 @@
#pragma once
#include <vector>
#include <filesystem>
using Path = std::filesystem::path;
#include "Vector.h"
#include "FileSystemPath.h"
class Directory
{
public:
static void createIfNotExisting(const Path& path);
static Vector<FileSystemPath> getSubdirectories(const FileSystemPath& path);
static std::vector<Path> getFilesWithExtension(const Path& path, const std::string& extension, bool recursive=false);
static void create(const FileSystemPath& path, bool existsOK = false);
static Vector<FileSystemPath> getFiles(const FileSystemPath& path, bool recursive=false);
static Vector<FileSystemPath> getFilesWithExtension(const FileSystemPath& path, const String& extension, bool recursive=false);
};

View file

@ -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();
}

View file

@ -1,57 +1,53 @@
#pragma once
#include "FileFormats.h"
#include "FileSystemPath.h"
#include "Optional.h"
#include "String.h"
#include "ByteTypes.h"
#include "Pointer.h"
#include <filesystem>
#include <string>
#include <fstream>
#include <memory>
#include <vector>
#include <optional>
using Path = std::filesystem::path;
class FileImpl;
class File
{
public:
enum class AccessMode{
Read,
Write
Write,
ReadWrite
};
public:
File(std::filesystem::path fullPath);
File(const FileSystemPath& path);
~File();
void close();
std::string dumpBinary();
String dumpBinary();
std::string getExtension() const;
std::ifstream* getInHandle() const;
std::ofstream* getOutHandle() const;
String getExtension() const;
FileFormat::Format inferFormat() const;
std::string readText();
String readText();
std::vector<std::string> readLines();
Vector<String> readLines();
std::string read();
String read();
bool pathExists() const;
bool open(AccessMode mode);
bool open(AccessMode mode, bool binary = false);
std::optional<unsigned char> readNextByte();
bool readBinary(VecBytes& bytes);
void writeText(const std::string& text);
Optional<Byte> readNextByte();
void writeText(const String& text);
private:
std::filesystem::path mFullPath;
std::unique_ptr<std::ifstream> mInHandle;
std::unique_ptr<std::ofstream> mOutHandle;
Ptr<FileImpl> m_impl;
FileSystemPath m_path;
};

View file

@ -1,7 +1,7 @@
#pragma once
#include <map>
#include <string>
#include "Map.h"
#include "String.h"
class FileFormat{
@ -24,13 +24,13 @@ public:
Unknown
};
using ExtensionMap = std::map<Format, std::string>;
using ExtensionMap = Map<Format, String>;
public:
static bool isFormat(const std::string& extension, Format format);
static bool isFormat(const String& extension, Format format);
static Format inferFormat(const std::string& query);
static Format inferFormat(const String& query);
static std::string getExtension(Format format);
static String getExtension(Format format);
private:
static ExtensionMap mExtensions;

View file

@ -0,0 +1,114 @@
#include "FileSystemPath.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
FileSystemPath::FileSystemPath(const String& path)
: m_path(path)
{
}
const String& FileSystemPath::as_string() const
{
return m_path;
}
Result<bool> FileSystemPath::is_empty() const
{
if (!is_regular_file())
{
return {Error("Requested empty check but target is not regular file.")};
}
const auto size_result = get_size();
if (!size_result.ok())
{
return {size_result.error().msg()};
}
return {size_result.value() == 0};
}
Result<size_t> FileSystemPath::get_size() const
{
if (!is_regular_file())
{
return {Error("Requested size but target is not regular file.")};
}
struct stat buf;
::stat(m_path.raw(), &buf);
return buf.st_size;
}
FileSystemPath FileSystemPath::current_dir()
{
errno = 0;
const auto path_max = ::pathconf(".", _PC_PATH_MAX);
std::size_t size{0};
if (path_max == -1)
{
size = 1024;
}
else if(path_max > 10240)
{
size = 10240;
}
else
{
size = path_max;
}
Vector<char> buffer(path_max);
const auto ret = ::getcwd(buffer.data(), path_max);
return FileSystemPath(String(buffer.data()));
}
bool FileSystemPath::is_regular_file() const
{
struct stat path_stat;
::stat(m_path.raw(), &path_stat);
return S_ISREG(path_stat.st_mode);
}
bool FileSystemPath::is_directory() const
{
struct stat path_stat;
::stat(m_path.raw(), &path_stat);
return S_ISDIR(path_stat.st_mode);
}
bool FileSystemPath::is_absolute() const
{
return false;
}
FileSystemPath FileSystemPath::parent_path() const
{
const auto split = m_path.rsplit('/');
return FileSystemPath(split.first());
}
String FileSystemPath::extension() const
{
const auto split = m_path.rsplit('.');
String result(".");
result += split.second();
return result;
}
bool FileSystemPath::exists() const
{
return ::access(m_path.raw(), F_OK) == 0;
}
FileSystemPath FileSystemPath::join(const String& entry) const
{
auto new_path = *this;
new_path.m_path+=m_delimiter;
new_path.m_path+=entry;
return new_path;
}

View file

@ -0,0 +1,38 @@
#pragma once
#include "String.h"
#include "Result.h"
class FileSystemPath
{
public:
FileSystemPath() = default;
FileSystemPath(const String& path);
const String& as_string() const;
static FileSystemPath current_dir();
String extension() const;
bool exists() const;
Result<bool> is_empty() const;
Result<size_t> get_size() const;
FileSystemPath join(const String& entry) const;
bool is_regular_file() const;
bool is_directory() const;
bool is_absolute() const;
FileSystemPath parent_path() const;
private:
String m_delimiter{"/"};
String m_path;
};

View file

@ -0,0 +1,17 @@
#include "ConsoleLogger.h"
#include <stdio.h>
#include <stdarg.h>
void ConsoleLogger::logLine(const String& msg)
{
printf("%s\n", msg.raw());
}
void ConsoleLogger::logLine(const char* fmt, ...)
{
va_list(args);
va_start(args, fmt);
vprintf((String(fmt) + "\n").raw(), args);
va_end(args);
}

View file

@ -0,0 +1,11 @@
#pragma once
#include "String.h"
class ConsoleLogger
{
public:
static void logLine(const String& msg);
static void logLine(const char* fmt, ...);
};

View file

@ -1,9 +1,20 @@
#include "FileLogger.h"
#include <time.h>
#include <iomanip>
#include <iostream>
#include <filesystem>
FileLogger::FileLogger()
:mWorkDirectory(),
mFileName("MT_Log.txt")
{
}
FileLogger& FileLogger::GetInstance()
{
static FileLogger instance;
return instance;
}
FileLogger::~FileLogger()
{

View file

@ -1,33 +1,21 @@
#pragma once
#define MLOG_ALL(msg, level) {std::ostringstream mt_logstream;\
#define MLOG_ALL(msg, level) {String mt_logstream;\
mt_logstream << msg; \
FileLogger::GetInstance().LogLine(level, mt_logstream, __FILE__, __FUNCTION__, __LINE__);};
#define MLOG_INFO(msg) MLOG_ALL(msg, "Info");
#define MLOG_ERROR(msg) MLOG_ALL(msg, "Error");
#include <memory>
#include <string>
#include <fstream>
#include <sstream>
#include "Pointer.h"
#include "String.h"
class FileLogger
{
FileLogger()
:mWorkDirectory(),
mFileName("MT_Log.txt"),
mFileStream()
{
}
FileLogger();
public:
static FileLogger& GetInstance()
{
static FileLogger instance;
return instance;
}
static FileLogger& GetInstance();
FileLogger(FileLogger const&) = delete;
void operator=(FileLogger const&) = delete;
@ -36,22 +24,19 @@ public:
void disable();
void SetWorkDirectory(const std::string& workDir);
void SetWorkDirectory(const String& workDir);
void SetFileName(const std::string& fileName);
void SetFileName(const String& fileName);
void Open();
void Close();
void LogLine(const std::ostringstream& line);
void LogLine(const String& line);
void LogLine(const std::string& logType, const std::ostringstream& line, const std::string& fileName = "", const std::string& functionName = "", int lineNumber=-1);
void LogLine(const String& logType, const String& line, const String& fileName = "", const String& functionName = "", int lineNumber=-1);
private:
bool mDisabled{false};
std::string mWorkDirectory;
std::string mFileName;
std::ofstream mFileStream;
};
using FileLoggerPtr = std::shared_ptr<FileLogger>;
String mWorkDirectory;
String mFileName;
};

View file

View file

@ -0,0 +1,29 @@
#pragma once
//#include <cstddef>
#include <stdlib.h>
template<typename T>
class Allocator
{
public:
T* allocate()
{
return new T;
}
void do_delete(T** p)
{
delete p;
}
T* alloc_array(std::size_t size)
{
return new T[size];
}
void delete_array(T*& arr)
{
delete[] arr;
}
};

View file

@ -0,0 +1,61 @@
#pragma once
#include "Allocator.h"
#include <utility>
template<typename T>
class Ptr
{
public:
Ptr()
{
}
static Ptr create()
{
Ptr p;
p.allocate();
return std::move(p);
}
void allocate()
{
m_raw = m_allocator.allocate();
}
~Ptr()
{
if (m_raw != nullptr)
{
m_allocator.do_delete(&m_raw);
}
}
Ptr(const Ptr& other) = delete;
Ptr(Ptr&& other)
: m_allocator(std::move(other.m_allocator)),
m_raw(other.m_raw)
{
other.m_raw = nullptr;
}
T* get()
{
return m_raw;
}
const T* get() const
{
return m_raw;
}
T* operator->()
{
return m_raw;
}
private:
Allocator<T> m_allocator;
T* m_raw{nullptr};
};

View file

@ -2,15 +2,12 @@
#include "ByteUtils.h"
#include <sstream>
#include <iostream>
BitStream::~BitStream()
{
}
unsigned char BitStream::getCurrentByte()
Byte BitStream::getCurrentByte()
{
if (mByteOffset < 0)
{
@ -19,19 +16,18 @@ unsigned char BitStream::getCurrentByte()
return mCurrentByte;
}
void BitStream::write(uint32_t data)
void BitStream::write(DWord data)
{
unsigned num_bytes = sizeof(uint32_t);
for(unsigned idx=0; idx<num_bytes;idx++)
for(std::size_t idx=0; idx<sizeof(DWord); idx++)
{
writeByte(ByteUtils::getByteN(data, idx));
}
}
void BitStream::writeWord(uint16_t data)
void BitStream::writeWord(Word data)
{
const auto byte0 = static_cast<unsigned char>(data >> 8);
const auto byte1 = static_cast<unsigned char>((data << 8) >> 8);
const auto byte0 = static_cast<Byte>(data >> 8);
const auto byte1 = static_cast<Byte>((data << 8) >> 8);
writeByte(byte0);
writeByte(byte1);
}
@ -41,24 +37,26 @@ int BitStream::getCurrentByteOffset() const
return mByteOffset;
}
unsigned BitStream::getCurrentBitOffset() const
std::size_t BitStream::getCurrentBitOffset() const
{
return mBitOffset;
}
std::string BitStream::logLocation()
String BitStream::logLocation()
{
std::stringstream sstr;
sstr << "Byte offset " << mByteOffset<< " | Bit offset " << mBitOffset;
sstr << " | Working byte " << ByteUtils::toString(getCurrentByte()) << '\n';
return sstr.str();
String ret;
ret << "Byte offset " << mByteOffset<< " | Bit offset " << mBitOffset;
ret << " | Working byte " << ByteUtils::toString(getCurrentByte()) << '\n';
return ret;
}
std::string BitStream::logNextNBytes(unsigned n) const
String BitStream::logNextNBytes(std::size_t n) const
{
std::stringstream sstr;
unsigned count{0};
for(auto byte : peekNextNBytes(n))
std::size_t count{0};
VecBytes bytes;
peekNextNBytes(n, bytes);
for(auto byte : bytes)
{
sstr << mByteOffset + count << " | " << ByteUtils::toString(byte) + '\n';
count++;
@ -66,28 +64,28 @@ std::string BitStream::logNextNBytes(unsigned n) const
return sstr.str();
}
void BitStream::writeNBits(uint32_t data, unsigned length)
void BitStream::writeNBits(DWord data, std::size_t length)
{
const auto num_left = 8 - mBitOffset;
const int overshoot = length - num_left;
if (overshoot > 0)
{
unsigned char lower_bits = ByteUtils::getLowerNBits(data, num_left);
Byte lower_bits = ByteUtils::getLowerNBits(data, num_left);
mCurrentByte |= lower_bits << mBitOffset;
writeByte(mCurrentByte, false);
unsigned num_bytes = overshoot / 8;
for (unsigned idx=0; idx< num_bytes; idx++)
std::size_t num_bytes = overshoot / 8;
for (std::size_t idx=0; idx< num_bytes; idx++)
{
mCurrentByte = ByteUtils::getMBitsAtN(static_cast<unsigned char>(data), overshoot, idx*8 + num_left);
mCurrentByte = ByteUtils::getMBitsAtN(static_cast<Byte>(data), overshoot, idx*8 + num_left);
writeByte(mCurrentByte, false);
}
if (const auto remainder = overshoot % 8; remainder > 0)
{
mCurrentByte = ByteUtils::getMBitsAtN(static_cast<unsigned char>(data), remainder, num_bytes*8 + num_left);
mCurrentByte = ByteUtils::getMBitsAtN(static_cast<Byte>(data), remainder, num_bytes*8 + num_left);
mBitOffset = remainder;
}
else
@ -98,7 +96,7 @@ void BitStream::writeNBits(uint32_t data, unsigned length)
}
else
{
mCurrentByte |= (static_cast<unsigned char>(data) << mBitOffset);
mCurrentByte |= (static_cast<Byte>(data) << mBitOffset);
mBitOffset += length;
if (mBitOffset == 8)
{
@ -107,10 +105,9 @@ void BitStream::writeNBits(uint32_t data, unsigned length)
mBitOffset = 0;
}
}
}
bool BitStream::readNextNBits(unsigned n, unsigned char& buffer)
bool BitStream::readNextNBits(std::size_t n, Byte& buffer)
{
if (mByteOffset < 0)
{
@ -123,15 +120,15 @@ bool BitStream::readNextNBits(unsigned n, unsigned char& buffer)
int overshoot = n + mBitOffset - 8;
if (overshoot > 0)
{
unsigned char last_byte = mCurrentByte;
const auto last_byte = mCurrentByte;
if (!readNextByte())
{
return false;
}
auto num_lower = 8 - mBitOffset;
char lower_bits = ByteUtils::getHigherNBits(last_byte, num_lower);
char higher_bits = ByteUtils::getLowerNBits(mCurrentByte, overshoot);
const auto lower_bits = ByteUtils::getHigherNBits(last_byte, num_lower);
const auto higher_bits = ByteUtils::getLowerNBits(mCurrentByte, overshoot);
buffer = (higher_bits << num_lower) | lower_bits;
@ -145,3 +142,44 @@ bool BitStream::readNextNBits(unsigned n, unsigned char& buffer)
return true;
}
}
void BitStream::resetOffsets()
{
mEndByteOffset = mByteOffset;
mEndBitOffset = mBitOffset;
mEndByte = mCurrentByte;
mCurrentByte = 0;
mByteOffset = -1;
mBitOffset = 0;
}
void BitStream::reset()
{
resetOffsets();
mCurrentByte = 0;
}
void BitStream::flushRemainingBits()
{
if (mBitOffset > 0)
{
writeByte(mCurrentByte, false);
mBitOffset = 0;
}
}
std::pair<Byte, std::size_t> BitStream::getRemainingBits() const
{
return {mEndByte, mEndBitOffset};
}
void BitStream::setChecksumCalculator(AbstractChecksumCalculator* calc)
{
mChecksumCalculator = calc;
}
void BitStream::clearChecksumCalculator()
{
mChecksumCalculator = nullptr;
}

View file

@ -1,92 +1,63 @@
#pragma once
#include "AbstractChecksumCalculator.h"
#include <vector>
#include <string>
#include <optional>
#include "ByteTypes.h"
#include "String.h"
#include "Optional.h"
#include "Pair.h"
class BitStream
{
public:
virtual ~BitStream();
unsigned char getCurrentByte();
Byte getCurrentByte();
int getCurrentByteOffset() const;
unsigned getCurrentBitOffset() const;
std::size_t getCurrentBitOffset() const;
virtual bool isFinished() const = 0;
std::string logNextNBytes(unsigned n) const;
String logNextNBytes(std::size_t n) const;
std::string logLocation();
String logLocation();
virtual std::vector<unsigned char> peekNextNBytes(unsigned n) const = 0;
virtual void peekNextNBytes(std::size_t n, VecBytes& bytes) const = 0;
virtual bool readNextNBits(unsigned n, unsigned char& buffer);
virtual bool readNextNBits(std::size_t n, Byte& buffer);
virtual std::optional<unsigned char> readNextByte() = 0;
virtual Optional<Byte> readNextByte() = 0;
virtual void writeNBits(uint32_t data, unsigned length);
virtual void writeNBits(DWord data, std::size_t length);
virtual void writeByte(unsigned char data, bool checkOverflow = true) = 0;
virtual void writeByte(Byte data, bool checkOverflow = true) = 0;
void write(uint32_t data);
void write(DWord data);
void writeWord(uint16_t data);
void writeWord(Word data);
virtual void writeBytes(const std::vector<unsigned char> data) = 0;
virtual void writeBytes(const VecBytes& data) = 0;
void resetOffsets()
{
mEndByteOffset = mByteOffset;
mEndBitOffset = mBitOffset;
mEndByte = mCurrentByte;
void resetOffsets();
mCurrentByte = 0;
mByteOffset = -1;
mBitOffset = 0;
}
virtual void reset();
virtual void reset()
{
resetOffsets();
mCurrentByte = 0;
}
void flushRemainingBits();
void flushRemainingBits()
{
if (mBitOffset > 0)
{
writeByte(mCurrentByte, false);
mBitOffset = 0;
}
}
Pair<Byte, std::size_t> getRemainingBits() const;
std::pair<unsigned char, unsigned> getRemainingBits() const
{
return {mEndByte, mEndBitOffset};
}
void setChecksumCalculator(AbstractChecksumCalculator* calc);
void setChecksumCalculator(AbstractChecksumCalculator* calc)
{
mChecksumCalculator = calc;
}
void clearChecksumCalculator()
{
mChecksumCalculator = nullptr;
}
void clearChecksumCalculator();
protected:
int mByteOffset{-1};
unsigned mBitOffset{0};
unsigned char mCurrentByte{0};
std::size_t mBitOffset{0};
Byte mCurrentByte{0};
int mEndByteOffset{-1};
unsigned mEndBitOffset{0};
unsigned char mEndByte{0};
std::size_t mEndBitOffset{0};
Byte mEndByte{0};
AbstractChecksumCalculator* mChecksumCalculator{nullptr};
};

View file

@ -9,10 +9,10 @@ bool BufferBitStream::isFinished() const
return mByteOffset == static_cast<int>(mBuffer.size()) - 1;
}
std::vector<unsigned char> BufferBitStream::peekNextNBytes(unsigned n) const
void BufferBitStream::peekNextNBytes(std::size_t n, VecBytes& ret) const
{
std::vector<unsigned char> ret (n, 0);
unsigned count = 0;
ret.resize(n, 0);
std::size_t count = 0;
int start = mByteOffset;
if (start<0)
@ -28,12 +28,11 @@ std::vector<unsigned char> BufferBitStream::peekNextNBytes(unsigned n) const
}
ret[count] = mBuffer[idx];
count ++;
count++;
}
return ret;
}
std::optional<unsigned char> BufferBitStream::readNextByte()
std::optional<uint8_t> BufferBitStream::readNextByte()
{
if (mByteOffset + 1 == static_cast<int>(mBuffer.size()))
{
@ -47,14 +46,14 @@ std::optional<unsigned char> BufferBitStream::readNextByte()
}
}
void BufferBitStream::setBuffer(const std::vector<unsigned char>& data)
void BufferBitStream::setBuffer(const VecBytes& data)
{
mBuffer = data;
}
void BufferBitStream::writeByte(unsigned char data, bool checkOverflow)
void BufferBitStream::writeByte(uint8_t data, bool checkOverflow)
{
unsigned char out_byte{0};
uint8_t out_byte{0};
if (checkOverflow && mBitOffset > 0)
{
out_byte = ByteUtils::getLowerNBits(mCurrentByte, mBitOffset);
@ -76,12 +75,12 @@ void BufferBitStream::writeByte(unsigned char data, bool checkOverflow)
}
void BufferBitStream::writeBytes(const std::vector<unsigned char> data)
void BufferBitStream::writeBytes(const VecBytes& data)
{
std::copy(data.begin(), data.end(), std::back_inserter(mBuffer));
}
const std::vector<unsigned char>& BufferBitStream::getBuffer() const
const VecBytes& BufferBitStream::getBuffer() const
{
return mBuffer;
}

View file

@ -2,28 +2,25 @@
#include "BitStream.h"
#include <vector>
#include <iterator>
class BufferBitStream : public BitStream
{
public:
const std::vector<unsigned char>& getBuffer() const;
const VecBytes& getBuffer() const;
bool isFinished() const override;
std::vector<unsigned char> peekNextNBytes(unsigned n) const override;
void peekNextNBytes(std::size_t n, VecBytes& bytes) const override;
std::optional<unsigned char> readNextByte() override;
std::optional<uint8_t> readNextByte() override;
void reset() override;
void setBuffer(const std::vector<unsigned char>& data);
void setBuffer(const VecBytes& data);
void writeByte(unsigned char data, bool checkOverflow = true) override;
void writeByte(uint8_t data, bool checkOverflow = true) override;
void writeBytes(const std::vector<unsigned char> data) override;
void writeBytes(const VecBytes& data) override;
private:
std::vector<unsigned char> mBuffer;
VecBytes mBuffer;
};

View file

@ -12,16 +12,15 @@ bool InputBitStream::isFinished() const
return mStream->good();
}
std::vector<unsigned char> InputBitStream::peekNextNBytes(unsigned) const
void InputBitStream::peekNextNBytes(std::size_t, VecBytes&) const
{
return {};
}
std::optional<unsigned char> InputBitStream::readNextByte()
std::optional<Byte> InputBitStream::readNextByte()
{
if (mStream->good())
{
return static_cast<unsigned char>(mStream->get());
return static_cast<Byte>(mStream->get());
}
else
{
@ -29,7 +28,7 @@ std::optional<unsigned char> InputBitStream::readNextByte()
}
}
void InputBitStream::writeByte(unsigned char, bool)
void InputBitStream::writeByte(Byte, bool)
{
}

View file

@ -10,13 +10,13 @@ class InputBitStream : public BitStream
bool isFinished() const override;
std::vector<unsigned char> peekNextNBytes(unsigned n) const override;
void peekNextNBytes(std::size_t n, VecBytes& bytes) const override;
std::optional<unsigned char> readNextByte() override;
std::optional<Byte> readNextByte() override;
void writeByte(unsigned char data, bool checkOverflow = true) override;
void writeByte(Byte data, bool checkOverflow = true) override;
void writeBytes(const std::vector<unsigned char>) override
void writeBytes(const VecBytes&) override
{
}

View file

@ -12,22 +12,22 @@ bool OutputBitStream::isFinished() const
return true;
}
std::vector<unsigned char> OutputBitStream::peekNextNBytes(unsigned) const
void OutputBitStream::peekNextNBytes(std::size_t, VecBytes&) const
{
return {};
}
std::optional<unsigned char> OutputBitStream::readNextByte()
std::optional<uint8_t> OutputBitStream::readNextByte()
{
return std::nullopt;
}
void OutputBitStream::writeByte(unsigned char data, bool)
void OutputBitStream::writeByte(uint8_t data, bool)
{
(*mStream) << data;
}
void OutputBitStream::writeBytes(const std::vector<unsigned char> data)
void OutputBitStream::writeBytes(const VecBytes& data)
{
for(auto byte : data)
{

View file

@ -11,13 +11,13 @@ public:
bool isFinished() const override;
std::vector<unsigned char> peekNextNBytes(unsigned n) const override;
void peekNextNBytes(std::size_t n, VecBytes& bytes) const override;
std::optional<unsigned char> readNextByte() override;
std::optional<Byte> readNextByte() override;
void writeByte(unsigned char data, bool checkOverflow = true) override;
void writeByte(Byte data, bool checkOverflow = true) override;
void writeBytes(const std::vector<unsigned char> data) override;
void writeBytes(const VecBytes& data) override;
private:
std::basic_ostream<char>* mStream{nullptr};

View file

@ -12,7 +12,7 @@ public:
this->mData->initializeTo(numPointsX * numPointsY * numPointsZ, T());
}
T getItem(std::size_t idx, std::size_t jdx, std::size_t kdx) const override
T getItem(std::size_t idx, std::size_t jdx, std::size_t kdx = 1) const override
{
return this->mData->getItem(getOffset(idx, jdx, kdx));
}
@ -37,3 +37,40 @@ public:
return this->mData->getLength();
}
};
template<typename T>
class SerializeableGrid : public Grid<T>
{
public:
SerializeableGrid(std::size_t itemSize, const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1)
: Grid<T>(bounds, numPointsX, numPointsY, numPointsZ),
mItemSize(itemSize)
{
}
uint8_t getByte(std::size_t index)
{
const auto item_index = index/mItemSize;
const auto item_internal_index = index % mItemSize;
return this->mData->getItem(item_index).getByte(item_internal_index);
}
void toBuffer(uint8_t* buffer, std::size_t bufferMaxSize)
{
std::size_t count{0};
std::size_t item_count{0};
while(count < bufferMaxSize && item_count < this->mData->getLength())
{
const auto& item = this->mData->getItem(item_count);
for(std::size_t idx = 0; idx< item.getSize(); idx++)
{
buffer[count] = item.getByte(idx);
count++;
}
item_count++;
}
}
private:
std::size_t mItemSize{1};
};