Browse Source

2010-05-26 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	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
Tatsuhiro Tsujikawa 15 years ago
parent
commit
974ad351a1
4 changed files with 71 additions and 19 deletions
  1. 10 0
      ChangeLog
  2. 58 18
      src/ExpatMetalinkProcessor.cc
  3. 2 0
      src/ExpatMetalinkProcessor.h
  4. 1 1
      src/Metalink2RequestGroup.cc

+ 10 - 0
ChangeLog

@@ -1,3 +1,13 @@
+2010-05-26  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	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  <t-tujikawa@users.sourceforge.net>
 
 	Updated doc

+ 58 - 18
src/ExpatMetalinkProcessor.cc

@@ -33,6 +33,10 @@
  */
 /* copyright --> */
 #include "ExpatMetalinkProcessor.h"
+
+#include <iostream>
+#include <fstream>
+
 #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>& sessionData)
+{
+  XML_Parser parser = XML_ParserCreateNS(0, static_cast<const XML_Char>('\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<SessionData*>(XML_GetUserData(parser));
+  const SharedHandle<MetalinkParserStateMachine>& 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<Metalinker>
 MetalinkProcessor::parseFile(const std::string& filename)
 {
-  SharedHandle<DefaultDiskWriter> 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<Metalinker>
+MetalinkProcessor::parseFile(std::istream& stream)
+{
+  _stm.reset(new MetalinkParserStateMachine());
+  char buf[4096];
+
+  SharedHandle<SessionData> sessionData(new SessionData(_stm));
+  XML_Parser parser = createParser(sessionData);
+  auto_delete<XML_Parser> 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<Metalinker>
@@ -146,12 +199,7 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle<BinaryStream>& binar
   unsigned char buf[bufSize];
 
   SharedHandle<SessionData> sessionData(new SessionData(_stm));
-  XML_Parser parser = XML_ParserCreateNS(0, static_cast<const XML_Char>('\t'));
-  auto_delete<XML_Parser> 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<BinaryStream>& 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();
 }
 

+ 2 - 0
src/ExpatMetalinkProcessor.h

@@ -55,6 +55,8 @@ private:
 public:
   SharedHandle<Metalinker> parseFile(const std::string& filename);
 
+  SharedHandle<Metalinker> parseFile(std::istream& stream);
+
   SharedHandle<Metalinker> parseFromBinaryStream
   (const SharedHandle<BinaryStream>& binaryStream);
 };

+ 1 - 1
src/Metalink2RequestGroup.cc

@@ -113,7 +113,7 @@ Metalink2RequestGroup::generate
   std::vector<SharedHandle<RequestGroup> > tempgroups;
   createRequestGroup(tempgroups, entries, option);
   SharedHandle<MetadataInfo> mi;
-  if(metalinkFile == "-") {
+  if(metalinkFile == DEV_STDIN) {
     mi.reset(new MetadataInfo());
   } else {
     mi.reset(new MetadataInfo(metalinkFile));