From 974ad351a12e00757dd490829aa850c73faa812a Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 26 May 2010 12:36:23 +0000 Subject: [PATCH] 2010-05-26 Tatsuhiro Tsujikawa Fixed the bug that feeding Metalink XML via pipe (-M- option) does not work when aria2 is built with expat. Fixed the bug that when Metalink XML is fed via pipe and --save-session is used, entry "/dev/stdin" is saved in session file. * src/ExpatMetalinkProcessor.cc * src/ExpatMetalinkProcessor.h * src/Metalink2RequestGroup.cc --- ChangeLog | 10 +++++ src/ExpatMetalinkProcessor.cc | 76 ++++++++++++++++++++++++++--------- src/ExpatMetalinkProcessor.h | 2 + src/Metalink2RequestGroup.cc | 2 +- 4 files changed, 71 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5939d627..e1f77388 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-05-26 Tatsuhiro Tsujikawa + + Fixed the bug that feeding Metalink XML via pipe (-M- option) does + not work when aria2 is built with expat. Fixed the bug that when + Metalink XML is fed via pipe and --save-session is used, entry + "/dev/stdin" is saved in session file. + * src/ExpatMetalinkProcessor.cc + * src/ExpatMetalinkProcessor.h + * src/Metalink2RequestGroup.cc + 2010-05-22 Tatsuhiro Tsujikawa Updated doc diff --git a/src/ExpatMetalinkProcessor.cc b/src/ExpatMetalinkProcessor.cc index 211d1992..7dc2c76c 100644 --- a/src/ExpatMetalinkProcessor.cc +++ b/src/ExpatMetalinkProcessor.cc @@ -33,6 +33,10 @@ */ /* copyright --> */ #include "ExpatMetalinkProcessor.h" + +#include +#include + #include "DefaultDiskWriter.h" #include "MetalinkParserStateMachine.h" #include "Metalinker.h" @@ -129,13 +133,62 @@ static void mlCharacters(void* userData, const char* ch, int len) } } +static XML_Parser createParser(const SharedHandle& sessionData) +{ + XML_Parser parser = XML_ParserCreateNS(0, static_cast('\t')); + XML_SetUserData(parser, sessionData.get()); + XML_SetElementHandler(parser, &mlStartElement, &mlEndElement); + XML_SetCharacterDataHandler(parser, &mlCharacters); + return parser; +} + +static void checkError(XML_Parser parser) +{ + if(XML_Parse(parser, 0, 0, 1) == XML_STATUS_ERROR) { + throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); + } + SessionData* sessionData = + reinterpret_cast(XML_GetUserData(parser)); + const SharedHandle& stm = sessionData->_stm; + if(!stm->finished()) { + throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); + } + if(!stm->getErrors().empty()) { + throw DL_ABORT_EX(stm->getErrorString()); + } +} + SharedHandle MetalinkProcessor::parseFile(const std::string& filename) { - SharedHandle dw(new DefaultDiskWriter(filename)); - dw->openExistingFile(); + if(filename == DEV_STDIN) { + return parseFile(std::cin); + } else { + std::ifstream infile(filename.c_str(), std::ios::binary); + return parseFile(infile); + } +} - return parseFromBinaryStream(dw); +SharedHandle +MetalinkProcessor::parseFile(std::istream& stream) +{ + _stm.reset(new MetalinkParserStateMachine()); + char buf[4096]; + + SharedHandle sessionData(new SessionData(_stm)); + XML_Parser parser = createParser(sessionData); + auto_delete deleter(parser, XML_ParserFree); + while(stream) { + stream.read(buf, sizeof(buf)); + if(XML_Parse(parser, buf, stream.gcount(), 0) == XML_STATUS_ERROR) { + throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); + } + } + if(stream.bad()) { + throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); + } + checkError(parser); + return _stm->getResult(); } SharedHandle @@ -146,12 +199,7 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle& binar unsigned char buf[bufSize]; SharedHandle sessionData(new SessionData(_stm)); - XML_Parser parser = XML_ParserCreateNS(0, static_cast('\t')); - auto_delete deleter(parser, XML_ParserFree); - XML_SetUserData(parser, sessionData.get()); - XML_SetElementHandler(parser, &mlStartElement, &mlEndElement); - XML_SetCharacterDataHandler(parser, &mlCharacters); - + XML_Parser parser = createParser(sessionData); off_t readOffset = 0; while(1) { ssize_t res = binaryStream->readData(buf, bufSize, readOffset); @@ -164,15 +212,7 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle& binar } readOffset += res; } - if(XML_Parse(parser, 0, 0, 1) == XML_STATUS_ERROR) { - throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); - } - if(!_stm->finished()) { - throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); - } - if(!_stm->getErrors().empty()) { - throw DL_ABORT_EX(_stm->getErrorString()); - } + checkError(parser); return _stm->getResult(); } diff --git a/src/ExpatMetalinkProcessor.h b/src/ExpatMetalinkProcessor.h index ee7457bb..eeecba16 100644 --- a/src/ExpatMetalinkProcessor.h +++ b/src/ExpatMetalinkProcessor.h @@ -55,6 +55,8 @@ private: public: SharedHandle parseFile(const std::string& filename); + SharedHandle parseFile(std::istream& stream); + SharedHandle parseFromBinaryStream (const SharedHandle& binaryStream); }; diff --git a/src/Metalink2RequestGroup.cc b/src/Metalink2RequestGroup.cc index a027a91f..5f1b9b54 100644 --- a/src/Metalink2RequestGroup.cc +++ b/src/Metalink2RequestGroup.cc @@ -113,7 +113,7 @@ Metalink2RequestGroup::generate std::vector > tempgroups; createRequestGroup(tempgroups, entries, option); SharedHandle mi; - if(metalinkFile == "-") { + if(metalinkFile == DEV_STDIN) { mi.reset(new MetadataInfo()); } else { mi.reset(new MetadataInfo(metalinkFile));