/* */ #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 std::string C_NAME("name"); const std::string C_NAME_UTF8("name.utf-8"); const std::string C_FILES("files"); const std::string C_LENGTH("length"); const std::string C_PATH("path"); const std::string C_PATH_UTF8("path.utf-8"); const std::string C_INFO("info"); const std::string C_PIECES("pieces"); const std::string C_PIECE_LENGTH("piece length"); const std::string C_PRIVATE("private"); const std::string C_URL_LIST("url-list"); const std::string C_ANNOUNCE("announce"); const std::string C_ANNOUNCE_LIST("announce-list"); const std::string C_NODES("nodes"); const std::string C_CREATION_DATE("creation date"); const std::string C_COMMENT("comment"); const std::string C_COMMENT_UTF8("comment.utf-8"); const std::string C_CREATED_BY("created by"); const std::string DEFAULT_PEER_ID_PREFIX("aria2-"); } // namespace const std::string MULTI("multi"); const std::string SINGLE("single"); namespace { void extractPieceHash(const SharedHandle& 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 (const SharedHandle& torrent, std::vector& uris, const ValueBase* v) { class UrlListVisitor:public ValueBaseVisitor { private: std::vector& uris_; const SharedHandle& torrent_; public: UrlListVisitor (std::vector& uris, const SharedHandle& torrent): uris_(uris), torrent_(torrent) {} virtual void visit(const String& v) { std::string utf8Uri = util::encodeNonUtf8(v.s()); uris_.push_back(utf8Uri); torrent_->urlList.push_back(utf8Uri); } virtual void visit(const Integer& v) {} virtual void visit(const Bool& v) {} virtual void visit(const Null& v) {} virtual void visit(const List& v) { for(List::ValueType::const_iterator itr = v.begin(), eoi = v.end(); itr != eoi; ++itr) { const String* uri = downcast(*itr); if(uri) { std::string utf8Uri = util::encodeNonUtf8(uri->s()); uris_.push_back(utf8Uri); torrent_->urlList.push_back(utf8Uri); } } } virtual void visit(const Dict& v) {} }; 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 SharedHandle& ctx, const SharedHandle& torrent, const Dict* infoDict, const SharedHandle