From 440f29aca353b8d4f1de560c183c01c43b8452fb Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 10 Nov 2011 22:38:01 +0900 Subject: [PATCH] Rewritten Metalink XML parser. Now we don't strip white spaces while parsing Metalink V3 document. Expat implementation does not included in this change. --- configure.ac | 6 +- src/Makefile.am | 24 +- src/Metalink2RequestGroup.cc | 2 +- src/MetalinkParserState.cc | 19 - src/MetalinkParserState.h | 25 +- src/MetalinkParserStateImpl.cc | 61 ++- src/MetalinkParserStateImpl.h | 21 +- src/MetalinkParserStateMachine.cc | 12 +- src/MetalinkParserStateMachine.h | 39 +- src/MetalinkParserStateV3Impl.cc | 453 ++++++++---------- src/MetalinkParserStateV3Impl.h | 130 ++--- src/MetalinkParserStateV4Impl.cc | 399 +++++++-------- src/MetalinkParserStateV4Impl.h | 114 ++--- src/ParserStateMachine.h | 70 +++ ...XMetalinkProcessor.cc => Xml2XmlParser.cc} | 183 +++---- ...SAXMetalinkProcessor.h => Xml2XmlParser.h} | 42 +- src/XmlAttr.cc | 47 ++ src/XmlAttr.h | 59 +++ src/{MetalinkProcessor.h => XmlParser.h} | 12 +- src/metalink_helper.cc | 45 +- src/metalink_helper.h | 10 +- test/MetalinkProcessorTest.cc | 311 ++++++------ 22 files changed, 1096 insertions(+), 988 deletions(-) create mode 100644 src/ParserStateMachine.h rename src/{XML2SAXMetalinkProcessor.cc => Xml2XmlParser.cc} (53%) rename src/{XML2SAXMetalinkProcessor.h => Xml2XmlParser.h} (69%) create mode 100644 src/XmlAttr.cc create mode 100644 src/XmlAttr.h rename src/{MetalinkProcessor.h => XmlParser.h} (88%) diff --git a/configure.ac b/configure.ac index 6ef0af17..24e2e92d 100644 --- a/configure.ac +++ b/configure.ac @@ -231,10 +231,8 @@ else AM_CONDITIONAL([ENABLE_METALINK], false) fi -AM_CONDITIONAL([ENABLE_METALINK_LIBXML2], - [test "x$enable_metalink" = "xyes" && test "x$have_libxml2" = "xyes"]) -AM_CONDITIONAL([ENABLE_METALINK_LIBEXPAT], - [test "x$enable_metalink" = "xyes" && test "x$have_libexpat" = "xyes"]) +AM_CONDITIONAL([HAVE_SOME_XMLLIB], + [test "x$have_libxml2" = "xyes" || test "x$have_libexpat" = "xyes"]) if test "x$have_libxml2" = "xyes" || test "x$have_libexpat" = "xyes"; then enable_xml_rpc=yes diff --git a/src/Makefile.am b/src/Makefile.am index c3670dca..cf387618 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -228,6 +228,12 @@ if MINGW_BUILD SRCS += WinConsoleFile.cc WinConsoleFile.h endif # MINGW_BUILD +if HAVE_SOME_XMLLIB +SRCS += XmlAttr.cc XmlAttr.h\ + XmlParser.h\ + ParserStateMachine.h +endif # HAVE_SOME_XMLLIB + if ENABLE_XML_RPC SRCS += XmlRpcRequestParserController.cc XmlRpcRequestParserController.h\ XmlRpcRequestParserStateMachine.cc XmlRpcRequestParserStateMachine.h\ @@ -487,7 +493,6 @@ SRCS += Metalinker.cc Metalinker.h\ MetalinkEntry.cc MetalinkEntry.h\ MetalinkResource.cc MetalinkResource.h\ MetalinkMetaurl.cc MetalinkMetaurl.h\ - MetalinkProcessor.h\ MetalinkParserController.cc MetalinkParserController.h\ MetalinkParserStateMachine.cc MetalinkParserStateMachine.h\ MetalinkParserState.cc MetalinkParserState.h\ @@ -497,16 +502,17 @@ SRCS += Metalinker.cc Metalinker.h\ Metalink2RequestGroup.cc Metalink2RequestGroup.h\ MetalinkPostDownloadHandler.cc MetalinkPostDownloadHandler.h\ metalink_helper.cc metalink_helper.h + +if HAVE_LIBXML2 +SRCS += Xml2XmlParser.cc Xml2XmlParser.h +endif # HAVE_LIBXML2 + +if HAVE_LIBEXPAT +SRCS += ExpatXmlParser.cc ExpatXmlParser.h +endif # HAVE_LIBEXPAT + endif # ENABLE_METALINK -if ENABLE_METALINK_LIBXML2 -SRCS += XML2SAXMetalinkProcessor.cc XML2SAXMetalinkProcessor.h -endif # ENABLE_METALINK_LIBXML2 - -if ENABLE_METALINK_LIBEXPAT -SRCS += ExpatMetalinkProcessor.cc ExpatMetalinkProcessor.h -endif # ENABLE_METALINK_LIBEXPAT - if !HAVE_ASCTIME_R SRCS += asctime_r.c asctime_r.h endif # !HAVE_ASCTIME_R diff --git a/src/Metalink2RequestGroup.cc b/src/Metalink2RequestGroup.cc index f56883cc..51d67551 100644 --- a/src/Metalink2RequestGroup.cc +++ b/src/Metalink2RequestGroup.cc @@ -136,7 +136,7 @@ Metalink2RequestGroup::generate const std::string& baseUri) { std::vector > entries; - metalink::parseAndQuery(entries, binaryStream, option.get(), baseUri); + metalink::parseAndQuery(entries, binaryStream.get(), option.get(), baseUri); std::vector > tempgroups; createRequestGroup(tempgroups, entries, option); SharedHandle mi(new MetadataInfo()); diff --git a/src/MetalinkParserState.cc b/src/MetalinkParserState.cc index 080cd413..7125dc16 100644 --- a/src/MetalinkParserState.cc +++ b/src/MetalinkParserState.cc @@ -36,23 +36,4 @@ namespace aria2 { -XmlAttr::XmlAttr() {} - -XmlAttr::XmlAttr(const XmlAttr& c) - : localname(c.localname), prefix(c.prefix), nsUri(c.nsUri), value(c.value) -{} - -XmlAttr::~XmlAttr() {} - -XmlAttr& XmlAttr::operator=(const XmlAttr& c) -{ - if(this != &c) { - localname = c.localname; - prefix = c.prefix; - nsUri = c.nsUri; - value = c.value; - } - return *this; -} - } // namespace aria2 diff --git a/src/MetalinkParserState.h b/src/MetalinkParserState.h index 79f52b6a..54fce4a0 100644 --- a/src/MetalinkParserState.h +++ b/src/MetalinkParserState.h @@ -43,18 +43,7 @@ namespace aria2 { class MetalinkParserStateMachine; - -struct XmlAttr { - std::string localname; - std::string prefix; - std::string nsUri; - std::string value; - - XmlAttr(); - XmlAttr(const XmlAttr& attr); - ~XmlAttr(); - XmlAttr& operator=(const XmlAttr&); -}; +class XmlAttr; class MetalinkParserState { @@ -63,16 +52,16 @@ public: virtual void beginElement (MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) {} virtual void endElement (MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) {} virtual bool needsCharactersBuffering() const diff --git a/src/MetalinkParserStateImpl.cc b/src/MetalinkParserStateImpl.cc index 2608d3bf..b61d8f57 100644 --- a/src/MetalinkParserStateImpl.cc +++ b/src/MetalinkParserStateImpl.cc @@ -33,36 +33,69 @@ */ /* copyright --> */ #include "MetalinkParserStateImpl.h" + +#include + #include "MetalinkParserStateV3Impl.h" #include "MetalinkParserStateV4Impl.h" #include "MetalinkParserStateMachine.h" +#include "XmlAttr.h" namespace aria2 { +namespace { +class FindAttr { +private: + const char* localname_; + const char* nsUri_; +public: + FindAttr(const char* localname, const char* nsUri) + : localname_(localname), + nsUri_(nsUri) + {} + + bool operator()(const XmlAttr& attr) const + { + return strcmp(attr.localname, localname_) == 0 && + (attr.nsUri == 0 || strcmp(attr.nsUri, nsUri_) == 0); + } +}; +} // namespace + +std::vector::const_iterator findAttr +(const std::vector& attrs, + const char* localname, + const char* nsUri) +{ + return std::find_if(attrs.begin(), attrs.end(), FindAttr(localname, nsUri)); +} + void InitialMetalinkParserState::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri == METALINK4_NAMESPACE_URI && localname == "metalink") { - stm->setMetalinkStateV4(); - } else if(nsUri == METALINK3_NAMESPACE_URI && localname == "metalink") { - stm->setMetalinkState(); + if(!nsUri || strcmp(localname, "metalink") != 0) { + psm->setSkipTagState(); + } else if(strcmp(nsUri, METALINK4_NAMESPACE_URI) == 0) { + psm->setMetalinkStateV4(); + } else if(strcmp(nsUri, METALINK3_NAMESPACE_URI) == 0) { + psm->setMetalinkState(); } else { - stm->setSkipTagState(); + psm->setSkipTagState(); } } void SkipTagMetalinkParserState::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - stm->setSkipTagState(); + psm->setSkipTagState(); } } // namespace aria2 diff --git a/src/MetalinkParserStateImpl.h b/src/MetalinkParserStateImpl.h index c6f6b452..94c823d6 100644 --- a/src/MetalinkParserStateImpl.h +++ b/src/MetalinkParserStateImpl.h @@ -39,23 +39,28 @@ namespace aria2 { +std::vector::const_iterator findAttr +(const std::vector& attrs, + const char* localname, + const char* nsUri); + class SkipTagMetalinkParserState:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); }; class InitialMetalinkParserState:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); }; diff --git a/src/MetalinkParserStateMachine.cc b/src/MetalinkParserStateMachine.cc index 1f2435c3..d97c6bbe 100644 --- a/src/MetalinkParserStateMachine.cc +++ b/src/MetalinkParserStateMachine.cc @@ -502,18 +502,18 @@ void MetalinkParserStateMachine::cancelMetaurlTransaction() } void MetalinkParserStateMachine::beginElement -(const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { stateStack_.top()->beginElement(this, localname, prefix, nsUri, attrs); } void MetalinkParserStateMachine::endElement -(const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { stateStack_.top()->endElement(this, localname, prefix, nsUri, characters); diff --git a/src/MetalinkParserStateMachine.h b/src/MetalinkParserStateMachine.h index f7dce78c..e0d9038c 100644 --- a/src/MetalinkParserStateMachine.h +++ b/src/MetalinkParserStateMachine.h @@ -35,7 +35,8 @@ #ifndef D_METALINK_PARSER_STATE_MACHINE_H #define D_METALINK_PARSER_STATE_MACHINE_H -#include "common.h" +#include "ParserStateMachine.h" + #include #include #include @@ -48,7 +49,7 @@ namespace aria2 { class Metalinker; -class MetalinkParserStateMachine { +class MetalinkParserStateMachine : public ParserStateMachine { private: SharedHandle ctrl_; @@ -92,7 +93,23 @@ private: public: MetalinkParserStateMachine(); - ~MetalinkParserStateMachine(); + virtual ~MetalinkParserStateMachine(); + + virtual bool needsCharactersBuffering() const; + + virtual bool finished() const; + + virtual void beginElement + (const char* localname, + const char* prefix, + const char* nsUri, + const std::vector& attrs); + + virtual void endElement + (const char* localname, + const char* prefix, + const char* nsUri, + const std::string& characters); void setSkipTagState(); @@ -138,20 +155,6 @@ public: void setURLStateV4(); void setMetaurlStateV4(); - bool finished() const; - - void beginElement - (const std::string& localname, - const std::string& prefix, - const std::string& nsUri, - const std::vector& attrs); - - void endElement - (const std::string& localname, - const std::string& prefix, - const std::string& nsUri, - const std::string& characters); - void newEntryTransaction(); void setFileNameOfEntry(const std::string& filename); @@ -250,8 +253,6 @@ public: void cancelMetaurlTransaction(); - bool needsCharactersBuffering() const; - // Only stores first 10 errors. void logError(const std::string& log); diff --git a/src/MetalinkParserStateV3Impl.cc b/src/MetalinkParserStateV3Impl.cc index 7156110d..857add9e 100644 --- a/src/MetalinkParserStateV3Impl.cc +++ b/src/MetalinkParserStateV3Impl.cc @@ -33,412 +33,385 @@ */ /* copyright --> */ #include "MetalinkParserStateV3Impl.h" + +#include + #include "MetalinkParserStateMachine.h" #include "RecoverableException.h" #include "MetalinkResource.h" #include "util.h" +#include "XmlAttr.h" namespace aria2 { -namespace { - -const std::string FILE("file"); -const std::string FILES("files"); -const std::string HASH("hash"); -const std::string LANGUAGE("language"); -const std::string LENGTH("length"); -const std::string LOCATION("location"); -const std::string MAXCONNECTIONS("maxconnections"); -// Can't use name VERSION because it is used as a macro. -const std::string METALINK_VERSION("version"); -const std::string NAME("name"); -const std::string OS("os"); -const std::string PIECE("piece"); -const std::string PIECES("pieces"); -const std::string PREFERENCE("preference"); -const std::string RESOURCES("resources"); -const std::string SIGNATURE("signature"); -const std::string SIZE("size"); -const std::string TYPE("type"); -const std::string URL("url"); -const std::string VERIFICATION("verification"); -} // namespace - -const std::string METALINK3_NAMESPACE_URI("http://www.metalinker.org/"); +const char METALINK3_NAMESPACE_URI[] = "http://www.metalinker.org/"; namespace { -class FindAttr { -private: - const std::string& localname_; -public: - FindAttr(const std::string& localname):localname_(localname) {} - - bool operator()(const XmlAttr& attr) const - { - return attr.localname == localname_ && - (attr.nsUri.empty() || attr.nsUri == METALINK3_NAMESPACE_URI); - } -}; -} // namespace - -namespace { -template -typename Container::const_iterator findAttr -(const Container& attrs, const std::string& localname) +bool checkNsUri(const char* nsUri) { - return std::find_if(attrs.begin(), attrs.end(), FindAttr(localname)); + return nsUri && strcmp(nsUri, METALINK3_NAMESPACE_URI) == 0; } } // namespace void MetalinkMetalinkParserState::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri == METALINK3_NAMESPACE_URI && localname == FILES) { - stm->setFilesState(); + if(checkNsUri(nsUri) && strcmp(localname, "files") == 0) { + psm->setFilesState(); } else { - stm->setSkipTagState(); + psm->setSkipTagState(); } } void FilesMetalinkParserState::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri == METALINK3_NAMESPACE_URI && localname == FILE) { - stm->setFileState(); - std::vector::const_iterator itr = findAttr(attrs, NAME); + if(checkNsUri(nsUri) && strcmp(localname, "file") == 0) { + psm->setFileState(); + std::vector::const_iterator itr = + findAttr(attrs, "name", METALINK3_NAMESPACE_URI); if(itr != attrs.end()) { - std::string name = util::strip((*itr).value); + std::string name((*itr).value, (*itr).valueLength); if(name.empty() || util::detectDirTraversal(name)) { return; } - stm->newEntryTransaction(); - stm->setFileNameOfEntry(name); + psm->newEntryTransaction(); + psm->setFileNameOfEntry(name); } } else { - stm->setSkipTagState(); + psm->setSkipTagState(); } } void FileMetalinkParserState::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri != METALINK3_NAMESPACE_URI) { - stm->setSkipTagState(); - } else if(localname == SIZE) { - stm->setSizeState(); - } else if(localname == METALINK_VERSION) { - stm->setVersionState(); - } else if(localname == LANGUAGE) { - stm->setLanguageState(); - } else if(localname == OS) { - stm->setOSState(); - } else if(localname == VERIFICATION) { - stm->setVerificationState(); - } else if(localname == RESOURCES) { - stm->setResourcesState(); + if(!checkNsUri(nsUri)) { + psm->setSkipTagState(); + } else if(strcmp(localname, "size") == 0) { + psm->setSizeState(); + } else if(strcmp(localname, "version") == 0) { + psm->setVersionState(); + } else if(strcmp(localname, "language") == 0) { + psm->setLanguageState(); + } else if(strcmp(localname, "os") == 0) { + psm->setOSState(); + } else if(strcmp(localname, "verification") == 0) { + psm->setVerificationState(); + } else if(strcmp(localname, "resources") == 0) { + psm->setResourcesState(); int maxConnections; - { - std::vector::const_iterator itr = findAttr(attrs,MAXCONNECTIONS); - if(itr == attrs.end()) { + std::vector::const_iterator itr = + findAttr(attrs, "maxconnections", METALINK3_NAMESPACE_URI); + if(itr == attrs.end()) { + maxConnections = -1; + } else { + if(!util::parseIntNoThrow + (maxConnections,(*itr).value, (*itr).value+(*itr).valueLength) || + maxConnections <= 0) { maxConnections = -1; - } else { - try { - maxConnections = - util::parseInt((*itr).value.begin(), (*itr).value.end()); - } catch(RecoverableException& e) { - maxConnections = -1; - } } } - stm->setMaxConnectionsOfEntry(maxConnections); + psm->setMaxConnectionsOfEntry(maxConnections); } else { - stm->setSkipTagState(); + psm->setSkipTagState(); } } void FileMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->commitEntryTransaction(); + psm->commitEntryTransaction(); } void SizeMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - try { - stm->setFileLengthOfEntry - (util::parseULLInt(characters.begin(), characters.end())); - } catch(RecoverableException& e) { - // current metalink specification doesn't require size element. + // current metalink specification doesn't require size element. + int64_t size; + if(util::parseLLIntNoThrow(size, characters.begin(), characters.end()) && + size >= 0) { + psm->setFileLengthOfEntry(size); } } void VersionMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setVersionOfEntry(util::strip(characters)); + psm->setVersionOfEntry(characters); } void LanguageMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setLanguageOfEntry(util::strip(characters)); + psm->setLanguageOfEntry(characters); } void OSMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setOSOfEntry(util::strip(characters)); + psm->setOSOfEntry(characters); } void VerificationMetalinkParserState::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri != METALINK3_NAMESPACE_URI) { - stm->setSkipTagState(); + if(!checkNsUri(nsUri)) { + psm->setSkipTagState(); } else #ifdef ENABLE_MESSAGE_DIGEST - if(localname == HASH) { - stm->setHashState(); - std::vector::const_iterator itr = findAttr(attrs, TYPE); - if(itr == attrs.end()) { - return; - } else { - std::string type = util::strip((*itr).value); - stm->newChecksumTransaction(); - stm->setTypeOfChecksum(type); - } - } else if(localname == PIECES) { - stm->setPiecesState(); - try { - size_t length; + if(strcmp(localname, "hash") == 0) { + psm->setHashState(); + std::vector::const_iterator itr = + findAttr(attrs, "type", METALINK3_NAMESPACE_URI); + if(itr == attrs.end()) { + return; + } else { + psm->newChecksumTransaction(); + psm->setTypeOfChecksum(std::string((*itr).value, (*itr).valueLength)); + } + } else if(strcmp(localname, "pieces") == 0) { + psm->setPiecesState(); + int32_t length; { - std::vector::const_iterator itr = findAttr(attrs, LENGTH); + std::vector::const_iterator itr = + findAttr(attrs, "length", METALINK3_NAMESPACE_URI); if(itr == attrs.end()) { return; } else { - length = util::parseInt((*itr).value.begin(), (*itr).value.end()); + if(!util::parseIntNoThrow + (length, (*itr).value, (*itr).value+(*itr).valueLength) || + length < 0) { + return; + } } } std::string type; { - std::vector::const_iterator itr = findAttr(attrs, TYPE); + std::vector::const_iterator itr = + findAttr(attrs, "type", METALINK3_NAMESPACE_URI); if(itr == attrs.end()) { return; } else { - type = util::strip((*itr).value); + type.assign((*itr).value, (*itr).valueLength); } } - stm->newChunkChecksumTransaction(); - stm->setLengthOfChunkChecksum(length); - stm->setTypeOfChunkChecksum(type); - } catch(RecoverableException& e) { - stm->cancelChunkChecksumTransaction(); - } - } else + psm->newChunkChecksumTransaction(); + psm->setLengthOfChunkChecksum(length); + psm->setTypeOfChunkChecksum(type); + } else #endif // ENABLE_MESSAGE_DIGEST - if(localname == SIGNATURE) { - stm->setSignatureState(); - std::vector::const_iterator itr = findAttr(attrs, TYPE); - if(itr == attrs.end()) { - return; - } else { - stm->newSignatureTransaction(); - stm->setTypeOfSignature(util::strip((*itr).value)); - std::vector::const_iterator itr = findAttr(attrs, FILE); - if(itr != attrs.end()) { - std::string file = util::strip((*itr).value); - if(!util::detectDirTraversal(file)) { - stm->setFileOfSignature(file); + if(strcmp(localname, "signature") == 0) { + psm->setSignatureState(); + std::vector::const_iterator itr = + findAttr(attrs, "type", METALINK3_NAMESPACE_URI); + if(itr == attrs.end()) { + return; + } else { + psm->newSignatureTransaction(); + psm->setTypeOfSignature + (std::string((*itr).value, (*itr).valueLength)); + std::vector::const_iterator itr = + findAttr(attrs, "file", METALINK3_NAMESPACE_URI); + if(itr != attrs.end()) { + std::string file((*itr).value, (*itr).valueLength); + if(!util::detectDirTraversal(file)) { + psm->setFileOfSignature(file); + } } } + } else { + psm->setSkipTagState(); } - } else { - stm->setSkipTagState(); - } } void HashMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setHashOfChecksum(util::strip(characters)); - stm->commitChecksumTransaction(); + psm->setHashOfChecksum(characters); + psm->commitChecksumTransaction(); } void PiecesMetalinkParserState::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri == METALINK3_NAMESPACE_URI && localname == HASH) { - stm->setPieceHashState(); - std::vector::const_iterator itr = findAttr(attrs, PIECE); + if(checkNsUri(nsUri) && strcmp(localname, "hash") == 0) { + psm->setPieceHashState(); + std::vector::const_iterator itr = + findAttr(attrs, "piece", METALINK3_NAMESPACE_URI); if(itr == attrs.end()) { - stm->cancelChunkChecksumTransaction(); + psm->cancelChunkChecksumTransaction(); } else { - try { - stm->createNewHashOfChunkChecksum - (util::parseInt((*itr).value.begin(), (*itr).value.end())); - } catch(RecoverableException& e) { - stm->cancelChunkChecksumTransaction(); + int32_t idx; + if(util::parseIntNoThrow + (idx, (*itr).value, (*itr).value+(*itr).valueLength) && idx >= 0) { + psm->createNewHashOfChunkChecksum(idx); + } else { + psm->cancelChunkChecksumTransaction(); } } } else { - stm->setSkipTagState(); + psm->setSkipTagState(); } } void PiecesMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->commitChunkChecksumTransaction(); + psm->commitChunkChecksumTransaction(); } void PieceHashMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setMessageDigestOfChunkChecksum(util::strip(characters)); - stm->addHashOfChunkChecksum(); + psm->setMessageDigestOfChunkChecksum(characters); + psm->addHashOfChunkChecksum(); } void SignatureMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setBodyOfSignature(util::strip(characters)); - stm->commitSignatureTransaction(); + psm->setBodyOfSignature(characters); + psm->commitSignatureTransaction(); } void ResourcesMetalinkParserState::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri != METALINK3_NAMESPACE_URI) { - stm->setSkipTagState(); - } else if(localname == URL) { - stm->setURLState(); + if(!checkNsUri(nsUri)) { + psm->setSkipTagState(); + } else if(strcmp(localname, "url") == 0) { + psm->setURLState(); std::string type; { - std::vector::const_iterator itr = findAttr(attrs, TYPE); + std::vector::const_iterator itr = + findAttr(attrs, "type", METALINK3_NAMESPACE_URI); if(itr == attrs.end()) { return; } else { - type = util::strip((*itr).value); + type.assign((*itr).value, (*itr).valueLength); } } std::string location; { - std::vector::const_iterator itr = findAttr(attrs, LOCATION); + std::vector::const_iterator itr = + findAttr(attrs, "location", METALINK3_NAMESPACE_URI); if(itr != attrs.end()) { - location = util::strip((*itr).value); + location.assign((*itr).value, (*itr).valueLength); } } int preference; { - std::vector::const_iterator itr = findAttr(attrs, PREFERENCE); + std::vector::const_iterator itr = + findAttr(attrs, "preference", METALINK3_NAMESPACE_URI); if(itr == attrs.end()) { preference = MetalinkResource::getLowestPriority(); } else { - try { + if(util::parseIntNoThrow + (preference, (*itr).value, (*itr).value+(*itr).valueLength) && + preference >= 0) { // In Metalink3Spec, highest prefernce value is 100. We - // uses Metalink4Spec priority unit system in which 1 is + // use Metalink4Spec priority unit system in which 1 is // higest. - preference = - 101-util::parseInt((*itr).value.begin(), (*itr).value.end()); - } catch(RecoverableException& e) { + preference = 101-preference; + } else { preference = MetalinkResource::getLowestPriority(); } } } int maxConnections; { - std::vector::const_iterator itr = findAttr(attrs,MAXCONNECTIONS); + std::vector::const_iterator itr = + findAttr(attrs, "maxconnections", METALINK3_NAMESPACE_URI); if(itr == attrs.end()) { maxConnections = -1; } else { - try { - maxConnections = - util::parseInt((*itr).value.begin(), (*itr).value.end()); - } catch(RecoverableException& e) { + if(!util::parseIntNoThrow + (maxConnections, (*itr).value, (*itr).value+(*itr).valueLength) || + maxConnections <= 0) { maxConnections = -1; } } } - stm->newResourceTransaction(); - stm->setTypeOfResource(type); - stm->setLocationOfResource(location); - stm->setPriorityOfResource(preference); - stm->setMaxConnectionsOfResource(maxConnections); + psm->newResourceTransaction(); + psm->setTypeOfResource(type); + psm->setLocationOfResource(location); + psm->setPriorityOfResource(preference); + psm->setMaxConnectionsOfResource(maxConnections); } else { - stm->setSkipTagState(); + psm->setSkipTagState(); } } void URLMetalinkParserState::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setURLOfResource(util::strip(characters)); - stm->commitResourceTransaction(); + psm->setURLOfResource(characters); + psm->commitResourceTransaction(); } } // namespace aria2 diff --git a/src/MetalinkParserStateV3Impl.h b/src/MetalinkParserStateV3Impl.h index 736d618e..dccc2298 100644 --- a/src/MetalinkParserStateV3Impl.h +++ b/src/MetalinkParserStateV3Impl.h @@ -40,25 +40,25 @@ namespace aria2 { -extern const std::string METALINK3_NAMESPACE_URI; +extern const char METALINK3_NAMESPACE_URI[]; class MetalinkMetalinkParserState:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); }; class FilesMetalinkParserState:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); virtual bool needsCharactersBuffering() const @@ -70,16 +70,16 @@ public: class FileMetalinkParserState:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -91,10 +91,10 @@ public: class SizeMetalinkParserState:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -106,10 +106,10 @@ public: class VersionMetalinkParserState:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -121,10 +121,10 @@ public: class LanguageMetalinkParserState:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -136,10 +136,10 @@ public: class OSMetalinkParserState:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -151,10 +151,10 @@ public: class VerificationMetalinkParserState:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); virtual bool needsCharactersBuffering() const @@ -166,10 +166,10 @@ public: class HashMetalinkParserState:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -181,16 +181,16 @@ public: class PiecesMetalinkParserState:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -202,10 +202,10 @@ public: class PieceHashMetalinkParserState:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -217,10 +217,10 @@ public: class SignatureMetalinkParserState:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -232,10 +232,10 @@ public: class ResourcesMetalinkParserState:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); virtual bool needsCharactersBuffering() const @@ -247,10 +247,10 @@ public: class URLMetalinkParserState:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const diff --git a/src/MetalinkParserStateV4Impl.cc b/src/MetalinkParserStateV4Impl.cc index 9df1f98e..7a22b98e 100644 --- a/src/MetalinkParserStateV4Impl.cc +++ b/src/MetalinkParserStateV4Impl.cc @@ -33,370 +33,343 @@ */ /* copyright --> */ #include "MetalinkParserStateV4Impl.h" + +#include + #include "MetalinkParserStateMachine.h" #include "RecoverableException.h" #include "MetalinkResource.h" #include "util.h" +#include "XmlAttr.h" namespace aria2 { -namespace { - -const std::string FILE("file"); -const std::string HASH("hash"); -const std::string LANGUAGE("language"); -const std::string LENGTH("length"); -const std::string LOCATION("location"); -const std::string METALINK("metalink"); -// Can't use name VERSION because it is used as a macro. -const std::string METALINK_VERSION("version"); -const std::string METAURL("metaurl"); -const std::string NAME("name"); -const std::string OS("os"); -const std::string PIECE("piece"); -const std::string PIECES("pieces"); -const std::string PRIORITY("priority"); -const std::string SIGNATURE("signature"); -const std::string SIZE("size"); -const std::string TYPE("type"); -const std::string MEDIATYPE("mediatype"); -const std::string URL("url"); -} // namespace - -const std::string METALINK4_NAMESPACE_URI("urn:ietf:params:xml:ns:metalink"); +const char METALINK4_NAMESPACE_URI[] = "urn:ietf:params:xml:ns:metalink"; namespace { -class FindAttr { -private: - const std::string& localname_; -public: - FindAttr(const std::string& localname):localname_(localname) {} - - bool operator()(const XmlAttr& attr) const - { - return attr.localname == localname_ && - (attr.nsUri.empty() || attr.nsUri == METALINK4_NAMESPACE_URI); - } -}; -} // namespace - -namespace { -template -typename Container::const_iterator findAttr -(const Container& attrs, const std::string& localname) +bool checkNsUri(const char* nsUri) { - return std::find_if(attrs.begin(), attrs.end(), FindAttr(localname)); + return nsUri && strcmp(nsUri, METALINK4_NAMESPACE_URI) == 0; } } // namespace void MetalinkMetalinkParserStateV4::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri == METALINK4_NAMESPACE_URI && localname == FILE) { - stm->setFileStateV4(); - std::vector::const_iterator itr = findAttr(attrs, NAME); - if(itr == attrs.end() || (*itr).value.empty()) { - stm->logError("Missing file@name"); - return; - } else if(util::detectDirTraversal((*itr).value)) { - stm->logError("Bad file@name"); + if(checkNsUri(nsUri) && strcmp(localname, "file") == 0) { + psm->setFileStateV4(); + std::vector::const_iterator itr = + findAttr(attrs, "name", METALINK4_NAMESPACE_URI); + if(itr == attrs.end() || (*itr).valueLength == 0) { + psm->logError("Missing file@name"); return; } - stm->newEntryTransaction(); - stm->setFileNameOfEntry((*itr).value); + std::string name((*itr).value, (*itr).valueLength); + if(util::detectDirTraversal(name)) { + psm->logError("Bad file@name"); + return; + } + psm->newEntryTransaction(); + psm->setFileNameOfEntry(name); } else { - stm->setSkipTagState(); + psm->setSkipTagState(); } } void FileMetalinkParserStateV4::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri != METALINK4_NAMESPACE_URI) { - stm->setSkipTagState(); - } else if(localname == SIZE) { - stm->setSizeStateV4(); - } else if(localname == METALINK_VERSION) { - stm->setVersionStateV4(); - } else if(localname == LANGUAGE) { - stm->setLanguageStateV4(); - } else if(localname == OS) { - stm->setOSStateV4(); - } else if(localname == METAURL) { - stm->setMetaurlStateV4(); + if(!checkNsUri(nsUri)) { + psm->setSkipTagState(); + } else if(strcmp(localname, "size") == 0) { + psm->setSizeStateV4(); + } else if(strcmp(localname, "version") == 0) { + psm->setVersionStateV4(); + } else if(strcmp(localname, "language") == 0) { + psm->setLanguageStateV4(); + } else if(strcmp(localname, "os") == 0) { + psm->setOSStateV4(); + } else if(strcmp(localname, "metaurl") == 0) { + psm->setMetaurlStateV4(); std::string name; { - std::vector::const_iterator itr = findAttr(attrs, NAME); + std::vector::const_iterator itr = + findAttr(attrs, "name", METALINK4_NAMESPACE_URI); if(itr != attrs.end()) { - if((*itr).value.empty() || util::detectDirTraversal((*itr).value)) { - stm->logError("Bad metaurl@name"); + name.assign((*itr).value, (*itr).valueLength); + if(name.empty() || util::detectDirTraversal(name)) { + psm->logError("Bad metaurl@name"); return; - } else { - name = (*itr).value; } } } int priority; { - std::vector::const_iterator itr = findAttr(attrs, PRIORITY); + std::vector::const_iterator itr = + findAttr(attrs, "priority", METALINK4_NAMESPACE_URI); if(itr == attrs.end()) { priority = MetalinkResource::getLowestPriority(); } else { - try { - priority = util::parseInt((*itr).value.begin(), (*itr).value.end()); + if(util::parseIntNoThrow + (priority, (*itr).value, (*itr).value+(*itr).valueLength)) { if(priority < 1 || MetalinkResource::getLowestPriority() < priority) { - stm->logError("metaurl@priority is out of range"); + psm->logError("metaurl@priority is out of range"); return; } - } catch(RecoverableException& e) { - stm->logError("Bad metaurl@priority"); + } else { + psm->logError("Bad metaurl@priority"); return; } } } std::string mediatype; { - std::vector::const_iterator itr = findAttr(attrs, MEDIATYPE); - if(itr == attrs.end() || (*itr).value.empty()) { - stm->logError("Missing metaurl@mediatype"); + std::vector::const_iterator itr = + findAttr(attrs, "mediatype", METALINK4_NAMESPACE_URI); + if(itr == attrs.end() || (*itr).valueLength == 0) { + psm->logError("Missing metaurl@mediatype"); return; } else { - mediatype = (*itr).value; + mediatype.assign((*itr).value, (*itr).valueLength); } } - stm->newMetaurlTransaction(); - stm->setPriorityOfMetaurl(priority); - stm->setMediatypeOfMetaurl(mediatype); - stm->setNameOfMetaurl(name); - } else if(localname == URL) { - stm->setURLStateV4(); + psm->newMetaurlTransaction(); + psm->setPriorityOfMetaurl(priority); + psm->setMediatypeOfMetaurl(mediatype); + psm->setNameOfMetaurl(name); + } else if(strcmp(localname, "url") == 0) { + psm->setURLStateV4(); std::string location; { - std::vector::const_iterator itr = findAttr(attrs, LOCATION); + std::vector::const_iterator itr = + findAttr(attrs, "location", METALINK4_NAMESPACE_URI); if(itr != attrs.end()) { - location = (*itr).value; + location.assign((*itr).value, (*itr).valueLength); } } int priority; { - std::vector::const_iterator itr = findAttr(attrs, PRIORITY); + std::vector::const_iterator itr = + findAttr(attrs, "priority", METALINK4_NAMESPACE_URI); if(itr == attrs.end()) { priority = MetalinkResource::getLowestPriority(); } else { - try { - priority = util::parseInt((*itr).value.begin(), (*itr).value.end()); + if(util::parseIntNoThrow + (priority, (*itr).value, (*itr).value+(*itr).valueLength)) { if(priority < 1 || MetalinkResource::getLowestPriority() < priority) { - stm->logError("url@priority is out of range"); + psm->logError("url@priority is out of range"); return; } - } catch(RecoverableException& e) { - stm->logError("Bad url@priority"); + } else { + psm->logError("Bad url@priority"); return; } } } - stm->newResourceTransaction(); - stm->setLocationOfResource(location); - stm->setPriorityOfResource(priority); + psm->newResourceTransaction(); + psm->setLocationOfResource(location); + psm->setPriorityOfResource(priority); } #ifdef ENABLE_MESSAGE_DIGEST - else if(localname == HASH) { - stm->setHashStateV4(); - std::vector::const_iterator itr = findAttr(attrs, TYPE); - if(itr == attrs.end() || (*itr).value.empty()) { - stm->logError("Missing hash@type"); + else if(strcmp(localname, "hash") == 0) { + psm->setHashStateV4(); + std::vector::const_iterator itr = + findAttr(attrs, "type", METALINK4_NAMESPACE_URI); + if(itr == attrs.end() || (*itr).valueLength == 0) { + psm->logError("Missing hash@type"); return; } else { - std::string type = (*itr).value; - stm->newChecksumTransaction(); - stm->setTypeOfChecksum(type); + psm->newChecksumTransaction(); + psm->setTypeOfChecksum(std::string((*itr).value, (*itr).valueLength)); } - } else if(localname == PIECES) { - stm->setPiecesStateV4(); - size_t length; + } else if(strcmp(localname, "pieces") == 0) { + psm->setPiecesStateV4(); + int32_t length; { - std::vector::const_iterator itr = findAttr(attrs, LENGTH); - if(itr == attrs.end() || (*itr).value.empty()) { - stm->logError("Missing pieces@length"); + std::vector::const_iterator itr = + findAttr(attrs, "length", METALINK4_NAMESPACE_URI); + if(itr == attrs.end() || (*itr).valueLength == 0) { + psm->logError("Missing pieces@length"); + return; + } else if(!util::parseIntNoThrow + (length, (*itr).value, (*itr).value+(*itr).valueLength) || + length < 0) { + psm->logError("Bad pieces@length"); return; - } else { - try { - length = util::parseInt((*itr).value.begin(), (*itr).value.end()); - } catch(RecoverableException& e) { - stm->logError("Bad pieces@length"); - return; - } } } std::string type; { - std::vector::const_iterator itr = findAttr(attrs, TYPE); - if(itr == attrs.end() || (*itr).value.empty()) { - stm->logError("Missing pieces@type"); + std::vector::const_iterator itr = + findAttr(attrs, "type", METALINK4_NAMESPACE_URI); + if(itr == attrs.end() || (*itr).valueLength == 0) { + psm->logError("Missing pieces@type"); return; } else { - type = (*itr).value; + type.assign((*itr).value, (*itr).valueLength); } } - stm->newChunkChecksumTransactionV4(); - stm->setLengthOfChunkChecksumV4(length); - stm->setTypeOfChunkChecksumV4(type); + psm->newChunkChecksumTransactionV4(); + psm->setLengthOfChunkChecksumV4(length); + psm->setTypeOfChunkChecksumV4(type); } #endif // ENABLE_MESSAGE_DIGEST - else if(localname == SIGNATURE) { - stm->setSignatureStateV4(); - std::vector::const_iterator itr = findAttr(attrs, MEDIATYPE); - if(itr == attrs.end() || (*itr).value.empty()) { - stm->logError("Missing signature@mediatype"); + else if(strcmp(localname, "signature") == 0) { + psm->setSignatureStateV4(); + std::vector::const_iterator itr = + findAttr(attrs, "mediatype", METALINK4_NAMESPACE_URI); + if(itr == attrs.end() || (*itr).valueLength == 0) { + psm->logError("Missing signature@mediatype"); return; } - stm->newSignatureTransaction(); - stm->setTypeOfSignature((*itr).value); + psm->newSignatureTransaction(); + psm->setTypeOfSignature(std::string((*itr).value, (*itr).valueLength)); } else { - stm->setSkipTagState(); + psm->setSkipTagState(); } } void FileMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->commitEntryTransaction(); + psm->commitEntryTransaction(); } void SizeMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - try { - stm->setFileLengthOfEntry - (util::parseULLInt(characters.begin(), characters.end())); - } catch(RecoverableException& e) { - stm->cancelEntryTransaction(); - stm->logError("Bad size"); + int64_t size; + if(util::parseLLIntNoThrow(size, characters.begin(), characters.end()) && + size >= 0) { + psm->setFileLengthOfEntry(size); + } else { + psm->cancelEntryTransaction(); + psm->logError("Bad size"); } } void VersionMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setVersionOfEntry(characters); + psm->setVersionOfEntry(characters); } void LanguageMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setLanguageOfEntry(characters); + psm->setLanguageOfEntry(characters); } void OSMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setOSOfEntry(characters); + psm->setOSOfEntry(characters); } void HashMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setHashOfChecksum(characters); - stm->commitChecksumTransaction(); + psm->setHashOfChecksum(characters); + psm->commitChecksumTransaction(); } void PiecesMetalinkParserStateV4::beginElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs) { - if(nsUri == METALINK4_NAMESPACE_URI && localname == HASH) { - stm->setPieceHashStateV4(); + if(checkNsUri(nsUri) && strcmp(localname, "hash") == 0) { + psm->setPieceHashStateV4(); } else { - stm->setSkipTagState(); + psm->setSkipTagState(); } } void PiecesMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->commitChunkChecksumTransactionV4(); + psm->commitChunkChecksumTransactionV4(); } void PieceHashMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->addHashOfChunkChecksumV4(characters); + psm->addHashOfChunkChecksumV4(characters); } void SignatureMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setBodyOfSignature(characters); - stm->commitSignatureTransaction(); + psm->setBodyOfSignature(characters); + psm->commitSignatureTransaction(); } void URLMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setURLOfResource(characters); - stm->commitResourceTransaction(); + psm->setURLOfResource(characters); + psm->commitResourceTransaction(); } void MetaurlMetalinkParserStateV4::endElement -(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, +(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters) { - stm->setURLOfMetaurl(characters); - stm->commitMetaurlTransaction(); + psm->setURLOfMetaurl(characters); + psm->commitMetaurlTransaction(); } } // namespace aria2 diff --git a/src/MetalinkParserStateV4Impl.h b/src/MetalinkParserStateV4Impl.h index ff599ee8..81628f32 100644 --- a/src/MetalinkParserStateV4Impl.h +++ b/src/MetalinkParserStateV4Impl.h @@ -40,31 +40,31 @@ namespace aria2 { -extern const std::string METALINK4_NAMESPACE_URI; +extern const char METALINK4_NAMESPACE_URI[]; class MetalinkMetalinkParserStateV4:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); }; class FileMetalinkParserStateV4:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -76,10 +76,10 @@ public: class SizeMetalinkParserStateV4:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -91,10 +91,10 @@ public: class VersionMetalinkParserStateV4:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -106,10 +106,10 @@ public: class LanguageMetalinkParserStateV4:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -121,10 +121,10 @@ public: class OSMetalinkParserStateV4:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -136,10 +136,10 @@ public: class HashMetalinkParserStateV4:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -151,16 +151,16 @@ public: class PiecesMetalinkParserStateV4:public MetalinkParserState { public: - virtual void beginElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void beginElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::vector& attrs); - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -172,10 +172,10 @@ public: class PieceHashMetalinkParserStateV4:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -187,10 +187,10 @@ public: class SignatureMetalinkParserStateV4:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -202,10 +202,10 @@ public: class URLMetalinkParserStateV4:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const @@ -217,10 +217,10 @@ public: class MetaurlMetalinkParserStateV4:public SkipTagMetalinkParserState { public: - virtual void endElement(MetalinkParserStateMachine* stm, - const std::string& localname, - const std::string& prefix, - const std::string& nsUri, + virtual void endElement(MetalinkParserStateMachine* psm, + const char* localname, + const char* prefix, + const char* nsUri, const std::string& characters); virtual bool needsCharactersBuffering() const diff --git a/src/ParserStateMachine.h b/src/ParserStateMachine.h new file mode 100644 index 00000000..abd07b32 --- /dev/null +++ b/src/ParserStateMachine.h @@ -0,0 +1,70 @@ +/* */ +#ifndef D_PARSER_STATE_MACHINE_H +#define D_PARSER_STATE_MACHINE_H + +#include "common.h" + +#include +#include + +namespace aria2 { + +class XmlAttr; + +class ParserStateMachine { +public: + virtual ~ParserStateMachine() {} + + virtual bool needsCharactersBuffering() const = 0; + + virtual bool finished() const = 0; + + virtual void beginElement + (const char* localname, + const char* prefix, + const char* nsUri, + const std::vector& attrs) = 0; + + virtual void endElement + (const char* localname, + const char* prefix, + const char* nsUri, + const std::string& characters) = 0; +}; + +} // namespace aria2 + +#endif // D_PARSER_STATE_MACHINE_H diff --git a/src/XML2SAXMetalinkProcessor.cc b/src/Xml2XmlParser.cc similarity index 53% rename from src/XML2SAXMetalinkProcessor.cc rename to src/Xml2XmlParser.cc index 6aede789..2e357e6d 100644 --- a/src/XML2SAXMetalinkProcessor.cc +++ b/src/Xml2XmlParser.cc @@ -2,7 +2,7 @@ /* * aria2 - The high speed download utility * - * Copyright (C) 2006 Tatsuhiro Tsujikawa + * Copyright (C) 2011 Tatsuhiro Tsujikawa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,75 +32,70 @@ * files in the program, then also delete it here. */ /* copyright --> */ -#include "XML2SAXMetalinkProcessor.h" +#include "XmlParser.h" #include +#include +#include +#include + +#include "a2io.h" #include "BinaryStream.h" -#include "MetalinkParserStateMachine.h" -#include "Metalinker.h" -#include "MetalinkEntry.h" -#include "util.h" +#include "ParserStateMachine.h" #include "message.h" #include "DlAbortEx.h" #include "A2STR.h" -#include "error_code.h" +#include "a2functional.h" +#include "XmlAttr.h" namespace aria2 { namespace { -class SessionData { -public: - SharedHandle stm_; - +struct SessionData { std::deque charactersStack_; - - SessionData(const SharedHandle& stm):stm_(stm) {} + ParserStateMachine* psm_; + SessionData(ParserStateMachine* psm) + : psm_(psm) + {} }; } // namespace namespace { void mlStartElement (void* userData, - const xmlChar* srcLocalname, - const xmlChar* srcPrefix, - const xmlChar* srcNsUri, + const xmlChar* localname, + const xmlChar* prefix, + const xmlChar* nsUri, int numNamespaces, - const xmlChar **namespaces, + const xmlChar** namespaces, int numAttrs, int numDefaulted, - const xmlChar **attrs) + const xmlChar** attrs) { SessionData* sd = reinterpret_cast(userData); std::vector xmlAttrs; - size_t index = 0; - for(int attrIndex = 0; attrIndex < numAttrs; ++attrIndex, index += 5) { + const char** pattrs = reinterpret_cast(attrs); + for(size_t i = 0, max = numAttrs*5; i < max; i += 5) { XmlAttr xmlAttr; - assert(attrs[index]); - xmlAttr.localname = reinterpret_cast(attrs[index]); - if(attrs[index+1]) { - xmlAttr.prefix = reinterpret_cast(attrs[index+1]); + assert(pattrs[i]); + xmlAttr.localname = pattrs[i]; + if(pattrs[i+1]) { + xmlAttr.prefix = pattrs[i+1]; } - if(attrs[index+2]) { - xmlAttr.nsUri = reinterpret_cast(attrs[index+2]); + if(attrs[i+2]) { + xmlAttr.nsUri = pattrs[i+2]; } - const char* valueBegin = reinterpret_cast(attrs[index+3]); - const char* valueEnd = reinterpret_cast(attrs[index+4]); - xmlAttr.value.assign(valueBegin, valueEnd); + xmlAttr.value = pattrs[i+3]; + xmlAttr.valueLength = pattrs[i+4]-xmlAttr.value; xmlAttrs.push_back(xmlAttr); } - assert(srcLocalname); - std::string localname = reinterpret_cast(srcLocalname); - std::string prefix; - std::string nsUri; - if(srcPrefix) { - prefix = reinterpret_cast(srcPrefix); - } - if(srcNsUri) { - nsUri = reinterpret_cast(srcNsUri); - } - sd->stm_->beginElement(localname, prefix, nsUri, xmlAttrs); - if(sd->stm_->needsCharactersBuffering()) { + sd->psm_->beginElement + (reinterpret_cast(localname), + reinterpret_cast(prefix), + reinterpret_cast(nsUri), + xmlAttrs); + if(sd->psm_->needsCharactersBuffering()) { sd->charactersStack_.push_front(A2STR::NIL); } } @@ -109,26 +104,21 @@ void mlStartElement namespace { void mlEndElement (void* userData, - const xmlChar* srcLocalname, - const xmlChar* srcPrefix, - const xmlChar* srcNsUri) + const xmlChar* localname, + const xmlChar* prefix, + const xmlChar* nsUri) { SessionData* sd = reinterpret_cast(userData); std::string characters; - if(sd->stm_->needsCharactersBuffering()) { + if(sd->psm_->needsCharactersBuffering()) { characters = sd->charactersStack_.front(); sd->charactersStack_.pop_front(); } - std::string localname = reinterpret_cast(srcLocalname); - std::string prefix; - std::string nsUri; - if(srcPrefix) { - prefix = reinterpret_cast(srcPrefix); - } - if(srcNsUri) { - nsUri = reinterpret_cast(srcNsUri); - } - sd->stm_->endElement(localname, prefix, nsUri, characters); + sd->psm_->endElement + (reinterpret_cast(localname), + reinterpret_cast(prefix), + reinterpret_cast(nsUri), + characters); } } // namespace @@ -136,7 +126,7 @@ namespace { void mlCharacters(void* userData, const xmlChar* ch, int len) { SessionData* sd = reinterpret_cast(userData); - if(sd->stm_->needsCharactersBuffering()) { + if(sd->psm_->needsCharactersBuffering()) { sd->charactersStack_.front().append(&ch[0], &ch[len]); } } @@ -180,89 +170,62 @@ xmlSAXHandler mySAXHandler = }; } // namespace -MetalinkProcessor::MetalinkProcessor() {} +XmlParser::XmlParser(ParserStateMachine* psm) + : psm_(psm) +{} -MetalinkProcessor::~MetalinkProcessor() {} +XmlParser::~XmlParser() {} -SharedHandle -MetalinkProcessor::parseFile -(const std::string& filename, - const std::string& baseUri) +bool XmlParser::parseFile(const char* filename) { - stm_.reset(new MetalinkParserStateMachine()); - stm_->setBaseUri(baseUri); - SharedHandle sessionData(new SessionData(stm_)); + SessionData sessionData(psm_); // Old libxml2(at least 2.7.6, Ubuntu 10.04LTS) does not read stdin // when "/dev/stdin" is passed as filename while 2.7.7 does. So we // convert DEV_STDIN to "-" for compatibility. - std::string nfilename; - if(filename == DEV_STDIN) { + const char* nfilename; + if(strcmp(filename, DEV_STDIN) == 0) { nfilename = "-"; } else { nfilename = filename; } - int retval = xmlSAXUserParseFile(&mySAXHandler, sessionData.get(), - nfilename.c_str()); - if(retval != 0) { - throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK, - error_code::METALINK_PARSE_ERROR); - } - if(!stm_->finished()) { - throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK, - error_code::METALINK_PARSE_ERROR); - } - if(!stm_->getErrors().empty()) { - throw DL_ABORT_EX2(stm_->getErrorString(), - error_code::METALINK_PARSE_ERROR); - } - return stm_->getResult(); + int r = xmlSAXUserParseFile(&mySAXHandler, &sessionData, nfilename); + return r == 0 && psm_->finished(); } - -SharedHandle -MetalinkProcessor::parseFromBinaryStream -(const SharedHandle& binaryStream, - const std::string& baseUri) + +bool XmlParser::parseBinaryStream(BinaryStream* bs) { - stm_.reset(new MetalinkParserStateMachine()); - stm_->setBaseUri(baseUri); - size_t bufSize = 4096; + const size_t bufSize = 4096; unsigned char buf[bufSize]; - - ssize_t res = binaryStream->readData(buf, 4, 0); + ssize_t res = bs->readData(buf, 4, 0); if(res != 4) { - throw DL_ABORT_EX2("Too small data for parsing XML.", - error_code::METALINK_PARSE_ERROR); + return false; } - - SharedHandle sessionData(new SessionData(stm_)); + SessionData sessionData(psm_); xmlParserCtxtPtr ctx = xmlCreatePushParserCtxt - (&mySAXHandler, sessionData.get(), + (&mySAXHandler, &sessionData, reinterpret_cast(buf), res, 0); auto_delete deleter(ctx, xmlFreeParserCtxt); - off_t readOffset = res; while(1) { - ssize_t res = binaryStream->readData(buf, bufSize, readOffset); + ssize_t res = bs->readData(buf, bufSize, readOffset); if(res == 0) { break; } if(xmlParseChunk(ctx, reinterpret_cast(buf), res, 0) != 0) { - throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK, - error_code::METALINK_PARSE_ERROR); + // TODO we need this? Just break is not suffice? + return false; } readOffset += res; } xmlParseChunk(ctx, reinterpret_cast(buf), 0, 1); + return psm_->finished(); +} - if(!stm_->finished()) { - throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK, - error_code::METALINK_PARSE_ERROR); - } - if(!stm_->getErrors().empty()) { - throw DL_ABORT_EX2(stm_->getErrorString(), - error_code::METALINK_PARSE_ERROR); - } - return stm_->getResult(); +bool XmlParser::parseMemory(const char* xml, size_t len) +{ + SessionData sessionData(psm_); + int r = xmlSAXUserParseMemory(&mySAXHandler, &sessionData, xml, len); + return r == 0 && psm_->finished(); } } // namespace aria2 diff --git a/src/XML2SAXMetalinkProcessor.h b/src/Xml2XmlParser.h similarity index 69% rename from src/XML2SAXMetalinkProcessor.h rename to src/Xml2XmlParser.h index 652a1bbf..66cc1a8b 100644 --- a/src/XML2SAXMetalinkProcessor.h +++ b/src/Xml2XmlParser.h @@ -2,7 +2,7 @@ /* * aria2 - The high speed download utility * - * Copyright (C) 2006 Tatsuhiro Tsujikawa + * Copyright (C) 2011 Tatsuhiro Tsujikawa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,42 +32,30 @@ * files in the program, then also delete it here. */ /* copyright --> */ -#ifndef D_XML2_SAX_METALINK_PROCESSOR_H -#define D_XML2_SAX_METALINK_PROCESSOR_H +#ifndef D_XML2_XML_PARSER_H +#define D_XML2_XML_PARSER_H #include "common.h" -#include - -#include -#include - -#include "SharedHandle.h" -#include "A2STR.h" +#include namespace aria2 { -class Metalinker; class BinaryStream; -class MetalinkParserStateMachine; +class ParserStateMachine; -class MetalinkProcessor { -private: - SharedHandle stm_; +class XmlParser { public: - MetalinkProcessor(); - - ~MetalinkProcessor(); - - SharedHandle parseFile - (const std::string& filename, - const std::string& baseUri = A2STR::NIL); - - SharedHandle parseFromBinaryStream - (const SharedHandle& binaryStream, - const std::string& baseUri = A2STR::NIL); + // This object does not delete psm. + XmlParser(ParserStateMachine* psm); + ~XmlParser(); + bool parseFile(const char* filename); + bool parseBinaryStream(BinaryStream* binaryStream); + bool parseMemory(const char* xml, size_t size); +private: + ParserStateMachine* psm_; }; } // namespace aria2 -#endif // D_XML2_SAX_METALINK_PROCESSOR_H +#endif // D_XML2_XML_PARSER_H diff --git a/src/XmlAttr.cc b/src/XmlAttr.cc new file mode 100644 index 00000000..404ebd1e --- /dev/null +++ b/src/XmlAttr.cc @@ -0,0 +1,47 @@ +/* */ +#include "XmlAttr.h" + +namespace aria2 { + +XmlAttr::XmlAttr() + : localname(0), + prefix(0), + nsUri(0), + value(0), + valueLength(0) +{} + +} // namespace aria2 diff --git a/src/XmlAttr.h b/src/XmlAttr.h new file mode 100644 index 00000000..b367ce60 --- /dev/null +++ b/src/XmlAttr.h @@ -0,0 +1,59 @@ +/* */ +#ifndef D_XML_ATTR_H +#define D_XML_ATTR_H + +#include "common.h" + +#include + +namespace aria2 { + +struct XmlAttr { + const char* localname; + const char* prefix; + const char* nsUri; + const char* value; + size_t valueLength; + + XmlAttr(); + // XmlAttr(const XmlAttr& attr); + // ~XmlAttr(); + // XmlAttr& operator=(const XmlAttr&); +}; + +} // namespace aria2 + +#endif // D_XML_ATTR_H diff --git a/src/MetalinkProcessor.h b/src/XmlParser.h similarity index 88% rename from src/MetalinkProcessor.h rename to src/XmlParser.h index bed699f5..44d68e51 100644 --- a/src/MetalinkProcessor.h +++ b/src/XmlParser.h @@ -2,7 +2,7 @@ /* * aria2 - The high speed download utility * - * Copyright (C) 2006 Tatsuhiro Tsujikawa + * Copyright (C) 2011 Tatsuhiro Tsujikawa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,15 +32,15 @@ * files in the program, then also delete it here. */ /* copyright --> */ -#ifndef D_METALINK_PROCESSOR_H -#define D_METALINK_PROCESSOR_H +#ifndef D_XML_PARSER_H +#define D_XML_PARSER_H #include "common.h" #ifdef HAVE_LIBXML2 -# include "XML2SAXMetalinkProcessor.h" +# include "Xml2XmlParser.h" #elif HAVE_LIBEXPAT -# include "ExpatMetalinkProcessor.h" +# include "Expat2XmlParser.h" #endif -#endif // D_METALINK_PROCESSOR_H +#endif // D_XML_PARSER_H diff --git a/src/metalink_helper.cc b/src/metalink_helper.cc index f0425592..8ac10d59 100644 --- a/src/metalink_helper.cc +++ b/src/metalink_helper.cc @@ -37,7 +37,7 @@ #include "MetalinkEntry.h" #include "MetalinkParserStateMachine.h" #include "Metalinker.h" -#include "MetalinkProcessor.h" +#include "XmlParser.h" #include "prefs.h" #include "DlAbortEx.h" #include "BinaryStream.h" @@ -68,20 +68,17 @@ void parseAndQuery const Option* option, const std::string& baseUri) { - MetalinkProcessor proc; - SharedHandle metalinker = proc.parseFile(filename, baseUri); + SharedHandle metalinker = parseFile(filename, baseUri); query(result, metalinker, option); } void parseAndQuery (std::vector >& result, - const SharedHandle& binaryStream, + BinaryStream* bs, const Option* option, const std::string& baseUri) { - MetalinkProcessor proc; - SharedHandle metalinker = - proc.parseFromBinaryStream(binaryStream, baseUri); + SharedHandle metalinker = parseBinaryStream(bs, baseUri); query(result, metalinker, option); } @@ -122,6 +119,40 @@ void groupEntryByMetaurlName } } +SharedHandle parseFile +(const std::string& filename, + const std::string& baseUri) +{ + MetalinkParserStateMachine psm; + psm.setBaseUri(baseUri); + if(!XmlParser(&psm).parseFile(filename.c_str())) { + 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); + if(!XmlParser(&psm).parseBinaryStream(bs)) { + 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 diff --git a/src/metalink_helper.h b/src/metalink_helper.h index 8ff7f060..f07752bd 100644 --- a/src/metalink_helper.h +++ b/src/metalink_helper.h @@ -60,7 +60,7 @@ void parseAndQuery void parseAndQuery (std::vector >& result, - const SharedHandle& binaryStream, + BinaryStream* bs, const Option* option, const std::string& baseUri = A2STR::NIL); @@ -69,6 +69,14 @@ void groupEntryByMetaurlName std::pair > > >& result, const std::vector >& entries); +SharedHandle parseFile +(const std::string& filename, + const std::string& baseUri = A2STR::NIL); + +SharedHandle parseBinaryStream +(BinaryStream* bs, + const std::string& baseUri = A2STR::NIL); + } // namespace metalink } // namespace aria2 diff --git a/test/MetalinkProcessorTest.cc b/test/MetalinkProcessorTest.cc index 8dd2d10b..ee5247f8 100644 --- a/test/MetalinkProcessorTest.cc +++ b/test/MetalinkProcessorTest.cc @@ -21,6 +21,7 @@ #include "fmt.h" #include "RecoverableException.h" #include "util.h" +#include "metalink_helper.h" namespace aria2 { @@ -31,7 +32,7 @@ class MetalinkProcessorTest:public CppUnit::TestFixture { CPPUNIT_TEST(testParseFileV4_attrs); CPPUNIT_TEST(testParseFile); CPPUNIT_TEST(testParseFile_dirtraversal); - CPPUNIT_TEST(testParseFromBinaryStream); + CPPUNIT_TEST(testParseBinaryStream); CPPUNIT_TEST(testMalformedXML); CPPUNIT_TEST(testMalformedXML2); CPPUNIT_TEST(testBadSize); @@ -57,7 +58,7 @@ public: void testParseFileV4_attrs(); void testParseFile(); void testParseFile_dirtraversal(); - void testParseFromBinaryStream(); + void testParseBinaryStream(); void testMalformedXML(); void testMalformedXML2(); void testBadSize(); @@ -82,8 +83,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION( MetalinkProcessorTest ); void MetalinkProcessorTest::testParseFileV4() { - MetalinkProcessor proc; - SharedHandle m = proc.parseFile(A2_TEST_DIR"/metalink4.xml"); + SharedHandle m = metalink::parseFile(A2_TEST_DIR"/metalink4.xml"); SharedHandle e; SharedHandle r; SharedHandle mu; @@ -152,9 +152,8 @@ void MetalinkProcessorTest::testParseFileV4() void MetalinkProcessorTest::testParseFileV4_attrs() { - MetalinkProcessor proc; SharedHandle m; - SharedHandle dw(new ByteArrayDiskWriter()); + ByteArrayDiskWriter dw; { // Testing file@name const char* tmpl = "" @@ -163,27 +162,27 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "http://example.org" "" ""; - dw->setString(fmt(tmpl, "foo")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "foo")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); // empty name - dw->setString(fmt(tmpl, "")); + dw.setString(fmt(tmpl, "")); try { - m = proc.parseFromBinaryStream(dw); + metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) { // success } // dir traversing - dw->setString(fmt(tmpl, "../doughnuts")); - try { - m = proc.parseFromBinaryStream(dw); - CPPUNIT_FAIL("exception must be thrown."); - } catch(RecoverableException& e) { - // success - } + dw.setString(fmt(tmpl, "../doughnuts")); + try { + m = metalink::parseBinaryStream(&dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } } { // Testing url@priority @@ -193,36 +192,36 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "http://example.org" "" ""; - dw->setString(fmt(tmpl, "0")); + dw.setString(fmt(tmpl, "0")); try { - m = proc.parseFromBinaryStream(dw); + metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) { // success } - dw->setString(fmt(tmpl, "1")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "1")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); - dw->setString(fmt(tmpl, "100")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "100")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); - dw->setString(fmt(tmpl, "999999")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "999999")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); - dw->setString(fmt(tmpl, "1000000")); + dw.setString(fmt(tmpl, "1000000")); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) { // success } - dw->setString(fmt(tmpl, "A")); + dw.setString(fmt(tmpl, "A")); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} } @@ -235,36 +234,36 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "http://example.org" "" ""; - dw->setString(fmt(tmpl, "0")); + dw.setString(fmt(tmpl, "0")); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) { // success } - dw->setString(fmt(tmpl, "1")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "1")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); - dw->setString(fmt(tmpl, "100")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "100")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); - dw->setString(fmt(tmpl, "999999")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "999999")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); - dw->setString(fmt(tmpl, "1000000")); + dw.setString(fmt(tmpl, "1000000")); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) { // success } - dw->setString(fmt(tmpl, "A")); + dw.setString(fmt(tmpl, "A")); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} } @@ -272,14 +271,14 @@ void MetalinkProcessorTest::testParseFileV4_attrs() // Testing metaurl@mediatype // no mediatype - dw->setString("" + dw.setString("" "" "" "http://example.org" "" ""); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) { // success @@ -293,14 +292,14 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""; - dw->setString(fmt(tmpl, "torrent")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "torrent")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); // empty mediatype - dw->setString(fmt(tmpl, "")); + dw.setString(fmt(tmpl, "")); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) { // success @@ -316,22 +315,22 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""; - dw->setString(fmt(tmpl, "foo")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "foo")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); // dir traversing - dw->setString(fmt(tmpl, "../doughnuts")); + dw.setString(fmt(tmpl, "../doughnuts")); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) { // success } // empty name - dw->setString(fmt(tmpl, "")); + dw.setString(fmt(tmpl, "")); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) { // success @@ -341,7 +340,7 @@ void MetalinkProcessorTest::testParseFileV4_attrs() { // Testing pieces@length // No pieces@length - dw->setString + dw.setString ("" "" "" @@ -352,7 +351,7 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} @@ -367,25 +366,25 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""; - dw->setString(fmt(tmpl, "262144")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "262144")); + m = metalink::parseBinaryStream(&dw); // empty try { - dw->setString(fmt(tmpl, "")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} // not a number try { - dw->setString(fmt(tmpl, "A")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "A")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} } { // Testing pieces@type // No pieces@type - dw->setString + dw.setString ("" "" "" @@ -396,7 +395,7 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} @@ -411,19 +410,19 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""; - dw->setString(fmt(tmpl, "sha-1")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "sha-1")); + m = metalink::parseBinaryStream(&dw); // empty try { - dw->setString(fmt(tmpl, "")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} } { // Testing hash@type // No hash@type - dw->setString + dw.setString ("" "" "" @@ -432,7 +431,7 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} @@ -445,12 +444,12 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""; - dw->setString(fmt(tmpl, "sha-1")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "sha-1")); + m = metalink::parseBinaryStream(&dw); // empty try { - dw->setString(fmt(tmpl, "")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} } @@ -458,7 +457,7 @@ void MetalinkProcessorTest::testParseFileV4_attrs() { // Testing signature@mediatype // No hash@type - dw->setString + dw.setString ("" "" "" @@ -467,7 +466,7 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} @@ -480,12 +479,12 @@ void MetalinkProcessorTest::testParseFileV4_attrs() "" ""; - dw->setString(fmt(tmpl, "application/pgp-signature")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "application/pgp-signature")); + m = metalink::parseBinaryStream(&dw); // empty try { - dw->setString(fmt(tmpl, "")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "")); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} } @@ -493,9 +492,9 @@ void MetalinkProcessorTest::testParseFileV4_attrs() void MetalinkProcessorTest::testParseFile() { - MetalinkProcessor proc; try { - SharedHandle metalinker = proc.parseFile(A2_TEST_DIR"/test.xml"); + SharedHandle metalinker = + metalink::parseFile(A2_TEST_DIR"/test.xml"); std::vector >::const_iterator entryItr = metalinker->getEntries().begin(); @@ -516,16 +515,17 @@ void MetalinkProcessorTest::testParseFile() CPPUNIT_ASSERT_EQUAL(std::string("pgp"), entry1->getSignature()->getType()); CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2.sig"), entry1->getSignature()->getFile()); - // Note that last '\n' character is trimmed. + // Note that we don't strip anything CPPUNIT_ASSERT_EQUAL (std::string - ("-----BEGIN PGP SIGNATURE-----\n" + ("\n-----BEGIN PGP SIGNATURE-----\n" "Version: GnuPG v1.4.9 (GNU/Linux)\n" "\n" "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" "ffffffffffffffffffffffff\n" "fffff\n" - "-----END PGP SIGNATURE-----"), + "-----END PGP SIGNATURE-----\n" + "\t"), entry1->getSignature()->getBody()); std::vector >::iterator resourceItr1 = @@ -600,9 +600,8 @@ void MetalinkProcessorTest::testParseFile() void MetalinkProcessorTest::testParseFile_dirtraversal() { - MetalinkProcessor proc; SharedHandle metalinker = - proc.parseFile(A2_TEST_DIR"/metalink3-dirtraversal.xml"); + metalink::parseFile(A2_TEST_DIR"/metalink3-dirtraversal.xml"); CPPUNIT_ASSERT_EQUAL((size_t)1, metalinker->getEntries().size()); SharedHandle e = metalinker->getEntries()[0]; CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.3.tar.bz2"), e->getPath()); @@ -610,15 +609,14 @@ void MetalinkProcessorTest::testParseFile_dirtraversal() CPPUNIT_ASSERT_EQUAL(std::string(""), e->getSignature()->getFile()); } -void MetalinkProcessorTest::testParseFromBinaryStream() +void MetalinkProcessorTest::testParseBinaryStream() { - MetalinkProcessor proc; - DefaultDiskWriterHandle dw(new DefaultDiskWriter(A2_TEST_DIR"/test.xml")); - dw->enableReadOnly(); - dw->openExistingFile(); + DefaultDiskWriter dw(A2_TEST_DIR"/test.xml"); + dw.enableReadOnly(); + dw.openExistingFile(); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); std::vector >::const_iterator entryItr = m->getEntries().begin(); @@ -631,12 +629,11 @@ void MetalinkProcessorTest::testParseFromBinaryStream() void MetalinkProcessorTest::testMalformedXML() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString(""); + ByteArrayDiskWriter dw; + dw.setString(""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(Exception& e) { std::cerr << e.stackTrace() << std::endl; @@ -645,12 +642,11 @@ void MetalinkProcessorTest::testMalformedXML() void MetalinkProcessorTest::testMalformedXML2() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString(""); + ByteArrayDiskWriter dw; + dw.setString(""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(Exception& e) { std::cerr << e.stackTrace() << std::endl; @@ -659,9 +655,8 @@ void MetalinkProcessorTest::testMalformedXML2() void MetalinkProcessorTest::testBadSizeV4() { - MetalinkProcessor proc; SharedHandle m; - SharedHandle dw(new ByteArrayDiskWriter()); + ByteArrayDiskWriter dw; const char* tmpl = "" @@ -672,21 +667,20 @@ void MetalinkProcessorTest::testBadSizeV4() "" ""; - dw->setString(fmt(tmpl, "9223372036854775807")); - m = proc.parseFromBinaryStream(dw); + dw.setString(fmt(tmpl, "9223372036854775807")); + m = metalink::parseBinaryStream(&dw); - dw->setString(fmt(tmpl, "-1")); + dw.setString(fmt(tmpl, "-1")); try { - m = proc.parseFromBinaryStream(dw); + m = metalink::parseBinaryStream(&dw); CPPUNIT_FAIL("exception must be thrown."); } catch(RecoverableException& e) {} } void MetalinkProcessorTest::testBadSize() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString("" + ByteArrayDiskWriter dw; + dw.setString("" "" "" " abc" @@ -698,7 +692,7 @@ void MetalinkProcessorTest::testBadSize() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); std::vector >::const_iterator entryItr = m->getEntries().begin(); @@ -716,9 +710,8 @@ void MetalinkProcessorTest::testBadSize() void MetalinkProcessorTest::testBadMaxConn() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString("" + ByteArrayDiskWriter dw; + dw.setString("" "" "" " 43743838" @@ -731,7 +724,7 @@ void MetalinkProcessorTest::testBadMaxConn() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); std::vector >::const_iterator entryItr = m->getEntries().begin(); @@ -744,9 +737,8 @@ void MetalinkProcessorTest::testBadMaxConn() void MetalinkProcessorTest::testNoName() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString("" + ByteArrayDiskWriter dw; + dw.setString("" "" "" " 1024" @@ -764,7 +756,7 @@ void MetalinkProcessorTest::testNoName() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); std::vector >::const_iterator entryItr = m->getEntries().begin(); @@ -777,9 +769,8 @@ void MetalinkProcessorTest::testNoName() void MetalinkProcessorTest::testBadURLPrefs() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString("" + ByteArrayDiskWriter dw; + dw.setString("" "" "" " 43743838" @@ -795,7 +786,7 @@ void MetalinkProcessorTest::testBadURLPrefs() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); SharedHandle e = m->getEntries()[0]; SharedHandle r = e->resources[0]; CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r->type); @@ -809,9 +800,8 @@ void MetalinkProcessorTest::testBadURLPrefs() void MetalinkProcessorTest::testBadURLMaxConn() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString("" + ByteArrayDiskWriter dw; + dw.setString("" "" "" " 43743838" @@ -828,7 +818,7 @@ void MetalinkProcessorTest::testBadURLMaxConn() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); SharedHandle e = m->getEntries()[0]; SharedHandle r = e->resources[0]; CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r->type); @@ -843,9 +833,8 @@ void MetalinkProcessorTest::testBadURLMaxConn() #ifdef ENABLE_MESSAGE_DIGEST void MetalinkProcessorTest::testUnsupportedType() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString("" + ByteArrayDiskWriter dw; + dw.setString("" "" "" " 43743838" @@ -862,7 +851,7 @@ void MetalinkProcessorTest::testUnsupportedType() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); SharedHandle e = m->getEntries()[0]; CPPUNIT_ASSERT_EQUAL((size_t)3, e->resources.size()); SharedHandle r1 = e->resources[0]; @@ -878,9 +867,8 @@ void MetalinkProcessorTest::testUnsupportedType() void MetalinkProcessorTest::testMultiplePieces() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString("" + ByteArrayDiskWriter dw; + dw.setString("" "" "" " " @@ -895,7 +883,7 @@ void MetalinkProcessorTest::testMultiplePieces() try { // aria2 prefers sha1 - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); SharedHandle e = m->getEntries()[0]; SharedHandle c = e->chunkChecksum; @@ -908,9 +896,8 @@ void MetalinkProcessorTest::testMultiplePieces() void MetalinkProcessorTest::testBadPieceNo() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString + ByteArrayDiskWriter dw; + dw.setString ("" "" "" @@ -928,7 +915,7 @@ void MetalinkProcessorTest::testBadPieceNo() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); SharedHandle e = m->getEntries()[0]; SharedHandle c = e->chunkChecksum; @@ -942,9 +929,8 @@ void MetalinkProcessorTest::testBadPieceNo() void MetalinkProcessorTest::testBadPieceLength() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString + ByteArrayDiskWriter dw; + dw.setString ("" "" "" @@ -961,7 +947,7 @@ void MetalinkProcessorTest::testBadPieceLength() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); SharedHandle e = m->getEntries()[0]; SharedHandle c = e->chunkChecksum; @@ -975,9 +961,8 @@ void MetalinkProcessorTest::testBadPieceLength() void MetalinkProcessorTest::testUnsupportedType_piece() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString + ByteArrayDiskWriter dw; + dw.setString ("" "" "" @@ -994,7 +979,7 @@ void MetalinkProcessorTest::testUnsupportedType_piece() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); SharedHandle e = m->getEntries()[0]; SharedHandle c = e->chunkChecksum; @@ -1009,21 +994,20 @@ void MetalinkProcessorTest::testUnsupportedType_piece() void MetalinkProcessorTest::testLargeFileSize() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString("" - "" - "" - " 9223372036854775807" - " " - " ftp://mirror/" - " " - "" - "" - ""); - + ByteArrayDiskWriter dw; + dw.setString + ("" + "" + "" + " 9223372036854775807" + " " + " ftp://mirror/" + " " + "" + "" + ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); SharedHandle e = m->getEntries()[0]; CPPUNIT_ASSERT_EQUAL((uint64_t)9223372036854775807ULL, e->getLength()); } catch(Exception& e) { @@ -1033,9 +1017,8 @@ void MetalinkProcessorTest::testLargeFileSize() void MetalinkProcessorTest::testXmlPrefixV3() { - MetalinkProcessor proc; - SharedHandle dw(new ByteArrayDiskWriter()); - dw->setString("" + ByteArrayDiskWriter dw; + dw.setString("" "" "" " 9223372036854775807" @@ -1047,7 +1030,7 @@ void MetalinkProcessorTest::testXmlPrefixV3() ""); try { - SharedHandle m = proc.parseFromBinaryStream(dw); + SharedHandle m = metalink::parseBinaryStream(&dw); CPPUNIT_ASSERT_EQUAL((size_t)1, m->getEntries().size()); SharedHandle e = m->getEntries()[0]; CPPUNIT_ASSERT_EQUAL((uint64_t)9223372036854775807ULL, e->getLength());