/* */ #include "bittorrent_helper.h" #include #include #include #include "DownloadContext.h" #include "Randomizer.h" #include "util.h" #include "DlAbortEx.h" #include "message.h" #include "fmt.h" #include "BtConstants.h" #include "MessageDigest.h" #include "message_digest_helper.h" #include "a2netcompat.h" #include "BtConstants.h" #include "bitfield.h" #include "base32.h" #include "magnet.h" #include "bencode2.h" #include "TorrentAttribute.h" #include "SocketCore.h" #include "Option.h" #include "prefs.h" #include "FileEntry.h" #include "error_code.h" #include "array_fun.h" #include "DownloadFailureException.h" #include "ValueBaseBencodeParser.h" namespace aria2 { namespace bittorrent { namespace { const char C_NAME[] = "name"; const char C_NAME_UTF8[] = "name.utf-8"; const char C_FILES[] = "files"; const char C_LENGTH[] = "length"; const char C_PATH[] = "path"; const char C_PATH_UTF8[] = "path.utf-8"; const char C_INFO[] = "info"; const char C_PIECES[] = "pieces"; const char C_PIECE_LENGTH[] = "piece length"; const char C_PRIVATE[] = "private"; const char C_URL_LIST[] = "url-list"; const char C_ANNOUNCE[] = "announce"; const char C_ANNOUNCE_LIST[] = "announce-list"; const char C_NODES[] = "nodes"; const char C_CREATION_DATE[] = "creation date"; const char C_COMMENT[] = "comment"; const char C_COMMENT_UTF8[] = "comment.utf-8"; const char C_CREATED_BY[] = "created by"; const char DEFAULT_PEER_ID_PREFIX[] = "aria2-"; } // namespace const std::string MULTI("multi"); const std::string SINGLE("single"); namespace { void extractPieceHash(const std::shared_ptr& ctx, const std::string& hashData, size_t hashLength, size_t numPieces) { std::vector pieceHashes; pieceHashes.reserve(numPieces); for (size_t i = 0; i < numPieces; ++i) { const char* p = hashData.data() + i * hashLength; pieceHashes.push_back(std::string(p, p + hashLength)); } ctx->setPieceHashes("sha-1", pieceHashes.begin(), pieceHashes.end()); } } // namespace namespace { void extractUrlList(TorrentAttribute* torrent, std::vector& uris, const ValueBase* v) { class UrlListVisitor : public ValueBaseVisitor { private: std::vector& uris_; TorrentAttribute* torrent_; public: UrlListVisitor(std::vector& uris, TorrentAttribute* torrent) : uris_(uris), torrent_(torrent) { } virtual void visit(const String& v) CXX11_OVERRIDE { std::string utf8Uri = util::encodeNonUtf8(v.s()); uris_.push_back(utf8Uri); torrent_->urlList.push_back(utf8Uri); } virtual void visit(const Integer& v) CXX11_OVERRIDE {} virtual void visit(const Bool& v) CXX11_OVERRIDE {} virtual void visit(const Null& v) CXX11_OVERRIDE {} virtual void visit(const List& v) CXX11_OVERRIDE { for (auto& elem : v) { const String* uri = downcast(elem); if (uri) { std::string utf8Uri = util::encodeNonUtf8(uri->s()); uris_.push_back(utf8Uri); torrent_->urlList.push_back(utf8Uri); } } } virtual void visit(const Dict& v) CXX11_OVERRIDE {} }; if (v) { UrlListVisitor visitor(uris, torrent); v->accept(visitor); } } } // namespace namespace { template OutputIterator createUri(InputIterator first, InputIterator last, OutputIterator out, const std::string& filePath) { for (; first != last; ++first) { if (!(*first).empty() && (*first)[(*first).size() - 1] == '/') { *out++ = (*first) + filePath; } else { *out++ = (*first) + "/" + filePath; } } return out; } } // namespace namespace { void extractFileEntries(const std::shared_ptr& ctx, TorrentAttribute* torrent, const Dict* infoDict, const std::shared_ptr