Skip to content

Commit

Permalink
fdt-v2: fixed property parsing, further progress
Browse files Browse the repository at this point in the history
Signed-off-by: Bartłomiej Burdukiewicz <[email protected]>
  • Loading branch information
dev-0x7C6 committed Jul 1, 2024
1 parent e6b8d38 commit 6c741a3
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 41 deletions.
10 changes: 7 additions & 3 deletions src/fdt/fdt-parser-v2.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#pragma once

#include <type_traits>
#include <variant>
#include <cstdint>
#include <string_view>
#include <variant>
#include <vector>
#include <cstdint>

using u32 = std::uint32_t;

Expand Down Expand Up @@ -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 <typename T>
Expand Down
94 changes: 56 additions & 38 deletions src/fdt/fdt-parser.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#include "fdt-parser.hpp"
#include "fdt/fdt-header.hpp"
#include "fdt-parser-v2.hpp"

#include <algorithm>
#include <cstring>
#include <iostream>
#include <ostream>
#include <string_view>
#include <variant>

#include <cstring>
#include <concepts>
#include <algorithm>
#include <endian-conversions.hpp>

fdt_parser::fdt_parser(const char *data, u64 size, iface_fdt_generator &generator, const QString &default_root_node, const std::vector<fdt_handle_special_property> &handle_special_properties)
Expand Down Expand Up @@ -84,10 +86,6 @@ void fdt_parser::parse(const fdt::header header, iface_fdt_generator &generator)
}
*/

#include "fdt-parser-v2.hpp"
#include <iostream>
#include <algorithm>

auto align(const std::size_t size) {
const auto q = size % sizeof(u32);
const auto w = size / sizeof(u32);
Expand All @@ -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<fdt::property>(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<fdt::property>(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 <fdt::tokenizer::Tokenizable... Ts>
auto foreach_token_type(std::variant<Ts...>, const u32 token_id, const char *data, int &skip, fdt::tokenizer::context &ctx) {
auto foreach_token_type(std::variant<Ts...>, 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;
Expand All @@ -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<const u32 *>(dt_struct);
const auto end = reinterpret_cast<const u32 *>(dt_struct) + header.size_dt_struct / sizeof(u32);
Expand All @@ -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<u32>(convert(*iter));
iter++;
std::cout << id << std::endl;
ctx.state.data = reinterpret_cast<const char *>(++iter);
ctx.state.skip = 0;

if (!foreach_token_type(token{}, id, ctx))
break;

// if (!ctx.tokens.empty() && std::holds_alternative<types::end>(ctx.tokens.back()))
// break;

auto skip = 0;
foreach_token_type(token{}, id, reinterpret_cast<const char *>(iter), skip, ctx);
iter += skip;
iter += ctx.state.skip;
}

const auto node_begin_count = std::ranges::count_if(ctx.tokens, [](auto &&v) {
Expand All @@ -195,21 +205,29 @@ void fdt_parser::parse(const fdt::header header, iface_fdt_generator &generator)
return std::holds_alternative<types::end>(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 &) {},
},
Expand Down

0 comments on commit 6c741a3

Please sign in to comment.