feature(refactor): big update (#41)
This commit is contained in:
76
src/utils/file.cpp
Normal file
76
src/utils/file.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdinc.hpp"
|
||||
#include "file.hpp"
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
auto file::read(std::filesystem::path const& file) -> std::vector<u8>
|
||||
{
|
||||
auto data = std::vector<u8>{};
|
||||
|
||||
auto stream = std::ifstream{ file, std::ios::binary };
|
||||
|
||||
if (!stream.good() && !stream.is_open())
|
||||
{
|
||||
throw std::runtime_error(fmt::format("couldn't open file {}", file.string()));
|
||||
}
|
||||
|
||||
stream.seekg(0, std::ios::end);
|
||||
std::streamsize size = stream.tellg();
|
||||
stream.seekg(0, std::ios::beg);
|
||||
|
||||
if (size > -1)
|
||||
{
|
||||
data.resize(static_cast<uint32_t>(size));
|
||||
stream.read(reinterpret_cast<char*>(data.data()), size);
|
||||
}
|
||||
|
||||
stream.close();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
auto file::save(std::filesystem::path const& file, std::vector<u8> const& data) -> void
|
||||
{
|
||||
return save(file, data.data(), data.size());
|
||||
}
|
||||
|
||||
auto file::save(std::filesystem::path const& file, u8 const* data, usize size) -> void
|
||||
{
|
||||
auto path = file;
|
||||
|
||||
std::filesystem::create_directories(path.remove_filename());
|
||||
|
||||
auto stream = std::ofstream{ file, std::ios::binary | std::ofstream::out };
|
||||
|
||||
if (stream.is_open())
|
||||
{
|
||||
stream.write(reinterpret_cast<char const*>(data), size);
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
auto file::length(std::filesystem::path const& file) -> usize
|
||||
{
|
||||
auto stream = std::ifstream{ file, std::ios::binary };
|
||||
|
||||
if (stream.good())
|
||||
{
|
||||
stream.seekg(0, std::ios::end);
|
||||
return static_cast<usize>(stream.tellg());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto file::exists(std::filesystem::path const& file) -> bool
|
||||
{
|
||||
return std::filesystem::exists(file);
|
||||
}
|
||||
|
||||
} // namespace xsk::utils
|
21
src/utils/file.hpp
Normal file
21
src/utils/file.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class file
|
||||
{
|
||||
public:
|
||||
static auto read(std::filesystem::path const& file) -> std::vector<u8>;
|
||||
static auto save(std::filesystem::path const& file, std::vector<u8> const& data) -> void;
|
||||
static auto save(std::filesystem::path const& file, u8 const* data, usize size) -> void;
|
||||
static auto length(std::filesystem::path const& file) -> usize;
|
||||
static auto exists(std::filesystem::path const& file) -> bool;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
256
src/utils/reader.cpp
Normal file
256
src/utils/reader.cpp
Normal file
@ -0,0 +1,256 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdinc.hpp"
|
||||
#include "reader.hpp"
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
reader::reader(bool swap) : data_{ nullptr }, size_ { 0 }, pos_{ 0 }, swap_{ swap }
|
||||
{
|
||||
}
|
||||
|
||||
reader::reader(std::vector<u8> const& data, bool swap) : data_{ data.data() }, size_{ static_cast<u32>(data.size()) }, pos_{ 0 }, swap_{ swap }
|
||||
{
|
||||
}
|
||||
|
||||
reader::reader(u8 const* data, u32 size, bool swap) : data_{ data }, size_{ size }, pos_{ 0 }, swap_{ swap }
|
||||
{
|
||||
}
|
||||
|
||||
template<> auto reader::read() -> i8
|
||||
{
|
||||
if (pos_ + 1 > size_) return i8{};
|
||||
|
||||
auto value = *reinterpret_cast<i8 const*>(data_ + pos_);
|
||||
pos_ += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
template<> auto reader::read() -> u8
|
||||
{
|
||||
if (pos_ + 1 > size_) return u8{};
|
||||
|
||||
auto value = *reinterpret_cast<u8 const*>(data_ + pos_);
|
||||
pos_ += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
template<> auto reader::read() -> i16
|
||||
{
|
||||
if (pos_ + 2 > size_) return i16{};
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
auto value = *reinterpret_cast<i16 const*>(data_ + pos_);
|
||||
pos_ += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
auto bytes = std::array<u8, 2>{};
|
||||
bytes[0] = (data_ + pos_)[1];
|
||||
bytes[1] = (data_ + pos_)[0];
|
||||
pos_ += 2;
|
||||
return *reinterpret_cast<i16*>(bytes.data());
|
||||
}
|
||||
|
||||
template<> auto reader::read() -> u16
|
||||
{
|
||||
if (pos_ + 2 > size_) return u16{};
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
auto value = *reinterpret_cast<u16 const*>(data_ + pos_);
|
||||
pos_ += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
auto bytes = std::array<u8, 2>{};
|
||||
bytes[0] = (data_ + pos_)[1];
|
||||
bytes[1] = (data_ + pos_)[0];
|
||||
pos_ += 2;
|
||||
return *reinterpret_cast<u16*>(bytes.data());
|
||||
}
|
||||
|
||||
template<> auto reader::read() -> i32
|
||||
{
|
||||
if (pos_ + 4 > size_) return i32{};
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
auto value = *reinterpret_cast<i32 const*>(data_ + pos_);
|
||||
pos_ += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
auto bytes = std::array<u8, 4>{};
|
||||
bytes[0] = (data_ + pos_)[3];
|
||||
bytes[1] = (data_ + pos_)[2];
|
||||
bytes[2] = (data_ + pos_)[1];
|
||||
bytes[3] = (data_ + pos_)[0];
|
||||
pos_ += 4;
|
||||
return *reinterpret_cast<i32*>(bytes.data());
|
||||
}
|
||||
|
||||
template<> auto reader::read() -> u32
|
||||
{
|
||||
if (pos_ + 4 > size_) return u32{};
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
auto value = *reinterpret_cast<u32 const*>(data_ + pos_);
|
||||
pos_ += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
auto bytes = std::array<u8, 4>{};
|
||||
bytes[0] = (data_ + pos_)[3];
|
||||
bytes[1] = (data_ + pos_)[2];
|
||||
bytes[2] = (data_ + pos_)[1];
|
||||
bytes[3] = (data_ + pos_)[0];
|
||||
pos_ += 4;
|
||||
return *reinterpret_cast<u32*>(bytes.data());
|
||||
}
|
||||
|
||||
template<> auto reader::read() -> i64
|
||||
{
|
||||
if (pos_ + 8 > size_) return i64{};
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
auto value = *reinterpret_cast<i64 const*>(data_ + pos_);
|
||||
pos_ += 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
auto bytes = std::array<u8, 8>{};
|
||||
bytes[0] = (data_ + pos_)[7];
|
||||
bytes[1] = (data_ + pos_)[6];
|
||||
bytes[2] = (data_ + pos_)[5];
|
||||
bytes[3] = (data_ + pos_)[4];
|
||||
bytes[4] = (data_ + pos_)[3];
|
||||
bytes[5] = (data_ + pos_)[2];
|
||||
bytes[6] = (data_ + pos_)[1];
|
||||
bytes[7] = (data_ + pos_)[0];
|
||||
pos_ += 8;
|
||||
return *reinterpret_cast<i64*>(bytes.data());
|
||||
}
|
||||
|
||||
template<> auto reader::read() -> u64
|
||||
{
|
||||
if (pos_ + 8 > size_) return u64{};
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
auto value = *reinterpret_cast<u64 const*>(data_ + pos_);
|
||||
pos_ += 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
auto bytes = std::array<u8, 8>{};
|
||||
bytes[0] = (data_ + pos_)[7];
|
||||
bytes[1] = (data_ + pos_)[6];
|
||||
bytes[2] = (data_ + pos_)[5];
|
||||
bytes[3] = (data_ + pos_)[4];
|
||||
bytes[4] = (data_ + pos_)[3];
|
||||
bytes[5] = (data_ + pos_)[2];
|
||||
bytes[6] = (data_ + pos_)[1];
|
||||
bytes[7] = (data_ + pos_)[0];
|
||||
pos_ += 8;
|
||||
return *reinterpret_cast<u64*>(bytes.data());
|
||||
}
|
||||
|
||||
template<> auto reader::read() -> f32
|
||||
{
|
||||
if (pos_ + 4 > size_) return f32{};
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
auto value = *reinterpret_cast<f32 const*>(data_ + pos_);
|
||||
pos_ += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
auto bytes = std::array<u8, 4>{};
|
||||
bytes[0] = (data_ + pos_)[3];
|
||||
bytes[1] = (data_ + pos_)[2];
|
||||
bytes[2] = (data_ + pos_)[1];
|
||||
bytes[3] = (data_ + pos_)[0];
|
||||
pos_ += 4;
|
||||
return *reinterpret_cast<f32*>(bytes.data());
|
||||
}
|
||||
|
||||
auto reader::read_cstr() -> std::string
|
||||
{
|
||||
auto ret = std::string{ reinterpret_cast<char const*>(data_ + pos_) };
|
||||
pos_ += static_cast<u32>(ret.size() + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto reader::read_bytes(u32 pos, u32 count) -> std::string
|
||||
{
|
||||
auto data = std::string{};
|
||||
|
||||
data.reserve(count * 3);
|
||||
|
||||
for (auto i = pos; i < pos + count; i++)
|
||||
{
|
||||
data += fmt::format("{:02X} ", *reinterpret_cast<u8 const*>(data_ + i));
|
||||
}
|
||||
|
||||
data.pop_back();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
auto reader::is_avail() -> bool
|
||||
{
|
||||
return (pos_ < size_) ? true : false;
|
||||
}
|
||||
|
||||
auto reader::seek(u32 size) -> void
|
||||
{
|
||||
if (pos_ + size <= size_) pos_ += size;
|
||||
}
|
||||
|
||||
auto reader::seek_neg(u32 size) -> void
|
||||
{
|
||||
if (pos_ - size >= 0) pos_ -= size;
|
||||
}
|
||||
|
||||
auto reader::align(u32 size) -> u32
|
||||
{
|
||||
auto pos = pos_;
|
||||
|
||||
pos_ = (pos_ + (size - 1)) & ~(size - 1);
|
||||
|
||||
return pos_ - pos;
|
||||
}
|
||||
|
||||
auto reader::data() -> u8 const*
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
auto reader::size() -> u32
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
auto reader::pos() -> u32
|
||||
{
|
||||
return pos_;
|
||||
}
|
||||
|
||||
auto reader::pos(u32 pos) -> void
|
||||
{
|
||||
if (pos >= 0 && pos <= size_)
|
||||
{
|
||||
pos_ = pos;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xsk::utils
|
40
src/utils/reader.hpp
Normal file
40
src/utils/reader.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class reader
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<reader>;
|
||||
|
||||
private:
|
||||
u8 const* data_;
|
||||
u32 size_;
|
||||
u32 pos_;
|
||||
bool swap_;
|
||||
|
||||
public:
|
||||
reader(bool swap = false);
|
||||
reader(std::vector<u8> const& data, bool swap = false);
|
||||
reader(u8 const* data, u32 size, bool swap = false);
|
||||
template <typename T>
|
||||
auto read() -> T;
|
||||
auto read_cstr() -> std::string;
|
||||
auto read_bytes(u32 pos, u32 count) -> std::string;
|
||||
auto is_avail() -> bool;
|
||||
auto seek(u32 size) -> void;
|
||||
auto seek_neg(u32 size) -> void;
|
||||
auto align(u32 size) -> u32;
|
||||
auto data() -> u8 const*;
|
||||
auto size() -> u32;
|
||||
auto pos() -> u32;
|
||||
auto pos(u32 pos) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
@ -1,6 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdafx.hpp"
|
@ -1,28 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
#include "xsk/utils.hpp"
|
@ -1,29 +1,30 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdafx.hpp"
|
||||
#include "stdinc.hpp"
|
||||
#include "string.hpp"
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
auto string::oct_to_dec(const char* str) -> std::string
|
||||
auto string::oct_to_dec(char const* str) -> std::string
|
||||
{
|
||||
return std::to_string(std::stoi(str, nullptr, 8));
|
||||
}
|
||||
|
||||
auto string::bin_to_dec(const char* str) -> std::string
|
||||
auto string::bin_to_dec(char const* str) -> std::string
|
||||
{
|
||||
return std::to_string(std::stoi(&str[2], nullptr, 2)); // str must prefix 0[bB]
|
||||
}
|
||||
|
||||
auto string::hex_to_dec(const char* str) -> std::string
|
||||
auto string::hex_to_dec(char const* str) -> std::string
|
||||
{
|
||||
return std::to_string(std::stoi(&str[2], nullptr, 16)); // str must prefix 0[xX]
|
||||
}
|
||||
|
||||
auto string::iequals(const std::string& a, const std::string& b) -> bool
|
||||
auto string::iequals(std::string const& a, std::string const& b) -> bool
|
||||
{
|
||||
return (a.size() == b.size()) && std::equal(a.begin(), a.end(), b.begin(), b.end(),
|
||||
[](char a, char b)
|
||||
@ -32,21 +33,21 @@ auto string::iequals(const std::string& a, const std::string& b) -> bool
|
||||
});
|
||||
}
|
||||
|
||||
auto string::is_number(const std::string& s) -> bool
|
||||
auto string::is_number(std::string const& s) -> bool
|
||||
{
|
||||
return !s.empty() && std::all_of(s.begin(), s.end(), isdigit);
|
||||
}
|
||||
|
||||
auto string::is_hex_number(const std::string& s) -> bool
|
||||
auto string::is_hex_number(std::string const& s) -> bool
|
||||
{
|
||||
return !s.empty() && std::all_of(s.begin(), s.end(), isxdigit);
|
||||
}
|
||||
|
||||
auto string::to_lower(const std::string& input) -> std::string
|
||||
auto string::to_lower(std::string const& input) -> std::string
|
||||
{
|
||||
std::string data(input.begin(), input.end());
|
||||
auto data = std::string{ input.begin(), input.end() };
|
||||
|
||||
for (std::size_t i = 0; i < data.size(); i++)
|
||||
for (auto i = 0u; i < data.size(); i++)
|
||||
{
|
||||
data[i] = static_cast<char>(std::tolower(static_cast<unsigned char>(input[i])));
|
||||
}
|
||||
@ -54,10 +55,10 @@ auto string::to_lower(const std::string& input) -> std::string
|
||||
return data;
|
||||
}
|
||||
|
||||
auto string::to_code(const std::string& input) -> std::string
|
||||
auto string::to_code(std::string const& input) -> std::string
|
||||
{
|
||||
std::string data = input.substr(1, input.size() - 2);
|
||||
std::size_t pos;
|
||||
auto data = input.substr(1, input.size() - 2);
|
||||
auto pos = usize{ 0 };
|
||||
|
||||
while ((pos = data.find("\\n")) != std::string::npos)
|
||||
{
|
||||
@ -90,10 +91,10 @@ auto string::to_code(const std::string& input) -> std::string
|
||||
return data;
|
||||
}
|
||||
|
||||
auto string::to_literal(const std::string& input) -> std::string
|
||||
auto string::to_literal(std::string const& input) -> std::string
|
||||
{
|
||||
std::string data(input.begin(), input.end());
|
||||
std::size_t pos;
|
||||
auto data = std::string{ input.begin(), input.end() };
|
||||
auto pos = usize{ 0 };
|
||||
|
||||
while ((pos = data.find('\n')) != std::string::npos)
|
||||
{
|
||||
@ -133,11 +134,11 @@ auto string::to_literal(const std::string& input) -> std::string
|
||||
return data;
|
||||
}
|
||||
|
||||
auto string::fordslash(const std::string& s) -> std::string
|
||||
auto string::fordslash(std::string const& s) -> std::string
|
||||
{
|
||||
std::string data(s.begin(), s.end());
|
||||
auto data = std::string{ s.begin(), s.end() };
|
||||
|
||||
for (std::size_t i = 0; i < data.size(); i++)
|
||||
for (auto i = 0u; i < data.size(); i++)
|
||||
{
|
||||
if (data[i] == '\\') data[i] = '/';
|
||||
}
|
||||
@ -145,11 +146,11 @@ auto string::fordslash(const std::string& s) -> std::string
|
||||
return data;
|
||||
}
|
||||
|
||||
auto string::backslash(const std::string& s) -> std::string
|
||||
auto string::backslash(std::string const& s) -> std::string
|
||||
{
|
||||
std::string data(s.begin(), s.end());
|
||||
auto data = std::string{ s.begin(), s.end() };
|
||||
|
||||
for (std::size_t i = 0; i < data.size(); i++)
|
||||
for (auto i = 0u; i < data.size(); i++)
|
||||
{
|
||||
if (data[i] == '/') data[i] = '\\';
|
||||
}
|
||||
@ -157,9 +158,9 @@ auto string::backslash(const std::string& s) -> std::string
|
||||
return data;
|
||||
}
|
||||
|
||||
auto string::quote(const std::string& s, bool single) -> std::string
|
||||
auto string::quote(std::string const& s, bool single) -> std::string
|
||||
{
|
||||
std::string data(s.begin(), s.end());
|
||||
auto data = std::string{ s.begin(), s.end() };
|
||||
|
||||
if (single)
|
||||
{
|
||||
@ -175,7 +176,7 @@ auto string::quote(const std::string& s, bool single) -> std::string
|
||||
return data;
|
||||
}
|
||||
|
||||
auto string::unquote(const std::string& s) -> std::string
|
||||
auto string::unquote(std::string const& s) -> std::string
|
||||
{
|
||||
if (s.at(0) == '\'' || s.at(0) == '\"')
|
||||
return s.substr(1, s.size() - 2);
|
||||
@ -185,9 +186,9 @@ auto string::unquote(const std::string& s) -> std::string
|
||||
|
||||
auto string::split(std::string& str, char delimiter) -> std::vector<std::string>
|
||||
{
|
||||
std::vector<std::string> tokens;
|
||||
std::stringstream ss(str);
|
||||
std::string tok;
|
||||
auto tokens = std::vector<std::string>{};
|
||||
auto ss = std::stringstream{ str };
|
||||
auto tok = std::string{};
|
||||
|
||||
while (std::getline(ss, tok, delimiter))
|
||||
{
|
||||
@ -197,10 +198,10 @@ auto string::split(std::string& str, char delimiter) -> std::vector<std::string>
|
||||
return tokens;
|
||||
}
|
||||
|
||||
auto string::clean_buffer_lines(std::vector<std::uint8_t>& buffer) -> std::vector<std::string>
|
||||
auto string::clean_buffer_lines(std::vector<u8>& buffer) -> std::vector<std::string>
|
||||
{
|
||||
std::string data = std::string(reinterpret_cast<char*>(buffer.data()), buffer.size());
|
||||
std::size_t pos;
|
||||
auto data = std::string{ reinterpret_cast<char*>(buffer.data()), buffer.size() };
|
||||
auto pos = usize{ 0 };
|
||||
|
||||
while ((pos = data.find("\t")) != std::string::npos)
|
||||
{
|
||||
@ -212,9 +213,9 @@ auto string::clean_buffer_lines(std::vector<std::uint8_t>& buffer) -> std::vecto
|
||||
data = data.replace(pos, 1, "");
|
||||
}
|
||||
|
||||
std::vector<std::string> lines;
|
||||
std::stringstream ss(data);
|
||||
std::string tok;
|
||||
auto lines = std::vector<std::string>{};
|
||||
auto ss = std::stringstream{ data };
|
||||
auto tok = std::string{};
|
||||
|
||||
while (std::getline(ss, tok, '\n'))
|
||||
{
|
||||
@ -226,10 +227,10 @@ auto string::clean_buffer_lines(std::vector<std::uint8_t>& buffer) -> std::vecto
|
||||
|
||||
auto string::parse_code(std::string& line) -> std::vector<std::string>
|
||||
{
|
||||
std::vector<std::string> data;
|
||||
std::regex exp(R"(([_A-Za-z0-9\-]+|\"(?:\\.|[^\"])*?\"|\'(?:\\.|[^\'])*?\')(?:\s+|$))");
|
||||
auto data = std::vector<std::string>{};
|
||||
auto exp = std::regex{ R"(([_A-Za-z0-9\-]+|\"(?:\\.|[^\"])*?\"|\'(?:\\.|[^\'])*?\')(?:\s+|$))" };
|
||||
|
||||
for (auto i = std::sregex_iterator(line.begin(), line.end(), exp); i != std::sregex_iterator(); ++i)
|
||||
for (auto i = std::sregex_iterator{ line.begin(), line.end(), exp }; i != std::sregex_iterator{}; ++i)
|
||||
{
|
||||
data.push_back(i->format("$1"));
|
||||
}
|
||||
@ -237,9 +238,9 @@ auto string::parse_code(std::string& line) -> std::vector<std::string>
|
||||
return data;
|
||||
}
|
||||
|
||||
auto string::float_string(float value) -> std::string
|
||||
auto string::float_string(float value, bool toint) -> std::string
|
||||
{
|
||||
enum flags_t : std::uint8_t { none = 0, negative = 1, integer = 2, has_exp = 4, exp_neg = 8 };
|
||||
enum flags_t : u8 { none = 0, negative = 1, integer = 2, has_exp = 4, exp_neg = 8 };
|
||||
|
||||
auto str = utils::string::va("%g", value);
|
||||
|
||||
@ -253,7 +254,7 @@ auto string::float_string(float value) -> std::string
|
||||
}
|
||||
|
||||
if (!(flags & has_exp))
|
||||
return str += (flags & integer) ? ".0" : "";
|
||||
return str += ((flags & integer) && !toint) ? ".0" : "";
|
||||
|
||||
std::string p_int;
|
||||
std::string p_dec;
|
||||
@ -271,7 +272,7 @@ auto string::float_string(float value) -> std::string
|
||||
while (i < str.size())
|
||||
p_exp.push_back(str[i++]);
|
||||
|
||||
std::size_t offset = std::stoi(p_exp);
|
||||
auto offset = usize{ std::stoul(p_exp) };
|
||||
|
||||
if ((flags & exp_neg))
|
||||
offset -= p_int.size();
|
||||
@ -303,7 +304,7 @@ auto string::float_string(float value) -> std::string
|
||||
while (i < str.size())
|
||||
p_exp.push_back(str[i++]);
|
||||
|
||||
std::size_t offset = std::stoi(p_exp);
|
||||
auto offset = usize{ std::stoul(p_exp) };
|
||||
|
||||
offset -= (flags & exp_neg) ? p_int.size() : p_dec.size();
|
||||
|
43
src/utils/string.hpp
Normal file
43
src/utils/string.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class string
|
||||
{
|
||||
public:
|
||||
template <typename ... Args>
|
||||
static auto va(std::string const& format, Args ... args) -> std::string
|
||||
{
|
||||
usize size = snprintf(nullptr, 0, format.data(), args ...) + 1;
|
||||
std::vector<char> buf;
|
||||
buf.resize(size);
|
||||
snprintf(buf.data(), size, format.data(), args ...);
|
||||
return std::string(buf.data(), buf.data() + size - 1);
|
||||
}
|
||||
|
||||
static auto oct_to_dec(char const* str) -> std::string;
|
||||
static auto bin_to_dec(char const* str) -> std::string;
|
||||
static auto hex_to_dec(char const* str) -> std::string;
|
||||
static auto iequals(std::string const& a, std::string const& b) -> bool;
|
||||
static auto is_number(std::string const& s) -> bool;
|
||||
static auto is_hex_number(std::string const& s) -> bool;
|
||||
static auto to_lower(std::string const& input) -> std::string;
|
||||
static auto to_code(std::string const& input) -> std::string;
|
||||
static auto to_literal(std::string const& input) -> std::string;
|
||||
static auto fordslash(std::string const& s) -> std::string;
|
||||
static auto backslash(std::string const& s) -> std::string;
|
||||
static auto quote(std::string const& s, bool single = true) -> std::string;
|
||||
static auto unquote(std::string const& s) -> std::string;
|
||||
static auto split(std::string& str, char delimiter) -> std::vector<std::string>;
|
||||
static auto clean_buffer_lines(std::vector<u8>& buffer) -> std::vector<std::string>;
|
||||
static auto parse_code(std::string& line) -> std::vector<std::string>;
|
||||
static auto float_string(float value, bool toint = false) -> std::string;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
266
src/utils/writer.cpp
Normal file
266
src/utils/writer.cpp
Normal file
@ -0,0 +1,266 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdinc.hpp"
|
||||
#include "writer.hpp"
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
writer::writer(bool swap) : size_{ 0x100000 }, pos_{ 0 }, swap_{ swap }
|
||||
{
|
||||
data_ = reinterpret_cast<u8*>(std::malloc(size_));
|
||||
std::memset(data_, 0, size_);
|
||||
}
|
||||
|
||||
writer::writer(u32 size, bool swap) : size_{ size }, pos_{ 0 }, swap_{ swap }
|
||||
{
|
||||
data_ = reinterpret_cast<u8*>(std::malloc(size_));
|
||||
std::memset(data_, 0, size_);
|
||||
}
|
||||
|
||||
writer::~writer()
|
||||
{
|
||||
std::free(reinterpret_cast<void*>(data_));
|
||||
}
|
||||
|
||||
auto writer::clear() -> void
|
||||
{
|
||||
std::memset(data_, 0, size_);
|
||||
}
|
||||
|
||||
template<> auto writer::write(i8 data) -> void
|
||||
{
|
||||
if (pos_ + 1 > size_) return;
|
||||
|
||||
*reinterpret_cast<i8*>(data_ + pos_) = data;
|
||||
pos_ += 1;
|
||||
}
|
||||
|
||||
template<> auto writer::write(u8 data) -> void
|
||||
{
|
||||
if (pos_ + 1 > size_) return;
|
||||
|
||||
*reinterpret_cast<u8*>(data_ + pos_) = data;
|
||||
pos_ += 1;
|
||||
}
|
||||
|
||||
template<> auto writer::write(i16 data) -> void
|
||||
{
|
||||
if (pos_ + 2 > size_) return;
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
*reinterpret_cast<i16*>(data_ + pos_) = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
(data_ + pos_)[0] = reinterpret_cast<u8*>(&data)[1];
|
||||
(data_ + pos_)[1] = reinterpret_cast<u8*>(&data)[0];
|
||||
}
|
||||
|
||||
pos_ += 2;
|
||||
}
|
||||
|
||||
template<> auto writer::write(u16 data) -> void
|
||||
{
|
||||
if (pos_ + 2 > size_) return;
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
*reinterpret_cast<u16*>(data_ + pos_) = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
(data_ + pos_)[0] = reinterpret_cast<u8*>(&data)[1];
|
||||
(data_ + pos_)[1] = reinterpret_cast<u8*>(&data)[0];
|
||||
}
|
||||
|
||||
pos_ += 2;
|
||||
}
|
||||
|
||||
template<> auto writer::write(i32 data) -> void
|
||||
{
|
||||
if (pos_ + 4 > size_) return;
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
*reinterpret_cast<i32*>(data_ + pos_) = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
(data_ + pos_)[0] = reinterpret_cast<u8*>(&data)[3];
|
||||
(data_ + pos_)[1] = reinterpret_cast<u8*>(&data)[2];
|
||||
(data_ + pos_)[2] = reinterpret_cast<u8*>(&data)[1];
|
||||
(data_ + pos_)[3] = reinterpret_cast<u8*>(&data)[0];
|
||||
}
|
||||
|
||||
pos_ += 4;
|
||||
}
|
||||
|
||||
template<> auto writer::write(u32 data) -> void
|
||||
{
|
||||
if (pos_ + 4 > size_) return;
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
*reinterpret_cast<u32*>(data_ + pos_) = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
(data_ + pos_)[0] = reinterpret_cast<u8*>(&data)[3];
|
||||
(data_ + pos_)[1] = reinterpret_cast<u8*>(&data)[2];
|
||||
(data_ + pos_)[2] = reinterpret_cast<u8*>(&data)[1];
|
||||
(data_ + pos_)[3] = reinterpret_cast<u8*>(&data)[0];
|
||||
}
|
||||
|
||||
pos_ += 4;
|
||||
}
|
||||
|
||||
template<> auto writer::write(i64 data) -> void
|
||||
{
|
||||
if (pos_ + 8 > size_) return;
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
*reinterpret_cast<i64*>(data_ + pos_) = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
(data_ + pos_)[0] = reinterpret_cast<u8*>(&data)[7];
|
||||
(data_ + pos_)[1] = reinterpret_cast<u8*>(&data)[6];
|
||||
(data_ + pos_)[2] = reinterpret_cast<u8*>(&data)[5];
|
||||
(data_ + pos_)[3] = reinterpret_cast<u8*>(&data)[4];
|
||||
(data_ + pos_)[4] = reinterpret_cast<u8*>(&data)[3];
|
||||
(data_ + pos_)[5] = reinterpret_cast<u8*>(&data)[2];
|
||||
(data_ + pos_)[6] = reinterpret_cast<u8*>(&data)[1];
|
||||
(data_ + pos_)[7] = reinterpret_cast<u8*>(&data)[0];
|
||||
}
|
||||
|
||||
pos_ += 8;
|
||||
}
|
||||
|
||||
template<> auto writer::write(u64 data) -> void
|
||||
{
|
||||
if (pos_ + 8 > size_) return;
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
*reinterpret_cast<u64*>(data_ + pos_) = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
(data_ + pos_)[0] = reinterpret_cast<u8*>(&data)[7];
|
||||
(data_ + pos_)[1] = reinterpret_cast<u8*>(&data)[6];
|
||||
(data_ + pos_)[2] = reinterpret_cast<u8*>(&data)[5];
|
||||
(data_ + pos_)[3] = reinterpret_cast<u8*>(&data)[4];
|
||||
(data_ + pos_)[4] = reinterpret_cast<u8*>(&data)[3];
|
||||
(data_ + pos_)[5] = reinterpret_cast<u8*>(&data)[2];
|
||||
(data_ + pos_)[6] = reinterpret_cast<u8*>(&data)[1];
|
||||
(data_ + pos_)[7] = reinterpret_cast<u8*>(&data)[0];
|
||||
}
|
||||
|
||||
pos_ += 8;
|
||||
}
|
||||
|
||||
template<> auto writer::write(f32 data) -> void
|
||||
{
|
||||
if (pos_ + 4 > size_) return;
|
||||
|
||||
if (!swap_)
|
||||
{
|
||||
*reinterpret_cast<f32*>(data_ + pos_) = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
(data_ + pos_)[0] = reinterpret_cast<u8*>(&data)[3];
|
||||
(data_ + pos_)[1] = reinterpret_cast<u8*>(&data)[2];
|
||||
(data_ + pos_)[2] = reinterpret_cast<u8*>(&data)[1];
|
||||
(data_ + pos_)[3] = reinterpret_cast<u8*>(&data)[0];
|
||||
}
|
||||
|
||||
pos_ += 4;
|
||||
}
|
||||
|
||||
auto writer::write_string(std::string const& data) -> void
|
||||
{
|
||||
if (pos_ + data.size() > size_) return;
|
||||
|
||||
std::memcpy(reinterpret_cast<void*>(data_ + pos_), data.data(), data.size());
|
||||
pos_ += static_cast<u32>(data.size());
|
||||
}
|
||||
|
||||
auto writer::write_cstr(std::string const& data) -> void
|
||||
{
|
||||
if (pos_ + data.size() >= size_) return;
|
||||
|
||||
std::memcpy(reinterpret_cast<void*>(data_ + pos_), data.data(), data.size());
|
||||
pos_ += static_cast<u32>(data.size() + 1);
|
||||
}
|
||||
|
||||
auto writer::read_bytes(u32 pos, u32 count) -> std::string
|
||||
{
|
||||
auto data = std::string{};
|
||||
|
||||
data.reserve(count * 3);
|
||||
|
||||
for (auto i = pos; i < pos + count; i++)
|
||||
{
|
||||
data += fmt::format("{:02X} ", *reinterpret_cast<const u8*>(data_ + i));
|
||||
}
|
||||
|
||||
data.pop_back();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
auto writer::is_avail() -> bool
|
||||
{
|
||||
return (pos_ < size_) ? true : false;
|
||||
}
|
||||
|
||||
auto writer::seek(u32 size) -> void
|
||||
{
|
||||
if (pos_ + size <= size_) pos_ += size;
|
||||
}
|
||||
|
||||
auto writer::seek_neg(u32 size) -> void
|
||||
{
|
||||
if (pos_ - size >= 0) pos_ -= size;
|
||||
}
|
||||
|
||||
auto writer::align(u32 size) -> u32
|
||||
{
|
||||
auto pos = pos_;
|
||||
|
||||
pos_ = (pos_ + (size - 1)) & ~(size - 1);
|
||||
|
||||
return pos_ - pos;
|
||||
}
|
||||
|
||||
auto writer::data() -> const u8*
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
auto writer::size() -> u32
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
auto writer::pos() -> u32
|
||||
{
|
||||
return pos_;
|
||||
}
|
||||
|
||||
auto writer::pos(u32 pos) -> void
|
||||
{
|
||||
if (pos >= 0 && pos <= size_)
|
||||
{
|
||||
pos_ = pos;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xsk::utils
|
42
src/utils/writer.hpp
Normal file
42
src/utils/writer.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class writer
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<writer>;
|
||||
|
||||
private:
|
||||
u8* data_;
|
||||
u32 size_;
|
||||
u32 pos_;
|
||||
bool swap_;
|
||||
|
||||
public:
|
||||
writer(bool swap = false);
|
||||
writer(u32 size, bool swap = false);
|
||||
~writer();
|
||||
auto clear() -> void;
|
||||
template <typename T>
|
||||
auto write(T data) -> void;
|
||||
auto write_string(std::string const& data) -> void;
|
||||
auto write_cstr(std::string const& data) -> void;
|
||||
auto read_bytes(u32 pos, u32 count) -> std::string;
|
||||
auto is_avail() -> bool;
|
||||
auto seek(u32 size) -> void;
|
||||
auto seek_neg(u32 size) -> void;
|
||||
auto align(u32 size) -> u32;
|
||||
auto data() -> u8 const*;
|
||||
auto size() -> u32;
|
||||
auto pos() -> u32;
|
||||
auto pos(u32 pos) -> void;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
@ -1,25 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
struct block
|
||||
{
|
||||
using ptr = std::unique_ptr<block>;
|
||||
|
||||
std::string loc_end;
|
||||
std::string loc_break;
|
||||
std::string loc_continue;
|
||||
abort_t abort;
|
||||
bool is_dev;
|
||||
|
||||
block() : abort(abort_t::abort_none), is_dev(false) {}
|
||||
block(const std::string& lbreak, const std::string& lcont) : loc_break(lbreak), loc_continue(lcont), abort(abort_t::abort_none), is_dev(false) {}
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class assembler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<assembler>;
|
||||
|
||||
virtual ~assembler() = default;
|
||||
virtual auto output() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void assemble(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||
virtual void assemble(const std::string& file, assembly::ptr& data) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class compiler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<compiler>;
|
||||
|
||||
virtual ~compiler() = default;
|
||||
virtual auto output() -> assembly::ptr = 0;
|
||||
virtual auto output_raw() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void compile(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class context
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<context>;
|
||||
|
||||
virtual ~context() = default;
|
||||
virtual void init(build mode, read_cb_type callback) = 0;
|
||||
virtual void cleanup() = 0;
|
||||
|
||||
virtual auto assembler() -> assembler& = 0;
|
||||
virtual auto disassembler() -> disassembler& = 0;
|
||||
virtual auto compiler() -> compiler& = 0;
|
||||
virtual auto decompiler() -> decompiler& = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class decompiler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<decompiler>;
|
||||
|
||||
virtual ~decompiler() = default;
|
||||
virtual auto output() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void decompile(const std::string& file, const assembly::ptr& data) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class disassembler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<disassembler>;
|
||||
|
||||
virtual ~disassembler() = default;
|
||||
virtual auto output() -> assembly::ptr = 0;
|
||||
virtual auto output_raw() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void disassemble(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
@ -1,46 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
class error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]: "s + what) {}
|
||||
};
|
||||
|
||||
class asm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
asm_error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]:assembler: "s + what) {}
|
||||
};
|
||||
|
||||
class disasm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
disasm_error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]:disassembler: "s + what) {}
|
||||
};
|
||||
|
||||
class comp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
comp_error(const location& loc, const std::string& what)
|
||||
: std::runtime_error("[ERROR]:compiler:" + loc.print() + ": " + what) {}
|
||||
};
|
||||
|
||||
class decomp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
decomp_error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]:decompiler: "s + what) {}
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
@ -1,229 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
/// A point in a source file.
|
||||
class position
|
||||
{
|
||||
public:
|
||||
/// Type for file name.
|
||||
typedef const std::string filename_type;
|
||||
/// Type for line and column numbers.
|
||||
typedef int counter_type;
|
||||
|
||||
/// Construct a position.
|
||||
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
: filename(f), line(l), column(c) {}
|
||||
|
||||
/// Initialization.
|
||||
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
filename = fn;
|
||||
line = l;
|
||||
column = c;
|
||||
}
|
||||
|
||||
/** \name Line and Column related manipulators
|
||||
** \{ */
|
||||
/// (line related) Advance to the COUNT next lines.
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
column = 1;
|
||||
line = add_(line, count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// (column related) Advance to the COUNT next columns.
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
column = add_(column, count, 1);
|
||||
}
|
||||
/** \} */
|
||||
|
||||
/// File name to which this position refers.
|
||||
filename_type *filename;
|
||||
/// Current line number.
|
||||
counter_type line;
|
||||
/// Current column number.
|
||||
counter_type column;
|
||||
|
||||
private:
|
||||
/// Compute max (min, lhs+rhs).
|
||||
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
|
||||
{
|
||||
return lhs + rhs < min ? min : lhs + rhs;
|
||||
}
|
||||
};
|
||||
|
||||
/// Add \a width columns, in place.
|
||||
inline position& operator+=(position &res, position::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add \a width columns.
|
||||
inline position operator+(position res, position::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns, in place.
|
||||
inline position& operator-=(position &res, position::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns.
|
||||
inline position operator-(position res, position::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
/** \brief Intercept output stream redirection.
|
||||
** \param ostr the destination output stream
|
||||
** \param pos a reference to the position to redirect
|
||||
*/
|
||||
template <typename YYChar>
|
||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const position &pos)
|
||||
{
|
||||
if (pos.filename)
|
||||
ostr << *pos.filename << ':';
|
||||
return ostr << pos.line << '.' << pos.column;
|
||||
}
|
||||
|
||||
/// Two points in a source file.
|
||||
class location
|
||||
{
|
||||
public:
|
||||
/// Type for file name.
|
||||
typedef position::filename_type filename_type;
|
||||
/// Type for line and column numbers.
|
||||
typedef position::counter_type counter_type;
|
||||
|
||||
/// Construct a location from \a b to \a e.
|
||||
location(const position &b, const position &e)
|
||||
: begin(b), end(e) {}
|
||||
|
||||
/// Construct a 0-width location in \a p.
|
||||
explicit location(const position &p = position())
|
||||
: begin(p), end(p) {}
|
||||
|
||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
||||
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
|
||||
: begin(f, l, c), end(f, l, c) {}
|
||||
|
||||
/// Initialization.
|
||||
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
begin.initialize(f, l, c);
|
||||
end = begin;
|
||||
}
|
||||
|
||||
/** \name Line and Column related manipulators
|
||||
** \{ */
|
||||
public:
|
||||
/// Reset initial location to final location.
|
||||
void step()
|
||||
{
|
||||
begin = end;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next columns.
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
end += count;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next lines.
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
end.lines(count);
|
||||
}
|
||||
/** \} */
|
||||
|
||||
public:
|
||||
auto print() const -> std::string
|
||||
{
|
||||
return *begin.filename + ":" + std::to_string(begin.line) + ":" + std::to_string(begin.column);
|
||||
}
|
||||
|
||||
auto label() const -> std::string
|
||||
{
|
||||
return utils::string::va("loc_%X", begin.line);
|
||||
}
|
||||
|
||||
public:
|
||||
/// Beginning of the located region.
|
||||
position begin;
|
||||
/// End of the located region.
|
||||
position end;
|
||||
};
|
||||
|
||||
/// Join two locations, in place.
|
||||
inline location& operator+=(location &res, const location &end)
|
||||
{
|
||||
res.end = end.end;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Join two locations.
|
||||
inline location operator+(location res, const location &end)
|
||||
{
|
||||
return res += end;
|
||||
}
|
||||
|
||||
/// Add \a width columns to the end position, in place.
|
||||
inline location& operator+=(location &res, location::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add \a width columns to the end position.
|
||||
inline location operator+(location res, location::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns to the end position, in place.
|
||||
inline location& operator-=(location &res, location::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns to the end position.
|
||||
inline location operator-(location res, location::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
/** \brief Intercept output stream redirection.
|
||||
** \param ostr the destination output stream
|
||||
** \param loc a reference to the location to redirect
|
||||
**
|
||||
** Avoid duplicate information.
|
||||
*/
|
||||
template <typename YYChar>
|
||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const location &loc)
|
||||
{
|
||||
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
||||
ostr << loc.begin;
|
||||
if (loc.end.filename && (!loc.begin.filename || *loc.begin.filename != *loc.end.filename))
|
||||
ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.line < loc.end.line)
|
||||
ostr << '-' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.column < end_col)
|
||||
ostr << '-' << end_col;
|
||||
return ostr;
|
||||
}
|
||||
|
||||
} // namespace xsk::arc
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,181 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::arc
|
||||
{
|
||||
|
||||
using read_cb_type = std::function<std::vector<std::uint8_t>(const std::string&)>;
|
||||
|
||||
enum class build
|
||||
{
|
||||
prod,
|
||||
dev,
|
||||
};
|
||||
|
||||
enum class abort_t
|
||||
{
|
||||
abort_none = 0,
|
||||
abort_continue = 1,
|
||||
abort_break = 2,
|
||||
abort_return = 3,
|
||||
};
|
||||
|
||||
struct include_t
|
||||
{
|
||||
std::string name;
|
||||
std::vector<std::string> funcs;
|
||||
|
||||
include_t(const std::string& name, const std::vector<std::string>& funcs) : name(name), funcs(funcs) {}
|
||||
};
|
||||
|
||||
struct animtree_t
|
||||
{
|
||||
std::string name;
|
||||
bool loaded;
|
||||
};
|
||||
|
||||
struct instruction
|
||||
{
|
||||
using ptr = std::unique_ptr<instruction>;
|
||||
|
||||
std::uint32_t index;
|
||||
std::uint32_t size;
|
||||
std::uint8_t opcode;
|
||||
std::vector<std::string> data;
|
||||
|
||||
instruction() : index(0), size(0), opcode(0xFF) {}
|
||||
};
|
||||
|
||||
struct function
|
||||
{
|
||||
using ptr = std::unique_ptr<function>;
|
||||
|
||||
std::uint32_t index;
|
||||
std::uint32_t size;
|
||||
std::uint8_t params;
|
||||
std::uint8_t flags;
|
||||
std::string name;
|
||||
std::vector<instruction::ptr> instructions;
|
||||
std::unordered_map<std::uint32_t, std::string> labels;
|
||||
|
||||
function() : index(0), size(0), params(0), flags(0) {}
|
||||
};
|
||||
|
||||
struct animation_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<animation_ref>;
|
||||
|
||||
std::string name;
|
||||
std::uint32_t ref;
|
||||
};
|
||||
|
||||
struct animtree_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<animtree_ref>;
|
||||
|
||||
std::string name;
|
||||
std::vector<std::uint32_t> refs;
|
||||
std::vector<animation_ref> anims;
|
||||
};
|
||||
|
||||
enum class string_type : std::uint8_t
|
||||
{
|
||||
literal = 0,
|
||||
canonical = 1,
|
||||
};
|
||||
|
||||
struct string_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<string_ref>;
|
||||
|
||||
std::string name;
|
||||
std::uint8_t type;
|
||||
std::vector<std::uint32_t> refs;
|
||||
};
|
||||
|
||||
enum class export_flags : std::uint8_t
|
||||
{
|
||||
export_none = 0x00,
|
||||
export_public = 0x01,
|
||||
export_autoexec = 0x02,
|
||||
export_private = 0x04,
|
||||
export_codecall = 0x08,
|
||||
export_private2 = 0x10,
|
||||
export_varargs = 0x20,
|
||||
};
|
||||
|
||||
struct export_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<export_ref>;
|
||||
|
||||
std::uint32_t checksum;
|
||||
std::uint32_t offset;
|
||||
std::string name;
|
||||
std::string space;
|
||||
std::uint8_t params;
|
||||
std::uint8_t flags;
|
||||
std::uint32_t size;
|
||||
};
|
||||
|
||||
enum class import_flags : std::uint8_t
|
||||
{
|
||||
none = 0,
|
||||
func_reference = 1,
|
||||
func_call = 2,
|
||||
func_call_thread = 3,
|
||||
meth_call = 4,
|
||||
meth_call_thread = 5,
|
||||
developer = 0x10,
|
||||
unk = 0x20, // T7, T8, T9
|
||||
};
|
||||
|
||||
struct import_ref
|
||||
{
|
||||
using ptr = std::shared_ptr<import_ref>;
|
||||
|
||||
std::string space;
|
||||
std::string name;
|
||||
std::uint8_t params;
|
||||
std::uint8_t flags;
|
||||
std::vector<std::uint32_t> refs;
|
||||
};
|
||||
|
||||
struct header
|
||||
{
|
||||
std::uint64_t magic;
|
||||
std::uint32_t source_crc;
|
||||
std::uint32_t include_offset;
|
||||
std::uint32_t animtree_offset;
|
||||
std::uint32_t cseg_offset;
|
||||
std::uint32_t stringtablefixup_offset;
|
||||
std::uint32_t exports_offset;
|
||||
std::uint32_t imports_offset;
|
||||
std::uint32_t fixup_offset;
|
||||
std::uint32_t profile_offset;
|
||||
std::uint32_t cseg_size;
|
||||
std::uint16_t name;
|
||||
std::uint16_t stringtablefixup_count;
|
||||
std::uint16_t exports_count;
|
||||
std::uint16_t imports_count;
|
||||
std::uint16_t fixup_count;
|
||||
std::uint16_t profile_count;
|
||||
std::uint8_t include_count;
|
||||
std::uint8_t animtree_count;
|
||||
std::uint8_t flags;
|
||||
// char[1] pad;
|
||||
};
|
||||
|
||||
struct assembly
|
||||
{
|
||||
using ptr = std::unique_ptr<assembly>;
|
||||
|
||||
std::vector<function::ptr> functions;
|
||||
std::vector<std::string> includes;
|
||||
std::vector<animtree_ref> animtrees;
|
||||
};
|
||||
|
||||
} // namespace xsk::arc
|
@ -1,64 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdafx.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
auto asset::serialize() -> std::vector<std::uint8_t>
|
||||
{
|
||||
std::vector<std::uint8_t> data;
|
||||
|
||||
data.resize(name.size() + compressedLen + bytecodeLen + 13);
|
||||
std::memset(data.data(), 0, data.size());
|
||||
|
||||
std::size_t pos = 0;
|
||||
|
||||
std::memcpy(&data[pos], name.data(), name.size() + 1);
|
||||
pos += name.size() + 1;
|
||||
|
||||
*reinterpret_cast<std::uint32_t*>(&data[pos]) = compressedLen;
|
||||
pos += 4;
|
||||
|
||||
*reinterpret_cast<std::uint32_t*>(&data[pos]) = len;
|
||||
pos += 4;
|
||||
|
||||
*reinterpret_cast<std::uint32_t*>(&data[pos]) = bytecodeLen;
|
||||
pos += 4;
|
||||
|
||||
std::memcpy(&data[pos], buffer.data(), buffer.size());
|
||||
pos += buffer.size();
|
||||
|
||||
std::memcpy(&data[pos], bytecode.data(), bytecode.size());
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void asset::deserialize(std::vector<std::uint8_t> data)
|
||||
{
|
||||
std::size_t pos = 0;
|
||||
|
||||
name = std::string(reinterpret_cast<const char*>(data.data()));
|
||||
pos += name.size() + 1;
|
||||
|
||||
compressedLen = *reinterpret_cast<std::uint32_t*>(data.data() + pos);
|
||||
pos += 4;
|
||||
|
||||
len = *reinterpret_cast<std::uint32_t*>(data.data() + pos);
|
||||
pos += 4;
|
||||
|
||||
bytecodeLen = *reinterpret_cast<std::uint32_t*>(data.data() + pos);
|
||||
pos += 4;
|
||||
|
||||
buffer.resize(compressedLen);
|
||||
std::memcpy(buffer.data(), data.data() + pos, compressedLen);
|
||||
pos += buffer.size();
|
||||
|
||||
bytecode.resize(bytecodeLen);
|
||||
std::memcpy(bytecode.data(), data.data() + pos, bytecodeLen);
|
||||
}
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
struct asset
|
||||
{
|
||||
using ptr = std::unique_ptr<asset>;
|
||||
|
||||
std::string name;
|
||||
std::uint32_t compressedLen;
|
||||
std::uint32_t len;
|
||||
std::uint32_t bytecodeLen;
|
||||
std::vector<std::uint8_t> buffer;
|
||||
std::vector<std::uint8_t> bytecode;
|
||||
|
||||
auto serialize() -> std::vector<std::uint8_t>;
|
||||
void deserialize(std::vector<std::uint8_t> data);
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,175 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdafx.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
block::block() : local_vars_create_count(0), local_vars_public_count(0),
|
||||
abort(abort_t::abort_none), is_last(false) { }
|
||||
|
||||
void block::transfer(const block::ptr& child)
|
||||
{
|
||||
child->loc_break = this->loc_break;
|
||||
child->loc_continue = this->loc_continue;
|
||||
|
||||
for (std::uint32_t i = 0; i < child->local_vars_public_count || i < this->local_vars_create_count; i++ )
|
||||
{
|
||||
auto pos = child->find_variable(i, this->local_vars.at(i).name);
|
||||
|
||||
if (pos < 0)
|
||||
{
|
||||
child->local_vars_public_count++;
|
||||
child->local_vars.insert(child->local_vars.begin() + i, this->local_vars.at(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& v = child->local_vars;
|
||||
if (pos > std::int32_t(i))
|
||||
std::rotate(v.rend() - pos - 1, v.rend() - pos, v.rend() - i);
|
||||
else
|
||||
std::rotate(v.begin() + pos, v.begin() + pos + 1, v.begin() + i + 1);
|
||||
child->local_vars.at(i).init = this->local_vars.at(i).init;
|
||||
|
||||
if (child->local_vars_public_count <= i)
|
||||
child->local_vars_public_count++;
|
||||
}
|
||||
}
|
||||
|
||||
child->local_vars_create_count = this->local_vars_create_count;
|
||||
child->abort = abort_t::abort_none;
|
||||
}
|
||||
|
||||
void block::copy(const block::ptr& child)
|
||||
{
|
||||
child->local_vars = this->local_vars;
|
||||
child->local_vars_create_count = this->local_vars_create_count;
|
||||
child->local_vars_public_count = 0;
|
||||
}
|
||||
|
||||
void block::append(const std::vector<block*>& childs)
|
||||
{
|
||||
bool glob = true;
|
||||
|
||||
if (childs.size() == 0) return;
|
||||
|
||||
for (std::size_t i = 0; i < childs.at(0)->local_vars.size(); i++ )
|
||||
{
|
||||
glob = true;
|
||||
auto& var = childs.at(0)->local_vars.at(i);
|
||||
|
||||
if (this->find_variable(0, var.name) < 0)
|
||||
{
|
||||
for (std::size_t j = 1; j < childs.size(); j++ )
|
||||
{
|
||||
if (childs.at(j)->find_variable(0, var.name) < 0)
|
||||
{
|
||||
glob = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (glob)
|
||||
{
|
||||
this->local_vars.push_back(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void block::merge(const std::vector<block*>& childs)
|
||||
{
|
||||
if (childs.size() == 0) return;
|
||||
|
||||
for (std::size_t childidx = 0; childidx < childs.size(); childidx++)
|
||||
{
|
||||
auto child = childs[childidx];
|
||||
|
||||
child->local_vars_public_count = static_cast<std::uint32_t>(this->local_vars.size());
|
||||
for (std::size_t i = 0; i < this->local_vars.size(); i++ )
|
||||
{
|
||||
auto& name = this->local_vars.at(i).name;
|
||||
|
||||
auto pos = child->find_variable(i, name);
|
||||
|
||||
if (pos < 0)
|
||||
{
|
||||
child->local_vars.insert(child->local_vars.begin() + i, this->local_vars.at(i));
|
||||
}
|
||||
else if (pos > static_cast<std::int32_t>(i))
|
||||
{
|
||||
auto& v = child->local_vars;
|
||||
std::rotate(v.rend() - pos - 1, v.rend() - pos, v.rend() - i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void block::init_from_child(const std::vector<block*>& childs)
|
||||
{
|
||||
if (childs.size() == 0) return;
|
||||
|
||||
auto create_count = childs[0]->local_vars_public_count;
|
||||
|
||||
for (std::size_t i = 1; i < childs.size(); ++i )
|
||||
{
|
||||
auto child = childs[i];
|
||||
if ( child->local_vars_public_count < create_count )
|
||||
create_count = child->local_vars_public_count;
|
||||
}
|
||||
|
||||
this->local_vars_create_count = create_count;
|
||||
|
||||
bool init = true;
|
||||
for (std::uint32_t i = 0; i < create_count; i++ )
|
||||
{
|
||||
init = true;
|
||||
if (!this->local_vars.at(i).init)
|
||||
{
|
||||
for (std::size_t j = 0; j < childs.size(); j++ )
|
||||
{
|
||||
auto child = childs[j];
|
||||
|
||||
if (!child->local_vars.at(i).init)
|
||||
{
|
||||
init = false;
|
||||
}
|
||||
}
|
||||
if (init) this->local_vars.at(i).init = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto block::find_variable(std::size_t start, const std::string& name) -> std::int32_t
|
||||
{
|
||||
for (std::size_t i = start; i < local_vars.size(); ++i )
|
||||
{
|
||||
if (local_vars.at(i).name == name)
|
||||
return static_cast<std::int32_t>(i);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void block::transfer_decompiler(const block::ptr& child)
|
||||
{
|
||||
for (std::uint32_t i = 0; i < this->local_vars.size(); i++ )
|
||||
{
|
||||
child->local_vars.push_back(this->local_vars.at(i));
|
||||
}
|
||||
|
||||
child->local_vars_public_count = static_cast<std::uint32_t>(this->local_vars.size());
|
||||
}
|
||||
|
||||
void block::append_decompiler(const block::ptr& child, bool all)
|
||||
{
|
||||
auto total = all ? child->local_vars.size() : child->local_vars_public_count;
|
||||
|
||||
for (auto i = this->local_vars.size(); i < total; i++ )
|
||||
{
|
||||
this->local_vars.push_back(child->local_vars.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,42 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
struct local_var
|
||||
{
|
||||
std::string name;
|
||||
std::uint8_t create;
|
||||
bool init;
|
||||
};
|
||||
|
||||
struct block
|
||||
{
|
||||
using ptr = std::unique_ptr<block>;
|
||||
|
||||
std::string loc_end;
|
||||
std::string loc_break;
|
||||
std::string loc_continue;
|
||||
std::vector<local_var> local_vars;
|
||||
std::uint32_t local_vars_create_count;
|
||||
std::uint32_t local_vars_public_count;
|
||||
abort_t abort;
|
||||
bool is_last;
|
||||
|
||||
block();
|
||||
void transfer(const block::ptr& child);
|
||||
void copy(const block::ptr& child);
|
||||
void append(const std::vector<block*>& childs);
|
||||
void merge(const std::vector<block*>& childs);
|
||||
void init_from_child(const std::vector<block*>& childs);
|
||||
auto find_variable(std::size_t start, const std::string& name) -> std::int32_t;
|
||||
void transfer_decompiler(const block::ptr& child);
|
||||
void append_decompiler(const block::ptr& child, bool all = false);
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,23 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class assembler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<assembler>;
|
||||
|
||||
virtual ~assembler() = default;
|
||||
virtual auto output_script() -> std::vector<std::uint8_t> = 0;
|
||||
virtual auto output_stack() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void assemble(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||
virtual void assemble(const std::string& file, std::vector<gsc::function::ptr>& funcs) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class compiler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<compiler>;
|
||||
|
||||
virtual ~compiler() = default;
|
||||
virtual auto output() -> std::vector<gsc::function::ptr> = 0;
|
||||
virtual void compile(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class context
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<context>;
|
||||
|
||||
virtual ~context() = default;
|
||||
virtual void init(build mode, read_cb_type callback) = 0;
|
||||
virtual void cleanup() = 0;
|
||||
|
||||
virtual auto assembler() -> assembler& = 0;
|
||||
virtual auto disassembler() -> disassembler& = 0;
|
||||
virtual auto compiler() -> compiler& = 0;
|
||||
virtual auto decompiler() -> decompiler& = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class decompiler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<decompiler>;
|
||||
|
||||
virtual ~decompiler() = default;
|
||||
virtual auto output() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void decompile(const std::string& file, std::vector<gsc::function::ptr>& funcs) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class disassembler
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<disassembler>;
|
||||
|
||||
virtual ~disassembler() = default;
|
||||
virtual auto output() -> std::vector<gsc::function::ptr> = 0;
|
||||
virtual auto output_data() -> std::vector<std::uint8_t> = 0;
|
||||
virtual void disassemble(const std::string& file, std::vector<std::uint8_t>& script, std::vector<std::uint8_t>& stack) = 0;
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,46 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
class error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]: "s + what) {}
|
||||
};
|
||||
|
||||
class asm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
asm_error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]:assembler: "s + what) {}
|
||||
};
|
||||
|
||||
class disasm_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
disasm_error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]:disassembler: "s + what) {}
|
||||
};
|
||||
|
||||
class comp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
comp_error(const gsc::location& loc, const std::string& what)
|
||||
: std::runtime_error("[ERROR]:compiler:" + loc.print() + ": " + what) {}
|
||||
};
|
||||
|
||||
class decomp_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
decomp_error(const std::string& what)
|
||||
: std::runtime_error("[ERROR]:decompiler: "s + what) {}
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,229 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
/// A point in a source file.
|
||||
class position
|
||||
{
|
||||
public:
|
||||
/// Type for file name.
|
||||
typedef const std::string filename_type;
|
||||
/// Type for line and column numbers.
|
||||
typedef int counter_type;
|
||||
|
||||
/// Construct a position.
|
||||
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
: filename(f), line(l), column(c) {}
|
||||
|
||||
/// Initialization.
|
||||
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
filename = fn;
|
||||
line = l;
|
||||
column = c;
|
||||
}
|
||||
|
||||
/** \name Line and Column related manipulators
|
||||
** \{ */
|
||||
/// (line related) Advance to the COUNT next lines.
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
column = 1;
|
||||
line = add_(line, count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// (column related) Advance to the COUNT next columns.
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
column = add_(column, count, 1);
|
||||
}
|
||||
/** \} */
|
||||
|
||||
/// File name to which this position refers.
|
||||
filename_type *filename;
|
||||
/// Current line number.
|
||||
counter_type line;
|
||||
/// Current column number.
|
||||
counter_type column;
|
||||
|
||||
private:
|
||||
/// Compute max (min, lhs+rhs).
|
||||
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
|
||||
{
|
||||
return lhs + rhs < min ? min : lhs + rhs;
|
||||
}
|
||||
};
|
||||
|
||||
/// Add \a width columns, in place.
|
||||
inline position& operator+=(position &res, position::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add \a width columns.
|
||||
inline position operator+(position res, position::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns, in place.
|
||||
inline position& operator-=(position &res, position::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns.
|
||||
inline position operator-(position res, position::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
/** \brief Intercept output stream redirection.
|
||||
** \param ostr the destination output stream
|
||||
** \param pos a reference to the position to redirect
|
||||
*/
|
||||
template <typename YYChar>
|
||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const position &pos)
|
||||
{
|
||||
if (pos.filename)
|
||||
ostr << *pos.filename << ':';
|
||||
return ostr << pos.line << '.' << pos.column;
|
||||
}
|
||||
|
||||
/// Two points in a source file.
|
||||
class location
|
||||
{
|
||||
public:
|
||||
/// Type for file name.
|
||||
typedef position::filename_type filename_type;
|
||||
/// Type for line and column numbers.
|
||||
typedef position::counter_type counter_type;
|
||||
|
||||
/// Construct a location from \a b to \a e.
|
||||
location(const position &b, const position &e)
|
||||
: begin(b), end(e) {}
|
||||
|
||||
/// Construct a 0-width location in \a p.
|
||||
explicit location(const position &p = position())
|
||||
: begin(p), end(p) {}
|
||||
|
||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
||||
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
|
||||
: begin(f, l, c), end(f, l, c) {}
|
||||
|
||||
/// Initialization.
|
||||
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||
{
|
||||
begin.initialize(f, l, c);
|
||||
end = begin;
|
||||
}
|
||||
|
||||
/** \name Line and Column related manipulators
|
||||
** \{ */
|
||||
public:
|
||||
/// Reset initial location to final location.
|
||||
void step()
|
||||
{
|
||||
begin = end;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next columns.
|
||||
void columns(counter_type count = 1)
|
||||
{
|
||||
end += count;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next lines.
|
||||
void lines(counter_type count = 1)
|
||||
{
|
||||
end.lines(count);
|
||||
}
|
||||
/** \} */
|
||||
|
||||
public:
|
||||
auto print() const -> std::string
|
||||
{
|
||||
return *begin.filename + ":" + std::to_string(begin.line) + ":" + std::to_string(begin.column);
|
||||
}
|
||||
|
||||
auto label() const -> std::string
|
||||
{
|
||||
return utils::string::va("loc_%X", begin.line);
|
||||
}
|
||||
|
||||
public:
|
||||
/// Beginning of the located region.
|
||||
position begin;
|
||||
/// End of the located region.
|
||||
position end;
|
||||
};
|
||||
|
||||
/// Join two locations, in place.
|
||||
inline location& operator+=(location &res, const location &end)
|
||||
{
|
||||
res.end = end.end;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Join two locations.
|
||||
inline location operator+(location res, const location &end)
|
||||
{
|
||||
return res += end;
|
||||
}
|
||||
|
||||
/// Add \a width columns to the end position, in place.
|
||||
inline location& operator+=(location &res, location::counter_type width)
|
||||
{
|
||||
res.columns(width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add \a width columns to the end position.
|
||||
inline location operator+(location res, location::counter_type width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns to the end position, in place.
|
||||
inline location& operator-=(location &res, location::counter_type width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Subtract \a width columns to the end position.
|
||||
inline location operator-(location res, location::counter_type width)
|
||||
{
|
||||
return res -= width;
|
||||
}
|
||||
|
||||
/** \brief Intercept output stream redirection.
|
||||
** \param ostr the destination output stream
|
||||
** \param loc a reference to the location to redirect
|
||||
**
|
||||
** Avoid duplicate information.
|
||||
*/
|
||||
template <typename YYChar>
|
||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const location &loc)
|
||||
{
|
||||
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
||||
ostr << loc.begin;
|
||||
if (loc.end.filename && (!loc.begin.filename || *loc.begin.filename != *loc.end.filename))
|
||||
ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.line < loc.end.line)
|
||||
ostr << '-' << loc.end.line << '.' << end_col;
|
||||
else if (loc.begin.column < end_col)
|
||||
ostr << '-' << end_col;
|
||||
return ostr;
|
||||
}
|
||||
|
||||
} // namespace xsk::gsc
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,11 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdafx.hpp"
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,67 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::gsc
|
||||
{
|
||||
|
||||
using read_cb_type = std::function<std::vector<std::uint8_t>(const std::string&)>;
|
||||
|
||||
enum class build
|
||||
{
|
||||
dev,
|
||||
prod,
|
||||
};
|
||||
|
||||
enum class abort_t
|
||||
{
|
||||
abort_none = 0,
|
||||
abort_continue = 1,
|
||||
abort_break = 2,
|
||||
abort_return = 3,
|
||||
};
|
||||
|
||||
struct include_t
|
||||
{
|
||||
std::string name;
|
||||
std::vector<std::string> funcs;
|
||||
|
||||
include_t(const std::string& name, const std::vector<std::string>& funcs) : name(name), funcs(funcs) {}
|
||||
};
|
||||
|
||||
struct animtree_t
|
||||
{
|
||||
std::string name;
|
||||
bool loaded;
|
||||
};
|
||||
|
||||
struct instruction
|
||||
{
|
||||
using ptr = std::unique_ptr<instruction>;
|
||||
|
||||
std::uint32_t index;
|
||||
std::uint32_t size;
|
||||
std::uint8_t opcode;
|
||||
std::vector<std::string> data;
|
||||
|
||||
instruction() : index(0), size(0), opcode(0xFF) {}
|
||||
};
|
||||
|
||||
struct function
|
||||
{
|
||||
using ptr = std::unique_ptr<function>;
|
||||
|
||||
std::uint32_t index;
|
||||
std::uint32_t size;
|
||||
std::uint32_t id;
|
||||
std::string name;
|
||||
std::vector<instruction::ptr> instructions;
|
||||
std::unordered_map<std::uint32_t, std::string> labels;
|
||||
|
||||
function() : index(0), size(0), id(0) {}
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc
|
@ -1,36 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/string.hpp"
|
||||
#include "utils/byte_buffer.hpp"
|
||||
#include "utils/compression.hpp"
|
||||
|
||||
#include "gsc/location.hpp"
|
||||
#include "gsc/types.hpp"
|
||||
#include "gsc/asset.hpp"
|
||||
#include "gsc/block.hpp"
|
||||
#include "gsc/nodetree.hpp"
|
||||
|
||||
#include "gsc/interfaces/exception.hpp"
|
||||
#include "gsc/interfaces/assembler.hpp"
|
||||
#include "gsc/interfaces/disassembler.hpp"
|
||||
#include "gsc/interfaces/compiler.hpp"
|
||||
#include "gsc/interfaces/decompiler.hpp"
|
||||
#include "gsc/interfaces/context.hpp"
|
||||
|
||||
#include "arc/location.hpp"
|
||||
#include "arc/types.hpp"
|
||||
#include "arc/block.hpp"
|
||||
#include "arc/nodetree.hpp"
|
||||
|
||||
#include "arc/interfaces/exception.hpp"
|
||||
#include "arc/interfaces/assembler.hpp"
|
||||
#include "arc/interfaces/disassembler.hpp"
|
||||
#include "arc/interfaces/compiler.hpp"
|
||||
#include "arc/interfaces/decompiler.hpp"
|
||||
#include "arc/interfaces/context.hpp"
|
@ -1,123 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdafx.hpp"
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
byte_buffer::byte_buffer()
|
||||
{
|
||||
data_.resize(0x100000);
|
||||
std::fill(data_.begin(), data_.end(), '\0');
|
||||
size_ = static_cast<std::uint32_t>(data_.size());
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
byte_buffer::byte_buffer(std::uint32_t size)
|
||||
{
|
||||
data_.resize(size);
|
||||
std::fill(data_.begin(), data_.end(), '\0');
|
||||
size_ = size;
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
byte_buffer::byte_buffer(const std::vector<std::uint8_t>& data)
|
||||
{
|
||||
data_ = data;
|
||||
size_ = static_cast<std::uint32_t>(data_.size());
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
byte_buffer::~byte_buffer()
|
||||
{
|
||||
data_.clear();
|
||||
size_ = 0;
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
void byte_buffer::clear()
|
||||
{
|
||||
std::fill(data_.begin(), data_.end(), '\0');
|
||||
}
|
||||
|
||||
auto byte_buffer::is_avail() -> bool
|
||||
{
|
||||
return (pos_ < size_) ? true : false;
|
||||
}
|
||||
|
||||
void byte_buffer::seek(std::uint32_t count)
|
||||
{
|
||||
pos_ += count;
|
||||
}
|
||||
|
||||
void byte_buffer::seek_neg(std::uint32_t count)
|
||||
{
|
||||
pos_ -= count;
|
||||
}
|
||||
|
||||
void byte_buffer::write_string(const std::string& data)
|
||||
{
|
||||
if (pos_ + data.size() > size_) return;
|
||||
|
||||
std::memcpy(reinterpret_cast<void*>(data_.data() + pos_), data.data(), data.size());
|
||||
pos_ += static_cast<std::uint32_t>(data.size());
|
||||
}
|
||||
|
||||
void byte_buffer::write_c_string(const std::string& data)
|
||||
{
|
||||
if (pos_ + data.size() >= size_) return;
|
||||
|
||||
std::memcpy(reinterpret_cast<void*>(data_.data() + pos_), data.data(), data.size());
|
||||
pos_ += static_cast<std::uint32_t>(data.size() + 1);
|
||||
}
|
||||
|
||||
auto byte_buffer::read_c_string() -> std::string
|
||||
{
|
||||
auto ret = std::string(reinterpret_cast<const char*>(data_.data() + pos_));
|
||||
pos_ += static_cast<std::uint32_t>(ret.size() + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto byte_buffer::print_bytes(std::uint32_t pos, std::uint32_t count) -> std::string
|
||||
{
|
||||
std::string data {};
|
||||
|
||||
for (auto i = pos; i < pos + count; i++)
|
||||
{
|
||||
data = utils::string::va("%s %02X", data.data(), (*reinterpret_cast<std::uint8_t*>(data_.data() + i)));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
auto byte_buffer::pos() -> std::uint32_t
|
||||
{
|
||||
return pos_;
|
||||
}
|
||||
|
||||
void byte_buffer::pos(std::uint32_t pos)
|
||||
{
|
||||
if (pos >= 0 && pos <= size_)
|
||||
{
|
||||
pos_ = pos;
|
||||
}
|
||||
}
|
||||
|
||||
auto byte_buffer::align(std::uint32_t size) -> std::uint32_t
|
||||
{
|
||||
auto pos = pos_;
|
||||
|
||||
pos_ = (pos_ + (size - 1)) & ~(size - 1);
|
||||
|
||||
return pos_ - pos;
|
||||
}
|
||||
|
||||
auto byte_buffer::buffer() -> std::vector<std::uint8_t>&
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
} // namespace xsk::utils
|
@ -1,93 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class byte_buffer
|
||||
{
|
||||
public:
|
||||
using ptr = std::unique_ptr<byte_buffer>;
|
||||
|
||||
private:
|
||||
std::vector<std::uint8_t> data_;
|
||||
std::uint32_t size_;
|
||||
std::uint32_t pos_;
|
||||
|
||||
public:
|
||||
byte_buffer();
|
||||
byte_buffer(std::uint32_t size);
|
||||
byte_buffer(const std::vector<std::uint8_t>& data);
|
||||
~byte_buffer();
|
||||
|
||||
template <typename T>
|
||||
auto read() -> T
|
||||
{
|
||||
if (pos_ + sizeof(T) > size_) return T{};
|
||||
|
||||
auto ret = *reinterpret_cast<T*>(data_.data() + pos_);
|
||||
pos_ += sizeof(T);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void write(T data)
|
||||
{
|
||||
if (pos_ + sizeof(T) > size_) return;
|
||||
|
||||
T* mem = reinterpret_cast<T*>(data_.data() + pos_);
|
||||
std::memcpy(mem, &data, sizeof(T));
|
||||
pos_ += sizeof(T);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto read_endian() -> T
|
||||
{
|
||||
if (pos_ + sizeof(T) > size_) return T{};
|
||||
|
||||
std::array<std::uint8_t, sizeof(T)> mem;
|
||||
|
||||
for (auto i = 0u; i < sizeof(T); i++)
|
||||
{
|
||||
mem[i] = reinterpret_cast<std::uint8_t*>(data_.data() + pos_)[sizeof(T) - 1 - i];
|
||||
}
|
||||
|
||||
pos_ += sizeof(T);
|
||||
|
||||
return *reinterpret_cast<T*>(mem.data());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void write_endian(T data)
|
||||
{
|
||||
if (pos_ + sizeof(T) > size_) return;
|
||||
|
||||
auto* mem = data_.data() + pos_;
|
||||
|
||||
for (auto i = 0u; i < sizeof(T); i++)
|
||||
{
|
||||
mem[i] = reinterpret_cast<std::uint8_t*>(&data)[sizeof(T) - 1 - i];
|
||||
}
|
||||
|
||||
pos_ += sizeof(T);
|
||||
}
|
||||
|
||||
void clear();
|
||||
auto is_avail() -> bool;
|
||||
void seek(std::uint32_t count);
|
||||
void seek_neg(std::uint32_t count);
|
||||
void write_string(const std::string& data);
|
||||
void write_c_string(const std::string& data);
|
||||
auto read_c_string() -> std::string;
|
||||
auto print_bytes(std::uint32_t pos, std::uint32_t count) -> std::string;
|
||||
auto pos() -> std::uint32_t;
|
||||
void pos(std::uint32_t pos);
|
||||
auto align(std::uint32_t size) -> std::uint32_t;
|
||||
auto buffer() -> std::vector<std::uint8_t>&;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
@ -1,40 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdafx.hpp"
|
||||
#include "zlib.h"
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
auto zlib::compress(const std::vector<std::uint8_t>& data) -> std::vector<std::uint8_t>
|
||||
{
|
||||
auto length = compressBound(static_cast<uLong>(data.size()));
|
||||
|
||||
std::vector<std::uint8_t> output;
|
||||
output.resize(length);
|
||||
|
||||
auto result = compress2(reinterpret_cast<Bytef*>(output.data()), &length, reinterpret_cast<const Bytef*>(data.data()), static_cast<uLong>(data.size()), Z_BEST_COMPRESSION);
|
||||
|
||||
if (result != Z_OK) return {};
|
||||
|
||||
output.resize(length);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
auto zlib::decompress(const std::vector<std::uint8_t>& data, std::uint32_t length) -> std::vector<std::uint8_t>
|
||||
{
|
||||
std::vector<std::uint8_t> output;
|
||||
output.resize(length);
|
||||
|
||||
auto result = uncompress(reinterpret_cast<Bytef*>(output.data()), reinterpret_cast<uLong*>(&length), reinterpret_cast<const Bytef*>(data.data()), static_cast<uLong>(data.size()));
|
||||
|
||||
if (result != Z_OK) return {};
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace xsk::uitls
|
@ -1,18 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class zlib
|
||||
{
|
||||
public:
|
||||
static auto compress(const std::vector<std::uint8_t>& data) -> std::vector<std::uint8_t>;
|
||||
static auto decompress(const std::vector<std::uint8_t>& data, std::uint32_t length) -> std::vector<std::uint8_t>;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
@ -1,73 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdafx.hpp"
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
auto file::read(const std::string& file) -> std::vector<std::uint8_t>
|
||||
{
|
||||
std::vector<std::uint8_t> data;
|
||||
|
||||
std::ifstream stream(file, std::ios::binary);
|
||||
|
||||
if (!stream.good() && !stream.is_open())
|
||||
{
|
||||
throw std::runtime_error("Couldn't open file " + file);
|
||||
}
|
||||
|
||||
stream.seekg(0, std::ios::end);
|
||||
std::streamsize size = stream.tellg();
|
||||
stream.seekg(0, std::ios::beg);
|
||||
|
||||
if (size > -1)
|
||||
{
|
||||
data.resize(static_cast<uint32_t>(size));
|
||||
stream.read(reinterpret_cast<char*>(data.data()), size);
|
||||
}
|
||||
|
||||
stream.close();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void file::save(const std::string& file, const std::vector<std::uint8_t>& data)
|
||||
{
|
||||
const auto pos = file.find_last_of("/\\");
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::filesystem::create_directories(file.substr(0, pos));
|
||||
}
|
||||
|
||||
std::ofstream stream(file, std::ios::binary | std::ofstream::out);
|
||||
|
||||
if (stream.is_open())
|
||||
{
|
||||
stream.write(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
auto file::length(const std::string& file) -> size_t
|
||||
{
|
||||
auto stream = std::ifstream(file, std::ios::binary);
|
||||
|
||||
if (stream.good())
|
||||
{
|
||||
stream.seekg(0, std::ios::end);
|
||||
return static_cast<size_t>(stream.tellg());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto file::exists(const std::string& file) -> bool
|
||||
{
|
||||
return std::filesystem::exists(file);
|
||||
}
|
||||
|
||||
} // namespace xsk::utils
|
@ -1,20 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class file
|
||||
{
|
||||
public:
|
||||
static auto read(const std::string& file) -> std::vector<std::uint8_t>;
|
||||
static void save(const std::string& file, const std::vector<std::uint8_t>& data);
|
||||
static auto length(const std::string& file) -> size_t;
|
||||
static auto exists(const std::string& file) -> bool;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
@ -1,43 +0,0 @@
|
||||
// Copyright 2022 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class string
|
||||
{
|
||||
public:
|
||||
template <typename ... Args>
|
||||
static auto va(const std::string& format, Args ... args) -> std::string
|
||||
{
|
||||
size_t size = snprintf(nullptr, 0, format.data(), args ...) + 1;
|
||||
std::vector<char> buf;
|
||||
buf.resize(size);
|
||||
snprintf(buf.data(), size, format.data(), args ...);
|
||||
return std::string(buf.data(), buf.data() + size - 1);
|
||||
}
|
||||
|
||||
static auto oct_to_dec(const char* str) -> std::string;
|
||||
static auto bin_to_dec(const char* str) -> std::string;
|
||||
static auto hex_to_dec(const char* str) -> std::string;
|
||||
static auto iequals(const std::string& a, const std::string& b) -> bool;
|
||||
static auto is_number(const std::string& s) -> bool;
|
||||
static auto is_hex_number(const std::string& s) -> bool;
|
||||
static auto to_lower(const std::string& input) -> std::string;
|
||||
static auto to_code(const std::string& input) -> std::string;
|
||||
static auto to_literal(const std::string& input) -> std::string;
|
||||
static auto fordslash(const std::string& s) -> std::string;
|
||||
static auto backslash(const std::string& s) -> std::string;
|
||||
static auto quote(const std::string& s, bool single = true) -> std::string;
|
||||
static auto unquote(const std::string& s) -> std::string;
|
||||
static auto split(std::string& str, char delimiter) -> std::vector<std::string>;
|
||||
static auto clean_buffer_lines(std::vector<std::uint8_t>& buffer) -> std::vector<std::string>;
|
||||
static auto parse_code(std::string& line) -> std::vector<std::string>;
|
||||
static auto float_string(float value) -> std::string;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
44
src/utils/zlib.cpp
Normal file
44
src/utils/zlib.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#include "stdinc.hpp"
|
||||
#include "zlib.hpp"
|
||||
#include "zlib.h"
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
auto zlib::compress(std::vector<u8> const& data) -> std::vector<u8>
|
||||
{
|
||||
auto length = compressBound(static_cast<uLong>(data.size()));
|
||||
|
||||
auto output = std::vector<u8>{};
|
||||
output.resize(length);
|
||||
|
||||
auto result = compress2(reinterpret_cast<Bytef*>(output.data()), &length, reinterpret_cast<const Bytef*>(data.data()), static_cast<uLong>(data.size()), Z_BEST_COMPRESSION);
|
||||
|
||||
if (result == Z_OK)
|
||||
{
|
||||
output.resize(length);
|
||||
return output;
|
||||
}
|
||||
|
||||
throw std::runtime_error(fmt::format("zlib compress error {}", result));
|
||||
}
|
||||
|
||||
auto zlib::decompress(std::vector<u8> const& data, u32 length) -> std::vector<u8>
|
||||
{
|
||||
auto output = std::vector<u8>{};
|
||||
output.resize(length);
|
||||
|
||||
auto result = uncompress(reinterpret_cast<Bytef*>(output.data()), reinterpret_cast<uLongf*>(&length), reinterpret_cast<const Bytef*>(data.data()), static_cast<uLong>(data.size()));
|
||||
|
||||
if (result == Z_OK)
|
||||
return output;
|
||||
|
||||
throw std::runtime_error(fmt::format("zlib decompress error {}", result));
|
||||
}
|
||||
|
||||
} // namespace xsk::uitls
|
18
src/utils/zlib.hpp
Normal file
18
src/utils/zlib.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2023 xensik. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a GNU GPLv3 license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xsk::utils
|
||||
{
|
||||
|
||||
class zlib
|
||||
{
|
||||
public:
|
||||
static auto compress(std::vector<u8> const& data) -> std::vector<u8>;
|
||||
static auto decompress(std::vector<u8> const& data, u32 length) -> std::vector<u8>;
|
||||
};
|
||||
|
||||
} // namespace xsk::utils
|
Reference in New Issue
Block a user