From fc0086b90f9cfed43c8f750130b7495ed07dc450 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 2 Apr 2025 21:14:56 +0100 Subject: [PATCH] More generic implementation for searching nodes --- src/main.cpp | 44 +++++++++++++++++++++--------- src/meson.build | 1 + src/split.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ src/split.hpp | 28 +++++++++++++++++++ 4 files changed, 133 insertions(+), 12 deletions(-) create mode 100644 src/split.cpp create mode 100644 src/split.hpp diff --git a/src/main.cpp b/src/main.cpp index 355b957..e633060 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,6 @@ #include "parser.hpp" +#include "split.hpp" + #include #include #include @@ -13,8 +15,6 @@ #include namespace { -constexpr char g_test[] = "d8:announce75:http://tracker.bakabt.me:2710/f53895da71a9546b3b14682e63cb9069/announce.php7:comment21:http://www.bakabt.me/10:created by37:ruTorrent (PHP Class - Adrien Gibrat)13:creation datei1394860194ee"; - std::string load_file (const std::string& path) { std::ifstream ifs(path); ifs >> std::noskipws; @@ -107,13 +107,35 @@ struct PrintVisitor { bool skip_first; }; -struct FindHashesVisitor : boost::static_visitor { +struct FindStringVisitor : boost::static_visitor { + FindStringVisitor (std::string path) { + auto split = dincore::split(path, '/', true, true); + search.reserve(split.size()); + for (const auto& itm : split) { + search.emplace_back(itm.data(), itm.size()); + } + } + + bool is_prefix_path (std::string_view curr_element) const { + if (path.size() + 1 > search.size()) + return false; + + return std::equal(path.cbegin(), path.cend(), search.cbegin()) and (search[path.size()] == curr_element); + } + + bool is_path_found() const { + if (path.size() != search.size()) + return false; + + return std::equal(path.cbegin(), path.cend(), search.cbegin()); + } + std::string_view operator() (long long value) { return {}; } std::string_view operator() (const duck::TorrentStringType& value) { - if (this_is_pieces) + if (is_path_found()) return value; else return {}; @@ -124,22 +146,20 @@ struct FindHashesVisitor : boost::static_visitor { } std::string_view operator() (const std::map& value) { - if (this_is_pieces) + if (is_path_found()) return {}; for (const auto& item : value) { - if (item.first == "info") { - return boost::apply_visitor(*this, item.second); - } - else if (item.first == "pieces") { - this_is_pieces = true; + if (is_prefix_path(item.first)) { + path.push_back(item.first); return boost::apply_visitor(*this, item.second); } } return {}; } - bool this_is_pieces{false}; + std::vector path; + std::vector search; }; std::vector> collect_hashes (std::string_view hashes) { @@ -189,7 +209,7 @@ int main(int argc, const char* argv[]) { } if (values.size() == 1) { - FindHashesVisitor visitor; + FindStringVisitor visitor("/info/pieces"); auto source_hashes = boost::apply_visitor(visitor, values.front()); std::cout << "Got source_hashes with size " << source_hashes.size() << '\n'; auto hashes = collect_hashes(source_hashes); diff --git a/src/meson.build b/src/meson.build index e611be6..65789b9 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,7 @@ executable(meson.project_name(), 'main.cpp', 'parser.cpp', + 'split.cpp', dependencies: [ boost_dep, libstriezel_dep, diff --git a/src/split.cpp b/src/split.cpp new file mode 100644 index 0000000..512284f --- /dev/null +++ b/src/split.cpp @@ -0,0 +1,72 @@ +/* Copyright 2015, 2016, Michele Santullo + * This file is part of "dindexer". + * + * "dindexer" is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * "dindexer" is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with "dindexer". If not, see . + */ + +#include "split.hpp" +#include +#include +#include +#include +#include +#include + +namespace dincore { + std::vector split (std::string_view parList, char parSeparator, bool parTrim, bool parDeleteEmpty) { + using OutRange = boost::iterator_range; + using boost::token_finder; + using boost::adaptors::transformed; + using boost::adaptors::filtered; + using std::string_view; + using boost::iter_split; + using boost::trim_copy; + + std::vector out_range; + + //See: + //https://stackoverflow.com/questions/27999941/how-to-use-boostsplit-with-booststring-ref-in-boost-1-55 + //http://www.boost.org/doc/libs/1_60_0/doc/html/boost/algorithm/iter_split.html + //http://www.boost.org/doc/libs/1_60_0/doc/html/boost/algorithm/token_finder.html + //https://stackoverflow.com/questions/20781090/difference-between-boostsplit-vs-boostiter-split + if (parTrim and parDeleteEmpty) { + return boost::copy_range>( + iter_split(out_range, parList, token_finder([parSeparator](char c){return parSeparator==c;})) | + transformed([](const OutRange& r){return trim_copy(r);}) | + transformed([](const OutRange& r){return string_view(&*r.begin(), r.size());}) | + filtered([](string_view r){return not r.empty();}) + ); + } + else if (parTrim) { + return boost::copy_range>( + iter_split(out_range, parList, token_finder([parSeparator](char c){return parSeparator==c;})) | + transformed([](const OutRange& r){return trim_copy(r);}) | + transformed([](const OutRange& r){return string_view(&*r.begin(), r.size());}) + ); + } + else if (parDeleteEmpty) { + return boost::copy_range>( + iter_split(out_range, parList, token_finder([parSeparator](char c){return parSeparator==c;})) | + transformed([](const OutRange& r){return string_view(&*r.begin(), r.size());}) | + filtered([](string_view r){return not r.empty();}) + ); + } + else { + return boost::copy_range>( + iter_split(out_range, parList, token_finder([parSeparator](char c){return parSeparator==c;})) | + transformed([](const OutRange& r){return string_view(&*r.begin(), r.size());}) + ); + } + } +} //namespace dincore diff --git a/src/split.hpp b/src/split.hpp new file mode 100644 index 0000000..1ddcb84 --- /dev/null +++ b/src/split.hpp @@ -0,0 +1,28 @@ +/* Copyright 2015, 2016, Michele Santullo + * This file is part of "dindexer". + * + * "dindexer" is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * "dindexer" is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with "dindexer". If not, see . + */ + +#ifndef id913CE9D2F60745349F39F2C82455973E +#define id913CE9D2F60745349F39F2C82455973E + +#include +#include + +namespace dincore { + std::vector split ( std::string_view parList, char parSeparator, bool parTrim, bool parDeleteEmpty ); +} //namespace dincore + +#endif