diff --git a/src/create_torrent.cpp b/src/create_torrent.cpp index 71f69e7fb..ba705ffcb 100644 --- a/src/create_torrent.cpp +++ b/src/create_torrent.cpp @@ -333,15 +333,25 @@ namespace { // target_piece_size = total_size / (target_list_size / hash_size); // Given hash_size = 20 bytes, target_piece_size = (16*1024 * pow(2, i)) // we can determine size_table = (total_size = pow(2 * target_piece_size / hash_size, 2)) - std::int64_t const size_table[] = {2684355, 10737418, 42949673, 171798692, 687194767, - 2748779069LL, 10995116278LL, 43980465111LL, 175921860444LL, 703687441777LL}; + std::array const size_table{{ + 2684355LL // -> 16kiB + , 10737418LL // -> 32 kiB + , 42949673LL // -> 64 kiB + , 171798692LL // -> 128 kiB + , 687194767LL // -> 256 kiB + , 2748779069LL // -> 512 kiB + , 10995116278LL // -> 1 MiB + , 43980465111LL // -> 2 MiB + , 175921860444LL // -> 4 MiB + , 703687441777LL}}; // -> 8 MiB int i = 0; - for (int max = sizeof(size_table) / sizeof(size_table[0]); i < max; ++i) + for (auto const s : size_table) { - if (size_table[i] >= fs.total_size()) break; + if (s >= fs.total_size()) break; + ++i; } - piece_size = 0x4000 << i; + piece_size = default_block_size << i; } else if (piece_size == 0 && m_merkle_torrent) { diff --git a/test/test_create_torrent.cpp b/test/test_create_torrent.cpp index 534c52097..d13464a76 100644 --- a/test/test_create_torrent.cpp +++ b/test/test_create_torrent.cpp @@ -70,3 +70,31 @@ TORRENT_TEST(create_verbatim_torrent) TEST_CHECK(memcmp(dest_info, test_torrent + 1, sizeof(test_torrent)-3) == 0); } +TORRENT_TEST(piece_size) +{ + std::int64_t const kiB = 1024; + std::int64_t const MiB = 1024 * 1024; + std::int64_t const GiB = 1024 * 1024 * 1024; + std::array, 11> samples{{ + {100LL, 16 * kiB}, + {3 * MiB, 32 * kiB}, + {11 * MiB, 64 * kiB}, + {43 * MiB, 128 * kiB}, + {172 * MiB, 256 * kiB}, + {688 * MiB, 512 * kiB}, + {3 * GiB, 1 * MiB}, + {11 * GiB, 2 * MiB}, + {44 * GiB, 4 * MiB}, + {176 * GiB, 8 * MiB}, + {704 * GiB, 16 * MiB}, + }}; + + for (auto const& t : samples) + { + lt::file_storage fs; + fs.add_file("a", t.first); + lt::create_torrent ct(fs, 0); + TEST_CHECK(ct.piece_length() == static_cast(t.second)); + } +} +