Move hashes collection to TorrentRead

So yeah, while TorrentRead is not compulsory to use,
right now it'd be pretty inconvenient to not use it
as the hash grouping function is fidgety to get right.
I think group_torrent_hashes() eventually should be
moved elsewhere.
This commit is contained in:
King_DuckZ 2025-04-07 01:19:56 +01:00
commit f7d90a789d
5 changed files with 41 additions and 39 deletions

View file

@ -15,7 +15,6 @@
* along with ducktorrent. If not, see <http://www.gnu.org/licenses/>.
*/
#include "parser.hpp"
#include "torrent_read.hpp"
#include <iostream>
@ -25,6 +24,7 @@
#include <cstdint>
#include <sha1/sha1.hpp>
#include <sha1/BufferSource.hpp>
#include <climits>
namespace {
SHA1::MessageDigest to_hash160_digest (const std::array<std::uint32_t, 5>& arr) {
@ -53,8 +53,7 @@ int main(int argc, const char* argv[]) {
torrent.print(std::cout);
const auto& values = torrent.parsed_values();
auto hashes = duck::collect_hashes(values);
auto hashes = duck::group_torrent_hashes(torrent);
std::cout << "Got " << hashes.size() << " hashes\n";
const auto file_count = torrent.read_file_count();

View file

@ -20,7 +20,6 @@
#endif
#include "parser.hpp"
#include "visitors/find_t_visitor.hpp"
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
@ -163,35 +162,4 @@ std::vector<TorrentValue> parse_torrent (std::string_view binary_data) {
return retval;
}
std::vector<std::array<std::uint32_t, 5>> collect_hashes (std::string_view hashes) {
typedef std::array<std::uint32_t, 5> array_type;
if (hashes.empty())
return {};
constexpr std::size_t hash_size = 20;
constexpr std::size_t uint_count = std::tuple_size<array_type>();
static_assert(sizeof(array_type::value_type) * uint_count == hash_size);
if (hashes.size() % hash_size != 0)
throw std::runtime_error("Bad pieces array size " + std::to_string(hashes.size()));
std::vector<array_type> retval(hashes.size() / hash_size);
const char* src = hashes.data();
for (std::size_t z = 0; z < retval.size(); ++z, src+=hash_size) {
//std::copy_n(src, hash_size, reinterpret_cast<char*>(retval[z].data()));
for (std::size_t n = 0; n < uint_count; ++n) {
char* const out_uint = reinterpret_cast<char*>(retval[z].data() + n);
for (std::size_t u = 0; u < sizeof(std::uint32_t); ++u) {
out_uint[u] = src[n * sizeof(std::uint32_t) + sizeof(std::uint32_t) - u - 1];
}
}
}
return retval;
}
std::vector<std::array<std::uint32_t, 5>> collect_hashes (const std::vector<TorrentValue>& values) {
return collect_hashes(find_string("/info/pieces", values));
}
} //namespace duck

View file

@ -21,8 +21,6 @@
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <map>
#include <vector>
#include <array>
#include <cstdint>
#include <stdexcept>
namespace duck {
@ -46,6 +44,4 @@ struct TorrentValue : public boost::spirit::x3::variant<
};
std::vector<TorrentValue> parse_torrent (std::string_view binary_data);
std::vector<std::array<std::uint32_t, 5>> collect_hashes (std::string_view hashes);
std::vector<std::array<std::uint32_t, 5>> collect_hashes (const std::vector<TorrentValue>& values);
} //namespace duck

View file

@ -212,6 +212,10 @@ std::string_view TorrentRead::read_comment() const {
return find_string("/comment", m_parsed_values);
}
std::string_view TorrentRead::read_hashes() const {
return find_string("/info/pieces", m_parsed_values);
}
std::string_view TorrentRead::read_created_by() const {
return find_string("/created by", m_parsed_values);
}
@ -243,4 +247,34 @@ const TorrentValue& TorrentRead::cached_info_files() const {
return *m_cached_info_files;
}
std::vector<std::array<std::uint32_t, 5>> group_torrent_hashes (std::string_view hashes) {
typedef std::array<std::uint32_t, 5> array_type;
if (hashes.empty())
return {};
constexpr std::size_t hash_size = 20;
constexpr std::size_t uint_count = std::tuple_size<array_type>();
static_assert(sizeof(array_type::value_type) * uint_count == hash_size);
if (hashes.size() % hash_size != 0)
throw std::runtime_error("Bad pieces array size " + std::to_string(hashes.size()));
std::vector<array_type> retval(hashes.size() / hash_size);
const char* src = hashes.data();
for (std::size_t z = 0; z < retval.size(); ++z, src+=hash_size) {
//std::copy_n(src, hash_size, reinterpret_cast<char*>(retval[z].data()));
for (std::size_t n = 0; n < uint_count; ++n) {
char* const out_uint = reinterpret_cast<char*>(retval[z].data() + n);
for (std::size_t u = 0; u < sizeof(std::uint32_t); ++u) {
out_uint[u] = src[n * sizeof(std::uint32_t) + sizeof(std::uint32_t) - u - 1];
}
}
}
return retval;
}
std::vector<std::array<std::uint32_t, 5>> group_torrent_hashes (const TorrentRead& torrent) {
return group_torrent_hashes(torrent.read_hashes());
}
} //namespace duck

View file

@ -29,6 +29,7 @@
#include <ostream>
#include <cstddef>
#include <cstdint>
#include <array>
namespace duck {
struct TorrentValue;
@ -51,6 +52,7 @@ public:
std::size_t read_file_size(std::size_t index) const;
bool read_is_private() const;
std::string_view read_comment() const;
std::string_view read_hashes() const;
std::string_view read_created_by() const;
std::string_view read_announce() const;
std::time_t read_creation_date() const;
@ -65,4 +67,7 @@ private:
mutable const TorrentValue* m_cached_info_files;
};
std::vector<std::array<std::uint32_t, 5>> group_torrent_hashes (std::string_view hashes);
std::vector<std::array<std::uint32_t, 5>> group_torrent_hashes (const TorrentRead& torrent);
} //namespace duck