/* */ #include "MetalinkRequestInfo.h" #include "Xml2MetalinkProcessor.h" #include "prefs.h" #include "DlAbortEx.h" #include "MultiUrlRequestInfo.h" class AccumulateNonP2PUrl { private: Strings* urlsPtr; int split; public: AccumulateNonP2PUrl(Strings* urlsPtr, int split) :urlsPtr(urlsPtr), split(split) {} void operator()(const MetalinkResourceHandle& resource) { switch(resource->type) { case MetalinkResource::TYPE_HTTP: case MetalinkResource::TYPE_HTTPS: case MetalinkResource::TYPE_FTP: for(int s = 1; s <= split; s++) { urlsPtr->push_back(resource->url); } break; } } }; class FindBitTorrentUrl { public: FindBitTorrentUrl() {} bool operator()(const MetalinkResourceHandle& resource) { if(resource->type == MetalinkResource::TYPE_BITTORRENT) { return true; } else { return false; } } }; RequestInfos MetalinkRequestInfo::execute() { Xml2MetalinkProcessor proc; RequestInfos nextReqInfos; try { MetalinkerHandle metalinker = proc.parseFile(metalinkFile); MetalinkEntries entries = metalinker->queryEntry(op->get(PREF_METALINK_VERSION), op->get(PREF_METALINK_LANGUAGE), op->get(PREF_METALINK_OS)); if(entries.size() == 0) { printf("No file matched with your preference.\n"); throw new DlAbortEx("No file matched with your preference."); } RequestGroups groups; for(MetalinkEntries::iterator itr = entries.begin(); itr != entries.end(); itr++) { MetalinkEntryHandle& entry = *itr; if(op->defined(PREF_METALINK_LOCATION)) { entry->setLocationPreference(op->get(PREF_METALINK_LOCATION), 100); } entry->dropUnsupportedResource(); if(entry->resources.size() == 0) { continue; } logger->info("Metalink: Queueing %s for download.", entry->filename.c_str()); MetalinkResources::iterator itr = find_if(entry->resources.begin(), entry->resources.end(), FindBitTorrentUrl()); Strings urls; ChecksumHandle checksum = 0; if(itr == entry->resources.end()) { entry->reorderResourcesByPreference(); for_each(entry->resources.begin(), entry->resources.end(), AccumulateNonP2PUrl(&urls, op->getAsInt(PREF_SPLIT))); // TODO // set checksum checksum = entry->checksum; } else { // BitTorrent downloading urls.push_back((*itr)->url); } RequestGroupHandle rg = new RequestGroup(urls, op); rg->setHintFilename(entry->filename); rg->setHintTotalLength(entry->size); rg->setNumConcurrentCommand(op->getAsInt(PREF_METALINK_SERVERS)); #ifdef ENABLE_MESSAGE_DIGEST if(entry->chunkChecksum.isNull()) { rg->setChecksum(checksum); } else { ChunkChecksumHandle cc = new ChunkChecksum(entry->chunkChecksum->digestAlgo, entry->chunkChecksum->pieceHashes, entry->chunkChecksum->pieceLength); rg->setChunkChecksum(cc); } #endif // ENABLE_MESSAGE_DIGEST groups.push_front(rg); } MultiUrlRequestInfoHandle reqInfo = new MultiUrlRequestInfo(groups, op); nextReqInfos.push_back(reqInfo); } catch(RecoverableException* ex) { logger->error("Exception caught", ex); delete ex; fail = true; } return nextReqInfos; }