/* */ #include "metalink_helper.h" #include "Option.h" #include "MetalinkEntry.h" #include "MetalinkParserStateMachine.h" #include "Metalinker.h" #include "XmlParser.h" #include "prefs.h" #include "DlAbortEx.h" #include "BinaryStream.h" #include "MetalinkMetaurl.h" namespace aria2 { namespace metalink { namespace { void query (std::vector >& result, const SharedHandle& metalinker, const Option* option) { metalinker->queryEntry(result, option->get(PREF_METALINK_VERSION), option->get(PREF_METALINK_LANGUAGE), option->get(PREF_METALINK_OS)); } } // namespace void parseAndQuery (std::vector >& result, const std::string& filename, const Option* option, const std::string& baseUri) { SharedHandle metalinker = parseFile(filename, baseUri); query(result, metalinker, option); } void parseAndQuery (std::vector >& result, BinaryStream* bs, const Option* option, const std::string& baseUri) { SharedHandle metalinker = parseBinaryStream(bs, baseUri); query(result, metalinker, option); } void groupEntryByMetaurlName (std::vector< std::pair > > >& result, const std::vector >& entries) { for(std::vector >::const_iterator eiter = entries.begin(), eoi = entries.end(); eiter != eoi; ++eiter) { if((*eiter)->metaurls.empty()) { std::pair > > p; p.second.push_back(*eiter); result.push_back(p); } else { std::vector< std::pair > > >::iterator i = result.begin(); if((*eiter)->metaurls[0]->name.empty() || !(*eiter)->sizeKnown) { i = result.end(); } for(; i != result.end(); ++i) { if((*i).first == (*eiter)->metaurls[0]->url && !(*i).second[0]->metaurls[0]->name.empty()) { (*i).second.push_back(*eiter); break; } } if(i == result.end()) { std::pair > > p; p.first = (*eiter)->metaurls[0]->url; p.second.push_back(*eiter); result.push_back(p); } } } } SharedHandle parseFile (const std::string& filename, const std::string& baseUri) { MetalinkParserStateMachine psm; psm.setBaseUri(baseUri); if(!xml::parseFile(filename, &psm)) { throw DL_ABORT_EX2("Could not parse Metalink XML document.", error_code::METALINK_PARSE_ERROR); } if(!psm.getErrors().empty()) { throw DL_ABORT_EX2(psm.getErrorString(), error_code::METALINK_PARSE_ERROR); } return psm.getResult(); } SharedHandle parseBinaryStream (BinaryStream* bs, const std::string& baseUri) { MetalinkParserStateMachine psm; psm.setBaseUri(baseUri); xml::XmlParser ps(&psm); unsigned char buf[4096]; ssize_t nread; int64_t offread = 0; bool retval = true; while((nread = bs->readData(buf, sizeof(buf), offread)) > 0) { if(ps.parseUpdate(reinterpret_cast(buf), nread) < 0) { retval = false; break; } offread += nread; } if(nread == 0 && retval) { if(ps.parseFinal(0, 0) < 0) { retval = false; } } if(!retval) { throw DL_ABORT_EX2("Could not parse Metalink XML document.", error_code::METALINK_PARSE_ERROR); } if(!psm.getErrors().empty()) { throw DL_ABORT_EX2(psm.getErrorString(), error_code::METALINK_PARSE_ERROR); } return psm.getResult(); } } // namespace metalink } // namespace aria2