diff --git a/src/fdt/fdt-parser-v2.hpp b/src/fdt/fdt-parser-v2.hpp index ea4d60e..8c03e4b 100644 --- a/src/fdt/fdt-parser-v2.hpp +++ b/src/fdt/fdt-parser-v2.hpp @@ -1,10 +1,9 @@ #pragma once -#include -#include +#include #include +#include #include -#include using u32 = std::uint32_t; @@ -37,6 +36,11 @@ struct context { std::string_view structs; std::string_view strings; token_list tokens; + + struct { + const char *data{nullptr}; + int skip{}; + } state; }; template diff --git a/src/fdt/fdt-parser.cpp b/src/fdt/fdt-parser.cpp index b14fede..9b92689 100644 --- a/src/fdt/fdt-parser.cpp +++ b/src/fdt/fdt-parser.cpp @@ -1,12 +1,14 @@ #include "fdt-parser.hpp" #include "fdt/fdt-header.hpp" +#include "fdt-parser-v2.hpp" + +#include +#include +#include #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) @@ -84,10 +86,6 @@ void fdt_parser::parse(const fdt::header header, iface_fdt_generator &generator) } */ -#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); @@ -99,42 +97,46 @@ 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); +auto parse(node_begin &&token, context &ctx) -> fdt::tokenizer::token { + const auto size = std::strlen(ctx.state.data); + token.name = std::string_view(ctx.state.data, size); + ctx.state.skip += align(size + 1); return {std::move(token)}; } -auto parse(node_end &&token, const char *data, int &skip, context &ctx) -> fdt::tokenizer::token { +auto parse(node_end &&token, 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); +auto parse(types::property &&token, context &ctx) -> fdt::tokenizer::token { + const auto header = read_data_32be(ctx.state.data); + ctx.state.skip += align(sizeof(header)) + align(header.len); + ctx.state.data += sizeof(header); - token.name = std::string_view(); - token.data = std::string_view(data, header.len); + const auto property = ctx.strings.data() + header.nameoff; + + token = { + .name = std::string_view(property, std::strlen(property)), + .data = std::string_view(ctx.state.data, header.len), + }; return {std::move(token)}; } -auto parse(nop &&token, const char *data, int &skip, context &ctx) -> fdt::tokenizer::token { +auto parse(nop &&token, context &ctx) -> fdt::tokenizer::token { return {std::move(token)}; } -auto parse(end &&token, const char *data, int &skip, context &ctx) -> fdt::tokenizer::token { +auto parse(end &&token, 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 foreach_token_type(std::variant, const u32 token_id, 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)); + ctx.tokens.emplace_back(fdt::parser::parse(std::move(token), ctx)); return true; } return false; @@ -158,7 +160,11 @@ void fdt_parser::parse(const fdt::header header, iface_fdt_generator &generator) using namespace fdt::tokenizer; using namespace fdt::tokenizer::types; - context ctx; + + context ctx{ + .structs = {dt_struct, header.size_dt_struct}, // + .strings = {dt_strings, header.size_dt_strings}, // + }; const auto begin = reinterpret_cast(dt_struct); const auto end = reinterpret_cast(dt_struct) + header.size_dt_struct / sizeof(u32); @@ -167,12 +173,16 @@ void fdt_parser::parse(const fdt::header header, iface_fdt_generator &generator) for (auto iter = begin; iter != end;) { const auto id = static_cast(convert(*iter)); - iter++; - std::cout << id << std::endl; + ctx.state.data = reinterpret_cast(++iter); + ctx.state.skip = 0; + + if (!foreach_token_type(token{}, id, ctx)) + break; + + // if (!ctx.tokens.empty() && std::holds_alternative(ctx.tokens.back())) + // break; - auto skip = 0; - foreach_token_type(token{}, id, reinterpret_cast(iter), skip, ctx); - iter += skip; + iter += ctx.state.skip; } const auto node_begin_count = std::ranges::count_if(ctx.tokens, [](auto &&v) { @@ -195,21 +205,29 @@ void fdt_parser::parse(const fdt::header header, iface_fdt_generator &generator) return std::holds_alternative(v); }); - std::cout << "is_aligned : " << is_aligned << std::endl; - 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; + std::cout << "is_aligned : " << is_aligned << std::endl; + std::cout << "node begin : " << node_begin_count << std::endl; + std::cout << "node end : " << node_end_count << std::endl; + std::cout << "property : " << property_count << std::endl; + std::cout << "nop : " << nop_count << std::endl; + std::cout << "end : " << end_count << std::endl; for (auto &&token : ctx.tokens) std::visit(overloaded{ [&](node_begin &arg) { generator.begin_node(QString::fromUtf8(arg.name.data(), arg.name.size())); }, [&](node_end &arg) { generator.end_node(); }, - [&](property &arg) { generator.insert_property(fdt_property{ - .name = QString::fromUtf8(arg.name.data(), arg.name.size()), - .data = QByteArray(arg.data.data(), arg.data.size()), - }); }, + [&](property &arg) { + auto property = fdt_property{ + .name = QString::fromUtf8(arg.name.data(), arg.name.size()), + .data = QByteArray(arg.data.data(), arg.data.size()), + }; + + generator.insert_property(property); + + // for (auto &&handle : m_handle_special_properties) + // if (handle.name.toStdString() == arg.name) + // handle.callback(property, generator); + }, [&](nop &) {}, [&](types::end &) {}, },