diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7f4c9b4..ee56bce 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,28 +2,12 @@ configure_file(config.h.in config.h) add_subdirectory("submodules/qhexview") +file(GLOB_RECURSE fdt-viewer-headers *.hpp) +file(GLOB_RECURSE fdt-viewer-sources *.cpp) + add_executable(fdt-viewer - dialogs.cpp - dialogs.hpp - endian-conversions.hpp - fdt/fdt-generator-qt.cpp - fdt/fdt-generator-qt.hpp - fdt/fdt-generator.hpp - fdt/fdt-header.hpp - fdt/fdt-parser.cpp - fdt/fdt-parser.hpp - fdt/fdt-property-types.hpp - fdt/fdt-view.cpp - fdt/fdt-view.hpp - main-window.cpp - main-window.hpp - main-window.ui - main.cpp - menu-manager.cpp - menu-manager.hpp - types.hpp - viewer-settings.cpp - viewer-settings.hpp + ${fdt-viewer-headers} + ${fdt-viewer-sources} ../resources.qrc ) diff --git a/src/fdt/fdt-parser-v2.hpp b/src/fdt/fdt-parser-v2.hpp new file mode 100644 index 0000000..1c0a221 --- /dev/null +++ b/src/fdt/fdt-parser-v2.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#include +#include + +using u32 = std::uint32_t; + +namespace fdt::tokenizer { + +namespace types { +struct node_begin { + std::string_view name; +}; +struct node_end {}; +struct property { + std::string_view name; + std::string_view data; +}; +struct nop {}; +struct end {}; + +constexpr auto id_of(node_begin) -> u32 { return 0x01; }; +constexpr auto id_of(node_end) -> u32 { return 0x02; }; +constexpr auto id_of(property) -> u32 { return 0x03; }; +constexpr auto id_of(nop) -> u32 { return 0x04; }; +constexpr auto id_of(end) -> u32 { return 0x09; }; + +} // namespace types + +using token = std::variant; +using token_list = std::vector; + +struct context { + std::string_view structs; + std::string_view strings; + token_list tokens; +}; + +template +concept Tokenizable = requires(T t) { + { fdt::tokenizer::types::id_of(t) } -> std::convertible_to; +}; + +} // namespace fdt::tokenizer diff --git a/src/fdt/fdt-parser.cpp b/src/fdt/fdt-parser.cpp index 1dcaf10..47cc315 100644 --- a/src/fdt/fdt-parser.cpp +++ b/src/fdt/fdt-parser.cpp @@ -1,6 +1,11 @@ #include "fdt-parser.hpp" +#include +#include +#include #include +#include +#include #include fdt_parser::fdt_parser(const char *data, u64 size, iface_fdt_generator &generator, const QString &default_root_node, const std::vector &handle_special_properties) @@ -24,6 +29,7 @@ fdt_parser::fdt_parser(const char *data, u64 size, iface_fdt_generator &generato } } +/* void fdt_parser::parse(const fdt::header header, iface_fdt_generator &generator) { const auto dt_struct = m_data + header.off_dt_struct; const auto dt_strings = m_data + header.off_dt_strings; @@ -75,3 +81,115 @@ void fdt_parser::parse(const fdt::header header, iface_fdt_generator &generator) break; } } +*/ + +#include "fdt-parser-v2.hpp" +#include +#include + +auto align(const std::size_t size) { + const auto q = size % sizeof(u32); + const auto w = size / sizeof(u32); + return std::max(1u, w + (q ? 1u : 0u)); +}; + +namespace fdt::parser { + +using namespace fdt::tokenizer; +using namespace fdt::tokenizer::types; + +auto parse(node_begin &&token, const char *data, int &skip, context &ctx) -> fdt::tokenizer::token { + const auto size = std::strlen(data); + token.name = std::string_view(data, size); + skip += align(size); + return {std::move(token)}; +} + +auto parse(node_end &&token, const char *data, int &skip, context &ctx) -> fdt::tokenizer::token { + return {std::move(token)}; +} + +auto parse(types::property &&token, const char *data, int &skip, context &ctx) -> fdt::tokenizer::token { + const auto header = read_data_32be(data); + skip += align(sizeof(header)) + align(header.len); + data += sizeof(header); + + token.name = std::string_view(); + token.data = std::string_view(data, header.len); + + return {std::move(token)}; +} + +auto parse(nop &&token, const char *data, int &skip, context &ctx) -> fdt::tokenizer::token { + return {std::move(token)}; +} + +auto parse(end &&token, const char *data, int &skip, context &ctx) -> fdt::tokenizer::token { + return {std::move(token)}; +} +} // namespace fdt::parser + +template +auto foreach_token_type(std::variant, const u32 token_id, const char *data, int &skip, fdt::tokenizer::context &ctx) { + auto conditional_parse = [&](auto &&token) { + if (fdt::tokenizer::types::id_of(token) == token_id) { + ctx.tokens.emplace_back(fdt::parser::parse(std::move(token), data, skip, ctx)); + return true; + } + return false; + }; + return (conditional_parse(Ts{}) || ...); +} + +void fdt_parser::parse(const fdt::header header, iface_fdt_generator &generator) { + const auto dt_struct = m_data + header.off_dt_struct; + const auto dt_strings = m_data + header.off_dt_strings; + + auto get_property_name = [&](auto offset) { + const auto ptr = dt_strings + offset; + return QString::fromUtf8(ptr, std::strlen(ptr)); + }; + + using namespace fdt::tokenizer; + using namespace fdt::tokenizer::types; + context ctx; + + auto begin = reinterpret_cast(dt_struct); + auto end = reinterpret_cast(dt_struct) + header.size_dt_struct / sizeof(u32); + + for (auto iter = begin; iter != end;) { + const auto id = static_cast(convert(*iter)); + iter++; + std::cout << id << std::endl; + + auto skip = 0; + foreach_token_type(token{}, id, reinterpret_cast(iter), skip, ctx); + iter += skip; + } + + const auto node_begin_count = std::ranges::count_if(ctx.tokens, [](auto &&v) { + return std::holds_alternative(v); + }); + + const auto node_end_count = std::ranges::count_if(ctx.tokens, [](auto &&v) { + return std::holds_alternative(v); + }); + + const auto property_count = std::ranges::count_if(ctx.tokens, [](auto &&v) { + return std::holds_alternative(v); + }); + + const auto nop_count = std::ranges::count_if(ctx.tokens, [](auto &&v) { + return std::holds_alternative(v); + }); + + const auto end_count = std::ranges::count_if(ctx.tokens, [](auto &&v) { + return std::holds_alternative(v); + }); + + std::cout << "node begin count: " << node_begin_count << std::endl; + std::cout << "node end count: " << node_end_count << std::endl; + std::cout << "property count: " << property_count << std::endl; + std::cout << "nop count: " << nop_count << std::endl; + std::cout << "end count: " << end_count << std::endl; +}