diff --git a/XML/include/Poco/XML/QName.h b/XML/include/Poco/XML/QName.h index 8602915d4..2e332800b 100644 --- a/XML/include/Poco/XML/QName.h +++ b/XML/include/Poco/XML/QName.h @@ -23,49 +23,35 @@ namespace XML class XML_API QName { public: - QName() - { - } - QName(const std::string& name) : - name_(name) - { - } - QName(const std::string& ns, const std::string& name) : - ns_(ns), - name_(name) - { - } - QName(const std::string& ns, const std::string& name, const std::string& prefix) : - ns_(ns), - name_(name), - prefix_(prefix) - { - } + QName(); + QName(const std::string& name); + QName(const std::string& ns, const std::string& name); + QName(const std::string& ns, const std::string& name, const std::string& prefix); const std::string& namespace_() const { - return ns_; + return _ns; } const std::string& name() const { - return name_; + return _name; } const std::string& prefix() const { - return prefix_; + return _prefix; } std::string& namespace_() { - return ns_; + return _ns; } std::string& name() { - return name_; + return _name; } std::string& prefix() { - return prefix_; + return _prefix; } // Printable representation in the [#] form. @@ -77,12 +63,12 @@ public: public: friend bool operator<(const QName& x, const QName& y) { - return x.ns_ < y.ns_ || (x.ns_ == y.ns_ && x.name_ < y.name_); + return x._ns < y._ns || (x._ns == y._ns && x._name < y._name); } friend bool operator==(const QName& x, const QName& y) { - return x.ns_ == y.ns_ && x.name_ == y.name_; + return x._ns == y._ns && x._name == y._name; } friend bool operator!=(const QName& x, const QName& y) @@ -91,9 +77,9 @@ public: } private: - std::string ns_; - std::string name_; - std::string prefix_; + std::string _ns; + std::string _name; + std::string _prefix; }; XML_API std::ostream& operator<<(std::ostream&, const QName&); diff --git a/XML/include/Poco/XML/XMLStreamParser.h b/XML/include/Poco/XML/XMLStreamParser.h index 37dd9b394..23700fe4d 100644 --- a/XML/include/Poco/XML/XMLStreamParser.h +++ b/XML/include/Poco/XML/XMLStreamParser.h @@ -2,8 +2,8 @@ // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file -#ifndef POCO_XML_PARSER_HXX -#define POCO_XML_PARSER_HXX +#ifndef POCO_XML_XMLSTREAMPARSER_H +#define POCO_XML_XMLSTREAMPARSER_H // We only support UTF-8 expat. // @@ -31,6 +31,21 @@ namespace XML class XML_API XMLStreamParser { public: + /// Parsing events. + enum EventType + { + // If adding new events, also update the stream insertion operator. + // + StartElement, + EndElement, + StartAttribute, + EndAttribute, + Characters, + StartNamespaceDecl, + EndNamespaceDecl, + Eof + }; + typedef unsigned short FeatureType; // If both receive_attributes_event and receive_attributes_map are @@ -58,28 +73,8 @@ public: // XMLStreamParser(const void* data, std::size_t size, const std::string& input_name, FeatureType = RECEIVE_DEFAULT); - const std::string& input_name() const - { - return iname_; - } - ~XMLStreamParser(); - /// Parsing events. - enum EventType - { - // If adding new events, also update the stream insertion operator. - // - StartElement, - EndElement, - StartAttribute, - EndAttribute, - Characters, - StartNamespaceDecl, - EndNamespaceDecl, - Eof - }; - EventType next(); // Get the next event and make sure that it's what's expected. If it @@ -103,6 +98,11 @@ public: return event_; } + const std::string& inputName() const + { + return iname_; + } + // Event data. // const QName& qname() const @@ -160,8 +160,7 @@ public: // the map is still valid after peek() that returned end_element until // this end_element event is retrieved with next(). // - const std::string& - attribute(const std::string& name) const; + const std::string& attribute(const std::string& name) const; template T attribute(const std::string& name) const; @@ -316,7 +315,8 @@ private: { std::istream* is; const void* buf; - }data_; + } + data_; std::size_t size_; @@ -329,7 +329,8 @@ private: enum { state_next, state_peek - }state_; + } + state_; EventType event_; EventType queue_; @@ -399,7 +400,7 @@ private: const ElementEntry* get_element_() const; - void pop_element(); + void popElement(); }; XML_API std::ostream& operator<<(std::ostream&, XMLStreamParser::EventType); @@ -608,6 +609,7 @@ T XMLStreamParser::element(const QName& qn, const T& dv) return dv; } + } } diff --git a/XML/include/Poco/XML/XMLStreamParserException.h b/XML/include/Poco/XML/XMLStreamParserException.h index a7816d6a1..4584ff29e 100644 --- a/XML/include/Poco/XML/XMLStreamParserException.h +++ b/XML/include/Poco/XML/XMLStreamParserException.h @@ -31,36 +31,20 @@ public: virtual ~XMLStreamParserException() throw (); - const char* name() const throw() - { - return name_.c_str(); - } - - Poco::UInt64 line() const - { - return line_; - } - - Poco::UInt64 column() const - { - return column_; - } - - const std::string& description() const - { - return description_; - } - + const char* name() const throw(); + Poco::UInt64 line() const; + Poco::UInt64 column() const; + const std::string& description() const; virtual const char* what() const throw (); private: void init(); - std::string name_; - Poco::UInt64 line_; - Poco::UInt64 column_; - std::string description_; - std::string what_; + std::string _name; + Poco::UInt64 _line; + Poco::UInt64 _column; + std::string _description; + std::string _what; }; } diff --git a/XML/include/Poco/XML/XMLStreamSerializer.h b/XML/include/Poco/XML/XMLStreamSerializer.h index 84221cfb3..edda1d200 100644 --- a/XML/include/Poco/XML/XMLStreamSerializer.h +++ b/XML/include/Poco/XML/XMLStreamSerializer.h @@ -2,8 +2,8 @@ // copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file -#ifndef POCO_XML_XMLSERIALIZER -#define POCO_XML_XMLSERIALIZER +#ifndef POCO_XML_XMLSERIALIZER_H +#define POCO_XML_XMLSERIALIZER_H #include "QName.h" #include "ValueTraits.h" @@ -17,7 +17,6 @@ namespace Poco { namespace XML { -class XMLStreamSerializer; class XML_API XMLStreamSerializer { @@ -32,13 +31,13 @@ public: // Otherwise, those are reported as the XMLStreamSerializerException exception. // XMLStreamSerializer(std::ostream&, const std::string& output_name, unsigned short indentation = 2); + ~XMLStreamSerializer(); const std::string& outputName() const { - return oname_; + return _oname; } - ~XMLStreamSerializer(); void startElement(const QName& qname); @@ -128,13 +127,13 @@ private: void handleError(genxStatus); - std::ostream& os_; - std::ostream::iostate os_state_;// Original exception state. - const std::string oname_; + std::ostream& _outputStream; + std::ostream::iostate _osState_;// Original exception state. + const std::string _oname; - genxWriter s_; - genxSender sender_; - std::size_t depth_; + genxWriter _writer; + genxSender _sender; + std::size_t _depth; }; inline void XMLStreamSerializer::startElement(const QName& qname) diff --git a/XML/include/Poco/XML/XMLStreamSerializerException.h b/XML/include/Poco/XML/XMLStreamSerializerException.h index fd38d8d4b..8287765fb 100644 --- a/XML/include/Poco/XML/XMLStreamSerializerException.h +++ b/XML/include/Poco/XML/XMLStreamSerializerException.h @@ -36,10 +36,9 @@ struct XML_API XMLStreamSerializerException: private: void init(); -private: - std::string name_; - std::string description_; - std::string what_; + std::string _name; + std::string _description; + std::string _what; }; } diff --git a/XML/src/QName.cpp b/XML/src/QName.cpp index 19654c441..198413a76 100644 --- a/XML/src/QName.cpp +++ b/XML/src/QName.cpp @@ -12,16 +12,42 @@ namespace Poco namespace XML { +QName::QName() +{ +} + + +QName::QName(const std::string& name) : + _name(name) +{ +} + + +QName::QName(const std::string& ns, const std::string& name) : + _ns(ns), + _name(name) +{ +} + + +QName::QName(const std::string& ns, const std::string& name, const std::string& prefix) : + _ns(ns), + _name(name), + _prefix(prefix) +{ +} + + string QName::string() const { std::string r; - if (!ns_.empty()) + if (!_ns.empty()) { - r += ns_; + r += _ns; r += '#'; } - r += name_; + r += _name; return r; } diff --git a/XML/src/XMLStreamParser.cpp b/XML/src/XMLStreamParser.cpp index 9fd0dcf14..fa367031d 100644 --- a/XML/src/XMLStreamParser.cpp +++ b/XML/src/XMLStreamParser.cpp @@ -17,7 +17,6 @@ namespace Poco namespace XML { - struct stream_exception_controller { ~stream_exception_controller() @@ -160,6 +159,7 @@ void XMLStreamParser::handle_error() throw XMLStreamParserException(iname_, XML_GetCurrentLineNumber(p_), XML_GetCurrentColumnNumber(p_), XML_ErrorString(e)); } + XMLStreamParser::EventType XMLStreamParser::next() { if (state_ == state_next) @@ -174,7 +174,7 @@ XMLStreamParser::EventType XMLStreamParser::next() case EndElement: { if (!element_state_.empty() && element_state_.back().depth == depth_) - pop_element(); + popElement(); depth_--; break; @@ -329,7 +329,7 @@ const XMLStreamParser::ElementEntry* XMLStreamParser::get_element_() const } -void XMLStreamParser::pop_element() +void XMLStreamParser::popElement() { // Make sure there are no unhandled attributes left. // @@ -372,7 +372,7 @@ XMLStreamParser::EventType XMLStreamParser::next_(bool peek) if (!peek) { if (!element_state_.empty() && element_state_.back().depth == depth_) - pop_element(); + popElement(); depth_--; } diff --git a/XML/src/XMLStreamParserException.cpp b/XML/src/XMLStreamParserException.cpp index 8ac04e4b3..37557bf62 100644 --- a/XML/src/XMLStreamParserException.cpp +++ b/XML/src/XMLStreamParserException.cpp @@ -27,14 +27,14 @@ XMLStreamParserException::~XMLStreamParserException() throw () XMLStreamParserException::XMLStreamParserException(const string& n, Poco::UInt64 l, Poco::UInt64 c, const string& d) - : name_(n), line_(l), column_(c), description_(d) + : _name(n), _line(l), _column(c), _description(d) { init(); } XMLStreamParserException::XMLStreamParserException(const XMLStreamParser& p, const std::string& d) - : name_(p.input_name()), line_(p.line()), column_(p.column()), description_(d) + : _name(p.inputName()), _line(p.line()), _column(p.column()), _description(d) { init(); } @@ -43,16 +43,36 @@ XMLStreamParserException::XMLStreamParserException(const XMLStreamParser& p, con void XMLStreamParserException::init() { std::ostringstream os; - if (!name_.empty()) - os << name_ << ':'; - os << line_ << ':' << column_ << ": error: " << description_; - what_ = os.str(); + if (!_name.empty()) + os << _name << ':'; + os << _line << ':' << _column << ": error: " << _description; + _what = os.str(); } +const char* XMLStreamParserException::name() const throw() +{ + return _name.c_str(); +} + +Poco::UInt64 XMLStreamParserException::line() const +{ + return _line; +} + +Poco::UInt64 XMLStreamParserException::column() const +{ + return _column; +} + +const std::string& XMLStreamParserException::description() const +{ + return _description; +} + char const* XMLStreamParserException::what() const throw () { - return what_.c_str(); + return _what.c_str(); } diff --git a/XML/src/XMLStreamSerializer.cpp b/XML/src/XMLStreamSerializer.cpp index 6eccfcdd7..1d1bc65af 100644 --- a/XML/src/XMLStreamSerializer.cpp +++ b/XML/src/XMLStreamSerializer.cpp @@ -47,39 +47,39 @@ extern "C" genxStatus genx_flush(void* p) XMLStreamSerializer::~XMLStreamSerializer() { - if (s_ != 0) - genxDispose (s_); + if (_writer != 0) + genxDispose (_writer); } XMLStreamSerializer::XMLStreamSerializer(ostream& os, const string& oname, unsigned short ind) - : os_(os), os_state_(os.exceptions()), oname_(oname), depth_(0) + : _outputStream(os), _osState_(os.exceptions()), _oname(oname), _depth(0) { // Temporarily disable exceptions on the stream. // - os_.exceptions(ostream::goodbit); + _outputStream.exceptions(ostream::goodbit); // Allocate the XMLStreamSerializer. Make sure nothing else can throw after // this call since otherwise we will leak it. // - s_ = genxNew(0, 0, 0); + _writer = genxNew(0, 0, 0); - if (s_ == 0) + if (_writer == 0) throw bad_alloc(); - genxSetUserData(s_, &os_); + genxSetUserData(_writer, &_outputStream); if (ind != 0) - genxSetPrettyPrint(s_, ind); + genxSetPrettyPrint(_writer, ind); - sender_.send = &genx_write; - sender_.sendBounded = &genx_write_bound; - sender_.flush = &genx_flush; + _sender.send = &genx_write; + _sender.sendBounded = &genx_write_bound; + _sender.flush = &genx_flush; - if (genxStatus e = genxStartDocSender(s_, &sender_)) + if (genxStatus e = genxStartDocSender(_writer, &_sender)) { - string m(genxGetErrorMessage(s_, e)); - genxDispose (s_); + string m(genxGetErrorMessage(_writer, e)); + genxDispose (_writer); throw XMLStreamSerializerException(oname, m); } } @@ -97,38 +97,38 @@ void XMLStreamSerializer::handleError(genxStatus e) // configure the stream to throw), then fall back to the // serialiation exception. // - os_.exceptions(os_state_); + _outputStream.exceptions(_osState_); // Fall through. default: - throw XMLStreamSerializerException(oname_, genxGetErrorMessage(s_, e)); + throw XMLStreamSerializerException(_oname, genxGetErrorMessage(_writer, e)); } } void XMLStreamSerializer::startElement(const string& ns, const string& name) { - if (genxStatus e = genxStartElementLiteral(s_, reinterpret_cast(ns.empty() ? 0 : ns.c_str()), reinterpret_cast(name.c_str()))) + if (genxStatus e = genxStartElementLiteral(_writer, reinterpret_cast(ns.empty() ? 0 : ns.c_str()), reinterpret_cast(name.c_str()))) handleError(e); - depth_++; + _depth++; } void XMLStreamSerializer::endElement() { - if (genxStatus e = genxEndElement(s_)) + if (genxStatus e = genxEndElement(_writer)) handleError(e); // Call EndDocument() if we are past the root element. // - if (--depth_ == 0) + if (--_depth == 0) { - if (genxStatus e = genxEndDocument(s_)) + if (genxStatus e = genxEndDocument(_writer)) handleError(e); // Also restore the original exception state on the stream. // - os_.exceptions(os_state_); + _outputStream.exceptions(_osState_); } } @@ -142,21 +142,21 @@ void XMLStreamSerializer::element(const string& ns, const string& n, const strin void XMLStreamSerializer::startAttribute(const string& ns, const string& name) { - if (genxStatus e = genxStartAttributeLiteral(s_, reinterpret_cast(ns.empty() ? 0 : ns.c_str()), reinterpret_cast(name.c_str()))) + if (genxStatus e = genxStartAttributeLiteral(_writer, reinterpret_cast(ns.empty() ? 0 : ns.c_str()), reinterpret_cast(name.c_str()))) handleError(e); } void XMLStreamSerializer::endAttribute() { - if (genxStatus e = genxEndAttribute(s_)) + if (genxStatus e = genxEndAttribute(_writer)) handleError(e); } void XMLStreamSerializer::attribute(const string& ns, const string& name, const string& value) { - if (genxStatus e = genxAddAttributeLiteral(s_, reinterpret_cast(ns.empty() ? 0 : ns.c_str()), reinterpret_cast(name.c_str()), + if (genxStatus e = genxAddAttributeLiteral(_writer, reinterpret_cast(ns.empty() ? 0 : ns.c_str()), reinterpret_cast(name.c_str()), reinterpret_cast(value.c_str()))) handleError(e); } @@ -164,7 +164,7 @@ void XMLStreamSerializer::attribute(const string& ns, const string& name, const void XMLStreamSerializer::characters(const string& value) { - if (genxStatus e = genxAddCountedText(s_, reinterpret_cast(value.c_str()), value.size())) + if (genxStatus e = genxAddCountedText(_writer, reinterpret_cast(value.c_str()), value.size())) handleError(e); } @@ -173,15 +173,15 @@ void XMLStreamSerializer::namespaceDecl(const string& ns, const string& p) { if (genxStatus e = ns.empty() && p.empty() ? - genxUnsetDefaultNamespace(s_) : - genxAddNamespaceLiteral(s_, reinterpret_cast(ns.c_str()), reinterpret_cast(p.c_str()))) + genxUnsetDefaultNamespace(_writer) : + genxAddNamespaceLiteral(_writer, reinterpret_cast(ns.c_str()), reinterpret_cast(p.c_str()))) handleError(e); } void XMLStreamSerializer::xmlDecl(const string& ver, const string& enc, const string& stl) { - if (genxStatus e = genxXmlDeclaration(s_, reinterpret_cast(ver.c_str()), (enc.empty() ? 0 : reinterpret_cast(enc.c_str())), + if (genxStatus e = genxXmlDeclaration(_writer, reinterpret_cast(ver.c_str()), (enc.empty() ? 0 : reinterpret_cast(enc.c_str())), (stl.empty() ? 0 : reinterpret_cast(stl.c_str())))) handleError(e); } @@ -193,7 +193,7 @@ bool XMLStreamSerializer::lookupNamespacePrefix(const string& ns, string& p) // already exist. // genxStatus e; - genxNamespace gns(genxDeclareNamespace(s_, reinterpret_cast(ns.c_str()), 0, &e)); + genxNamespace gns(genxDeclareNamespace(_writer, reinterpret_cast(ns.c_str()), 0, &e)); if (e != GENX_SUCCESS) handleError(e); diff --git a/XML/src/XMLStreamSerializerException.cpp b/XML/src/XMLStreamSerializerException.cpp index 4b2d990b1..ee5ff19a6 100644 --- a/XML/src/XMLStreamSerializerException.cpp +++ b/XML/src/XMLStreamSerializerException.cpp @@ -25,45 +25,45 @@ XMLStreamSerializerException::~XMLStreamSerializerException() throw () } XMLStreamSerializerException::XMLStreamSerializerException(const string& n, const string& d) - : name_(n), description_(d) + : _name(n), _description(d) { init(); } XMLStreamSerializerException::XMLStreamSerializerException(const XMLStreamSerializer& s, const std::string& d) - : name_(s.outputName()), description_(d) + : _name(s.outputName()), _description(d) { init(); } void XMLStreamSerializerException::init() { - if (!name_.empty()) + if (!_name.empty()) { - what_ += name_; - what_ += ": "; + _what += _name; + _what += ": "; } - what_ += "error: "; - what_ += description_; + _what += "error: "; + _what += _description; } const char* XMLStreamSerializerException::name() const throw () { - return name_.c_str(); + return _name.c_str(); } const std::string& XMLStreamSerializerException::description() const { - return description_; + return _description; } char const* XMLStreamSerializerException::what() const throw () { - return what_.c_str(); + return _what.c_str(); } } /* namespace XML */ diff --git a/XML/testsuite/Makefile b/XML/testsuite/Makefile index b71638b23..f2818ddf0 100644 --- a/XML/testsuite/Makefile +++ b/XML/testsuite/Makefile @@ -12,7 +12,8 @@ objects = AttributesImplTest ChildNodesTest DOMTestSuite DocumentTest \ DocumentTypeTest Driver ElementTest EventTest NamePoolTest NameTest \ NamespaceSupportTest NodeIteratorTest NodeTest ParserWriterTest \ SAXParserTest SAXTestSuite TextTest TreeWalkerTest \ - XMLTestSuite XMLWriterTest NodeAppenderTest + XMLTestSuite XMLWriterTest NodeAppenderTest XMLStreamSerializerTestSuite \ + XMLStreamParserTestSuite target = testrunner target_version = 1 diff --git a/XML/testsuite/src/XMLStreamParserTestSuite.cpp b/XML/testsuite/src/XMLStreamParserTestSuite.cpp new file mode 100644 index 000000000..6af418e20 --- /dev/null +++ b/XML/testsuite/src/XMLStreamParserTestSuite.cpp @@ -0,0 +1,489 @@ +// +// XMLStreamParserTestSuite.cpp +// +// $Id: //poco/1.4/XML/testsuite/src/XMLStreamParserTestSuite.cpp#4 $ +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + +#include "XMLStreamParserTestSuite.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/XML/XMLStreamParser.h" +#include "Poco/Exception.h" +#include +#include +#include +#include + +using namespace Poco::XML; +using namespace std; + +XMLStreamParserTestSuite::XMLStreamParserTestSuite(const std::string& name) + : CppUnit::TestCase(name) +{ +} + +XMLStreamParserTestSuite::~XMLStreamParserTestSuite() +{ +} + +void XMLStreamParserTestSuite::testParser() +{ + // Test error handling. + // + try + { + istringstream is("X"); + XMLStreamParser p(is, "test"); + + poco_assert(p.next() == XMLStreamParser::StartElement); + poco_assert(p.next() == XMLStreamParser::StartElement); + poco_assert(p.next() == XMLStreamParser::Characters && p.value() == "X"); + p.next(); + poco_assert(false); + } catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + try + { + istringstream is(""); + is.exceptions(ios_base::badbit | ios_base::failbit); + XMLStreamParser p(is, "test"); + + is.setstate(ios_base::badbit); + p.next(); + poco_assert(false); + } catch (const ios_base::failure&) + { + } + + // Test the nextExpect() functionality. + // + { + istringstream is(""); + XMLStreamParser p(is, "test"); + p.nextExpect(XMLStreamParser::StartElement, "root"); + p.nextExpect(XMLStreamParser::EndElement); + } + + try + { + istringstream is(""); + XMLStreamParser p(is, "test"); + p.nextExpect(XMLStreamParser::EndElement); + poco_assert(false); + } catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + try + { + istringstream is(""); + XMLStreamParser p(is, "test"); + p.nextExpect(XMLStreamParser::StartElement, "root1"); + poco_assert(false); + } catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + // Test nextExpect() with content setting. + // + { + istringstream is(" "); + XMLStreamParser p(is, "empty"); + + p.nextExpect(XMLStreamParser::StartElement, "root", Content::Empty); + p.nextExpect(XMLStreamParser::EndElement); + p.nextExpect(XMLStreamParser::Eof); + } + + // Test namespace declarations. + // + { + // Followup end element event that should be precedeeded by end + // namespace declaration. + // + istringstream is(""); + XMLStreamParser p(is, "test", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_NAMESPACE_DECLS); + + p.nextExpect(XMLStreamParser::StartElement, "root"); + p.nextExpect(XMLStreamParser::StartNamespaceDecl); + p.nextExpect(XMLStreamParser::EndNamespaceDecl); + p.nextExpect(XMLStreamParser::EndElement); + } + + // Test value extraction. + // + { + istringstream is("123"); + XMLStreamParser p(is, "test"); + p.nextExpect(XMLStreamParser::StartElement, "root"); + p.nextExpect(XMLStreamParser::Characters); + poco_assert(p.value() == 123); + p.nextExpect(XMLStreamParser::EndElement); + } + + // Test attribute maps. + // + { + istringstream is(""); + XMLStreamParser p(is, "test"); + p.nextExpect(XMLStreamParser::StartElement, "root"); + + poco_assert(p.attribute("a") == "a"); + poco_assert(p.attribute("b", "B") == "b"); + poco_assert(p.attribute("c", "C") == "C"); + poco_assert(p.attribute("d") == 123); + poco_assert(p.attribute("t") == true); + poco_assert(p.attribute("f", false) == false); + + p.nextExpect(XMLStreamParser::EndElement); + } + + { + istringstream is(""); + XMLStreamParser p(is, "test"); + p.nextExpect(XMLStreamParser::StartElement, "root"); + poco_assert(p.attribute("a") == "a"); + poco_assert(p.peek() == XMLStreamParser::StartElement && p.name() == "nested"); + poco_assert(p.attribute("a") == "a"); + p.nextExpect(XMLStreamParser::StartElement, "nested"); + poco_assert(p.attribute("a") == "A"); + p.nextExpect(XMLStreamParser::StartElement, "inner"); + poco_assert(p.attribute("a", "") == ""); + p.nextExpect(XMLStreamParser::EndElement); + poco_assert(p.attribute("a") == "A"); + poco_assert(p.peek() == XMLStreamParser::EndElement); + poco_assert(p.attribute("a") == "A"); // Still valid. + p.nextExpect(XMLStreamParser::EndElement); + poco_assert(p.attribute("a") == "a"); + p.nextExpect(XMLStreamParser::EndElement); + poco_assert(p.attribute("a", "") == ""); + } + + try + { + istringstream is(""); + XMLStreamParser p(is, "test"); + p.nextExpect(XMLStreamParser::StartElement, "root"); + poco_assert(p.attribute("a") == "a"); + p.nextExpect(XMLStreamParser::EndElement); + poco_assert(false); + } catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + try + { + istringstream is(""); + XMLStreamParser p(is, "test"); + p.nextExpect(XMLStreamParser::StartElement, "root"); + p.attribute("a"); + poco_assert(false); + } catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + // Test peeking and getting the current event. + // + { + istringstream is("x"); + XMLStreamParser p(is, "peek", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_ATTRIBUTES_EVENT); + + poco_assert(p.event() == XMLStreamParser::Eof); + + poco_assert(p.peek() == XMLStreamParser::StartElement); + poco_assert(p.next() == XMLStreamParser::StartElement); + poco_assert(p.event() == XMLStreamParser::StartElement); + + poco_assert(p.peek() == XMLStreamParser::StartAttribute); + poco_assert(p.event() == XMLStreamParser::StartAttribute); + poco_assert(p.next() == XMLStreamParser::StartAttribute); + + poco_assert(p.peek() == XMLStreamParser::Characters && p.value() == "x"); + poco_assert(p.next() == XMLStreamParser::Characters && p.value() == "x"); + poco_assert(p.event() == XMLStreamParser::Characters && p.value() == "x"); + + poco_assert(p.peek() == XMLStreamParser::EndAttribute); + poco_assert(p.event() == XMLStreamParser::EndAttribute); + poco_assert(p.next() == XMLStreamParser::EndAttribute); + + poco_assert(p.peek() == XMLStreamParser::Characters && p.value() == "x"); + poco_assert(p.next() == XMLStreamParser::Characters && p.value() == "x"); + poco_assert(p.event() == XMLStreamParser::Characters && p.value() == "x"); + + poco_assert(p.peek() == XMLStreamParser::StartElement); + poco_assert(p.next() == XMLStreamParser::StartElement); + poco_assert(p.event() == XMLStreamParser::StartElement); + + poco_assert(p.peek() == XMLStreamParser::EndElement); + poco_assert(p.next() == XMLStreamParser::EndElement); + poco_assert(p.event() == XMLStreamParser::EndElement); + + poco_assert(p.peek() == XMLStreamParser::EndElement); + poco_assert(p.next() == XMLStreamParser::EndElement); + poco_assert(p.event() == XMLStreamParser::EndElement); + + poco_assert(p.peek() == XMLStreamParser::Eof); + poco_assert(p.next() == XMLStreamParser::Eof); + poco_assert(p.event() == XMLStreamParser::Eof); + } + + // Test content processing. + // + + // empty + // + { + istringstream is(" \n\t "); + XMLStreamParser p(is, "empty", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_ATTRIBUTES_EVENT); + + poco_assert(p.next() == XMLStreamParser::StartElement); + p.content(Content::Empty); + poco_assert(p.next() == XMLStreamParser::StartAttribute); + poco_assert(p.next() == XMLStreamParser::Characters && p.value() == " x "); + poco_assert(p.next() == XMLStreamParser::EndAttribute); + poco_assert(p.next() == XMLStreamParser::EndElement); + poco_assert(p.next() == XMLStreamParser::Eof); + } + + try + { + istringstream is(" \n & X \t "); + XMLStreamParser p(is, "empty"); + + poco_assert(p.next() == XMLStreamParser::StartElement); + p.content(Content::Empty); + p.next(); + poco_assert(false); + } catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + // simple + // + { + istringstream is(" X "); + XMLStreamParser p(is, "simple"); + + poco_assert(p.next() == XMLStreamParser::StartElement); + p.content(Content::Simple); + poco_assert(p.next() == XMLStreamParser::Characters && p.value() == " X "); + poco_assert(p.next() == XMLStreamParser::EndElement); + poco_assert(p.next() == XMLStreamParser::Eof); + } + + try + { + istringstream is(" ? "); + XMLStreamParser p(is, "simple"); + + poco_assert(p.next() == XMLStreamParser::StartElement); + p.content(Content::Simple); + poco_assert(p.next() == XMLStreamParser::Characters && p.value() == " ? "); + p.next(); + poco_assert(false); + } catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + { + // Test content accumulation in simple content. + // + istringstream is("123"); + XMLStreamParser p(is, "simple", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_NAMESPACE_DECLS); + + poco_assert(p.next() == XMLStreamParser::StartElement); + p.nextExpect(XMLStreamParser::StartNamespaceDecl); + p.content(Content::Simple); + poco_assert(p.next() == XMLStreamParser::Characters && p.value() == "123"); + p.nextExpect(XMLStreamParser::EndNamespaceDecl); + poco_assert(p.next() == XMLStreamParser::EndElement); + poco_assert(p.next() == XMLStreamParser::Eof); + } + + try + { + // Test error handling in accumulation in simple content. + // + istringstream is("123"); + XMLStreamParser p(is, "simple", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_NAMESPACE_DECLS); + + poco_assert(p.next() == XMLStreamParser::StartElement); + p.nextExpect(XMLStreamParser::StartNamespaceDecl); + p.content(Content::Simple); + p.next(); + poco_assert(false); + } catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + // complex + // + { + istringstream is("\n" + " \n" + " \n" + " X \n" + " \n" + "\n"); + XMLStreamParser p(is, "complex", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_ATTRIBUTES_EVENT); + + poco_assert(p.next() == XMLStreamParser::StartElement); // root + p.content(Content::Complex); + + poco_assert(p.next() == XMLStreamParser::StartAttribute); + poco_assert(p.next() == XMLStreamParser::Characters && p.value() == " x "); + poco_assert(p.next() == XMLStreamParser::EndAttribute); + + poco_assert(p.next() == XMLStreamParser::StartElement); // nested + p.content(Content::Complex); + + poco_assert(p.next() == XMLStreamParser::StartElement); // inner + p.content(Content::Empty); + poco_assert(p.next() == XMLStreamParser::EndElement); // inner + + poco_assert(p.next() == XMLStreamParser::StartElement); // inner + p.content(Content::Simple); + poco_assert(p.next() == XMLStreamParser::Characters && p.value() == " X "); + poco_assert(p.next() == XMLStreamParser::EndElement); // inner + + poco_assert(p.next() == XMLStreamParser::EndElement); // nested + poco_assert(p.next() == XMLStreamParser::EndElement); // root + poco_assert(p.next() == XMLStreamParser::Eof); + } + + try + { + istringstream is(" \n X X "); + XMLStreamParser p(is, "complex"); + + poco_assert(p.next() == XMLStreamParser::StartElement); + p.content(Content::Complex); + poco_assert(p.next() == XMLStreamParser::StartElement); + poco_assert(p.next() == XMLStreamParser::EndElement); + p.next(); + poco_assert(false); + } catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + // Test element with simple content helpers. + // + { + istringstream is("" + " X" + " " + " 123" + " Y" + " Z" + " 234" + " 345" + " A" + " B" + " A" + " B" + " 1" + " 2" + " 1" + " 2" + ""); + XMLStreamParser p(is, "element"); + + p.nextExpect(XMLStreamParser::StartElement, "root", Content::Complex); + + p.nextExpect(XMLStreamParser::StartElement, "nested"); + poco_assert(p.element() == "X"); + + p.nextExpect(XMLStreamParser::StartElement, "nested"); + poco_assert(p.element() == ""); + + p.nextExpect(XMLStreamParser::StartElement, "nested"); + poco_assert(p.element() == 123); + + poco_assert(p.element("nested") == "Y"); + poco_assert(p.element(QName("test", "nested")) == "Z"); + + poco_assert(p.element("nested") == 234); + poco_assert(p.element(QName("test", "nested")) == 345); + + poco_assert(p.element("nested", "a") == "A"); + poco_assert(p.element(QName("test", "nested"), "b") == "B"); + + poco_assert(p.element("nested", "a") == "a" && p.element("nested1") == "A"); + poco_assert(p.element(QName("test", "nested"), "b") == "b" && p.element(QName("test", "nested1")) == "B"); + + poco_assert(p.element("nested", 10) == 1); + poco_assert(p.element(QName("test", "nested"), 20) == 2); + + poco_assert(p.element("nested", 10) == 10 && p.element("nested1") == 1); + poco_assert(p.element(QName("test", "nested"), 20) == 20 && p.element(QName("test", "nested1")) == 2); + + p.nextExpect(XMLStreamParser::EndElement); + } + + // Test the iterator interface. + // + { + istringstream is("X"); + XMLStreamParser p(is, "iterator"); + + vector v; + + for (XMLStreamParser::Iterator i(p.begin()); i != p.end(); ++i) + v.push_back(*i); + + //for (XMLStreamParser::EventType e: p) + // v.push_back (e); + + poco_assert(v.size() == 5); + poco_assert(v[0] == XMLStreamParser::StartElement); + poco_assert(v[1] == XMLStreamParser::StartElement); + poco_assert(v[2] == XMLStreamParser::Characters); + poco_assert(v[3] == XMLStreamParser::EndElement); + poco_assert(v[4] == XMLStreamParser::EndElement); + } + + // Test space extraction into the std::string value. + // + { + istringstream is(" b "); + XMLStreamParser p(is, "test"); + p.nextExpect(XMLStreamParser::StartElement, "root"); + poco_assert(p.attribute("a") == " a "); + p.nextExpect(XMLStreamParser::Characters); + poco_assert(p.value() == " b "); + p.nextExpect(XMLStreamParser::EndElement); + } +} + +void XMLStreamParserTestSuite::setUp() +{ +} + +void XMLStreamParserTestSuite::tearDown() +{ +} + +CppUnit::Test* XMLStreamParserTestSuite::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("XMLStreamParserTestSuite"); + + CppUnit_addTest(pSuite, XMLStreamParserTestSuite, testParser); + + return pSuite; +} diff --git a/XML/testsuite/src/XMLStreamParserTestSuite.h b/XML/testsuite/src/XMLStreamParserTestSuite.h new file mode 100644 index 000000000..5626448ae --- /dev/null +++ b/XML/testsuite/src/XMLStreamParserTestSuite.h @@ -0,0 +1,40 @@ +// +// XMLStreamParserTestSuite.h +// +// $Id: //poco/1.4/XML/testsuite/src/XMLStreamParserTestSuite.h#2 $ +// +// Definition of the XMLStreamParserTestSuite class. +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef XMLStreamParserTestSuite_INCLUDED +#define XMLStreamParserTestSuite_INCLUDED + + +#include "Poco/XML/XML.h" +#include "CppUnit/TestCase.h" + + +class XMLStreamParserTestSuite: public CppUnit::TestCase +{ +public: + XMLStreamParserTestSuite(const std::string& name); + ~XMLStreamParserTestSuite(); + + void testParser(); + + void setUp(); + void tearDown(); + + static CppUnit::Test* suite(); + +private: +}; + + +#endif // XMLStreamParserTestSuite_INCLUDED diff --git a/XML/testsuite/src/XMLStreamSerializerTestSuite.cpp b/XML/testsuite/src/XMLStreamSerializerTestSuite.cpp new file mode 100644 index 000000000..7f68ca3fd --- /dev/null +++ b/XML/testsuite/src/XMLStreamSerializerTestSuite.cpp @@ -0,0 +1,131 @@ +// +// XMLStreamSerializerTestSuite.cpp +// +// $Id: //poco/1.4/XML/testsuite/src/XMLStreamSerializerTestSuite.cpp#4 $ +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + +#include "XMLStreamSerializerTestSuite.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/XML/XMLStreamSerializer.h" +#include "Poco/Exception.h" +#include +#include +#include +#include + +using namespace Poco::XML; +using namespace std; + +XMLStreamSerializerTestSuite::XMLStreamSerializerTestSuite(const std::string& name) + : CppUnit::TestCase(name) +{ +} + +XMLStreamSerializerTestSuite::~XMLStreamSerializerTestSuite() +{ +} + +void XMLStreamSerializerTestSuite::testSerialize() +{ + try + { + ostringstream os; + XMLStreamSerializer s (os, "test"); + + s.attribute ("foo", "bar"); + assert (false); + } + catch (const Poco::Exception&) + { + // cerr << e.what () << endl; + } + + try + { + ostringstream os; + os.exceptions (ios_base::badbit | ios_base::failbit); + XMLStreamSerializer s (os, "test"); + + s.startElement ("root"); + s.characters ("one"); + os.setstate (ios_base::badbit); + s.characters ("two"); + assert (false); + } + catch (const ios_base::failure&) + { + } + + // Test value serialization. + // + { + ostringstream os; + XMLStreamSerializer s (os, "test", 0); + + s.startElement ("root"); + s.attribute ("version", 123); + s.characters (true); + s.endElement (); + + assert (os.str () == "true\n"); + } + + // Test helpers for serializing elements with simple content. + // + { + ostringstream os; + XMLStreamSerializer s (os, "element", 0); + + s.startElement ("root"); + + s.startElement ("nested"); + s.element ("X"); + + s.startElement ("nested"); + s.element (123); + + s.element ("nested", "X"); + s.element ("nested", 123); + s.element ("test", "nested", "X"); + s.element ("test", "nested", 123); + s.element (QName ("test", "nested"), "X"); + s.element (QName ("test", "nested"), 123); + + s.endElement (); // root + + assert (os.str () == + "" + "X" + "123" + "X" + "123" + "X" + "123" + "X" + "123" + "\n"); + } +} + +void XMLStreamSerializerTestSuite::setUp() +{ +} + +void XMLStreamSerializerTestSuite::tearDown() +{ +} + +CppUnit::Test* XMLStreamSerializerTestSuite::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("XMLStreamSerializerTestSuite"); + + CppUnit_addTest(pSuite, XMLStreamSerializerTestSuite, testSerialize); + + return pSuite; +} diff --git a/XML/testsuite/src/XMLStreamSerializerTestSuite.h b/XML/testsuite/src/XMLStreamSerializerTestSuite.h new file mode 100644 index 000000000..9adef5a7a --- /dev/null +++ b/XML/testsuite/src/XMLStreamSerializerTestSuite.h @@ -0,0 +1,40 @@ +// +// XMLStreamSerializerTestSuite.h +// +// $Id: //poco/1.4/XML/testsuite/src/XMLStreamSerializerTestSuite.h#2 $ +// +// Definition of the XMLStreamSerializerTestSuite class. +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef XMLStreamSerializerTestSuite_INCLUDED +#define XMLStreamSerializerTestSuite_INCLUDED + + +#include "Poco/XML/XML.h" +#include "CppUnit/TestCase.h" + + +class XMLStreamSerializerTestSuite: public CppUnit::TestCase +{ +public: + XMLStreamSerializerTestSuite(const std::string& name); + ~XMLStreamSerializerTestSuite(); + + void testSerialize(); + + void setUp(); + void tearDown(); + + static CppUnit::Test* suite(); + +private: +}; + + +#endif // XMLStreamSerializerTestSuite_INCLUDED diff --git a/XML/testsuite/src/XMLTestSuite.cpp b/XML/testsuite/src/XMLTestSuite.cpp index 28bb213ed..87be648bd 100644 --- a/XML/testsuite/src/XMLTestSuite.cpp +++ b/XML/testsuite/src/XMLTestSuite.cpp @@ -16,7 +16,8 @@ #include "XMLWriterTest.h" #include "SAXTestSuite.h" #include "DOMTestSuite.h" - +#include "XMLStreamParserTestSuite.h" +#include "XMLStreamSerializerTestSuite.h" CppUnit::Test* XMLTestSuite::suite() { @@ -27,6 +28,8 @@ CppUnit::Test* XMLTestSuite::suite() pSuite->addTest(XMLWriterTest::suite()); pSuite->addTest(SAXTestSuite::suite()); pSuite->addTest(DOMTestSuite::suite()); + pSuite->addTest(XMLStreamParserTestSuite::suite()); + pSuite->addTest(XMLStreamSerializerTestSuite::suite()); return pSuite; }