Initial test bootstrap.
This commit is contained in:
parent
6c618749f1
commit
4b308f6c32
94 changed files with 2543 additions and 681 deletions
78
src/base/compiler/KScope.cpp
Normal file
78
src/base/compiler/KScope.cpp
Normal 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();
|
||||
}
|
86
src/base/compiler/KScope.h
Normal file
86
src/base/compiler/KScope.h
Normal 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;
|
||||
};
|
|
@ -33,8 +33,8 @@ public:
|
|||
bool hitBufferFull() const;
|
||||
|
||||
private:
|
||||
|
||||
bool lookAheadSourceEmpty() const;
|
||||
|
||||
unsigned char getSearchBufferItem(unsigned index) const;
|
||||
|
||||
unsigned lookAheadForMatchingChars(unsigned searchIndex);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
11
src/base/core/Serializeable.h
Normal file
11
src/base/core/Serializeable.h
Normal 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;
|
||||
};
|
12
src/base/core/base_types/ByteTypes.h
Normal file
12
src/base/core/base_types/ByteTypes.h
Normal 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;
|
11
src/base/core/base_types/Error.cpp
Normal file
11
src/base/core/base_types/Error.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "Error.h"
|
||||
|
||||
Error::Error(const String& msg)
|
||||
: m_message(msg)
|
||||
{
|
||||
}
|
||||
|
||||
const String& Error::msg() const
|
||||
{
|
||||
return m_message;
|
||||
}
|
15
src/base/core/base_types/Error.h
Normal file
15
src/base/core/base_types/Error.h
Normal 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;
|
||||
};
|
17
src/base/core/base_types/Index.cpp
Normal file
17
src/base/core/base_types/Index.cpp
Normal 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;
|
||||
}
|
19
src/base/core/base_types/Index.h
Normal file
19
src/base/core/base_types/Index.h
Normal 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};
|
||||
};
|
41
src/base/core/base_types/Result.h
Normal file
41
src/base/core/base_types/Result.h
Normal 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
0
src/base/core/build.toml
Normal 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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
6
src/base/core/data_structures/Map.h
Normal file
6
src/base/core/data_structures/Map.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
template<typename T, typename U>
|
||||
class Map{
|
||||
|
||||
};
|
29
src/base/core/data_structures/Optional.h
Normal file
29
src/base/core/data_structures/Optional.h
Normal 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;
|
||||
};
|
27
src/base/core/data_structures/Pair.h
Normal file
27
src/base/core/data_structures/Pair.h
Normal 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;
|
||||
};
|
|
@ -1,7 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
template<typename T>
|
||||
class RawNode
|
||||
{
|
||||
|
|
232
src/base/core/data_structures/String.cpp
Normal file
232
src/base/core/data_structures/String.cpp
Normal 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;
|
||||
}
|
||||
|
59
src/base/core/data_structures/String.h
Normal file
59
src/base/core/data_structures/String.h
Normal 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;
|
||||
};
|
|
@ -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
|
||||
|
|
0
src/base/core/data_structures/Vector.cpp
Normal file
0
src/base/core/data_structures/Vector.cpp
Normal file
233
src/base/core/data_structures/Vector.h
Normal file
233
src/base/core/data_structures/Vector.h
Normal 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};
|
||||
};
|
|
@ -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
|
||||
|
|
35
src/base/core/encoding/CharUtils.cpp
Normal file
35
src/base/core/encoding/CharUtils.cpp
Normal 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';
|
||||
}
|
17
src/base/core/encoding/CharUtils.h
Normal file
17
src/base/core/encoding/CharUtils.h
Normal 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);
|
||||
};
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "ByteTypes.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
114
src/base/core/file_utilities/FileSystemPath.cpp
Normal file
114
src/base/core/file_utilities/FileSystemPath.cpp
Normal 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;
|
||||
}
|
38
src/base/core/file_utilities/FileSystemPath.h
Normal file
38
src/base/core/file_utilities/FileSystemPath.h
Normal 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;
|
||||
};
|
17
src/base/core/loggers/ConsoleLogger.cpp
Normal file
17
src/base/core/loggers/ConsoleLogger.cpp
Normal 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);
|
||||
}
|
11
src/base/core/loggers/ConsoleLogger.h
Normal file
11
src/base/core/loggers/ConsoleLogger.h
Normal 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, ...);
|
||||
};
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
0
src/base/core/memory/Allocator.cpp
Normal file
0
src/base/core/memory/Allocator.cpp
Normal file
29
src/base/core/memory/Allocator.h
Normal file
29
src/base/core/memory/Allocator.h
Normal 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;
|
||||
}
|
||||
};
|
61
src/base/core/memory/Pointer.h
Normal file
61
src/base/core/memory/Pointer.h
Normal 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};
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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};
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue