XMLStream API fixes

This commit is contained in:
Marian Krivos 2015-08-22 17:36:39 +02:00
parent 11211d345d
commit 9bc8d3c851
28 changed files with 365 additions and 308 deletions

View File

@ -25,6 +25,12 @@ else()
) )
endif (POCO_UNBUNDLED) endif (POCO_UNBUNDLED)
# GENX lib
POCO_SOURCES( SRCS genx
src/genx.c
src/char-props.c
)
if(WIN32) if(WIN32)
#TODO: Is XML_STATIC only required with Windows? What does it do? #TODO: Is XML_STATIC only required with Windows? What does it do?
add_definitions(-DXML_STATIC -DXML_NS -DXML_DTD -DHAVE_EXPAT_CONFIG_H) add_definitions(-DXML_STATIC -DXML_NS -DXML_DTD -DHAVE_EXPAT_CONFIG_H)

View File

@ -12,7 +12,7 @@ COMMONFLAGS += -DXML_NS -DXML_DTD -DHAVE_EXPAT_CONFIG_H
objects = AbstractContainerNode AbstractNode Attr AttrMap Attributes \ objects = AbstractContainerNode AbstractNode Attr AttrMap Attributes \
AttributesImpl CDATASection CharacterData ChildNodesList Comment \ AttributesImpl CDATASection CharacterData ChildNodesList Comment \
Content ContentHandler DOMBuilder DOMException DOMImplementation DOMObject \ ContentHandler DOMBuilder DOMException DOMImplementation DOMObject \
DOMParser DOMSerializer DOMWriter DTDHandler DTDMap DeclHandler \ DOMParser DOMSerializer DOMWriter DTDHandler DTDMap DeclHandler \
DefaultHandler Document DocumentEvent DocumentFragment DocumentType \ DefaultHandler Document DocumentEvent DocumentFragment DocumentType \
Element ElementsByTagNameList Entity EntityReference EntityResolver \ Element ElementsByTagNameList Entity EntityReference EntityResolver \

View File

@ -27,19 +27,10 @@ struct XML_API XMLStreamSerializerException:
virtual ~XMLStreamSerializerException() throw (); virtual ~XMLStreamSerializerException() throw ();
XMLStreamSerializerException(const std::string& name, const std::string& description); XMLStreamSerializerException(const std::string& name, const std::string& description);
XMLStreamSerializerException(const XMLStreamSerializer&, const std::string& description); XMLStreamSerializerException(const XMLStreamSerializer&, const std::string& description);
const char* name() const throw () const char* name() const throw ();
{ const std::string& description() const;
return name_.c_str();
}
const std::string& description() const
{
return description_;
}
virtual const char* what() const throw (); virtual const char* what() const throw ();
private: private:

View File

@ -2,7 +2,7 @@
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
// license : MIT; see accompanying LICENSE file // license : MIT; see accompanying LICENSE file
#include "QName.h" #include "Poco/XML/QName.h"
#include <ostream> #include <ostream>
using namespace std; using namespace std;

View File

@ -2,8 +2,8 @@
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
// license : MIT; see accompanying LICENSE file // license : MIT; see accompanying LICENSE file
#include "XMLStreamParser.h" #include "Poco/XML/XMLStreamParser.h"
#include "XMLStreamParserException.h" #include "Poco/XML/XMLStreamParserException.h"
using namespace std; using namespace std;

View File

@ -2,6 +2,7 @@
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
// license : MIT; see accompanying LICENSE file // license : MIT; see accompanying LICENSE file
#include "Poco/XML/XMLStreamParser.h"
#include <new> // std::bad_alloc #include <new> // std::bad_alloc
#include <cassert> #include <cassert>
#include <cstring> // std::strchr #include <cstring> // std::strchr
@ -9,33 +10,81 @@
#include <ostream> #include <ostream>
#include <sstream> #include <sstream>
#include "XMLStreamParser.h"
using namespace std; using namespace std;
namespace Poco namespace Poco
{ {
namespace XML namespace XML
{ {
// XMLStreamParser::event_type
//
static const char* parser_event_str[] =
{ "start element", "end element", "start attribute", "end attribute", "characters", "start namespace declaration", "end namespace declaration", "end of file" };
ostream&
operator<<(ostream& os, XMLStreamParser::EventType e) struct stream_exception_controller
{
~stream_exception_controller()
{
istream::iostate s = is_.rdstate();
s &= ~istream::failbit;
// If our error state (sans failbit) intersects with the
// exception state then that means we have an active
// exception and changing error/exception state will
// cause another to be thrown.
//
if (!(old_state_ & s))
{
// Clear failbit if it was caused by eof.
//
if (is_.fail() && is_.eof())
is_.clear(s);
is_.exceptions(old_state_);
}
}
stream_exception_controller(istream& is)
: is_(is), old_state_(is_.exceptions())
{
is_.exceptions(old_state_ & ~istream::failbit);
}
private:
stream_exception_controller(const stream_exception_controller&);
stream_exception_controller&
operator=(const stream_exception_controller&);
private:
istream& is_;
istream::iostate old_state_;
};
static const char* parser_event_str[] =
{
"start element",
"end element",
"start attribute",
"end attribute",
"characters",
"start namespace declaration",
"end namespace declaration",
"end of file"
};
ostream& operator<<(ostream& os, XMLStreamParser::EventType e)
{ {
return os << parser_event_str[e]; return os << parser_event_str[e];
} }
// XMLStreamParser
//
XMLStreamParser::~XMLStreamParser() XMLStreamParser::~XMLStreamParser()
{ {
if (p_ != 0) if (p_ != 0)
XML_ParserFree (p_); XML_ParserFree(p_);
} }
void XMLStreamParser::init() void XMLStreamParser::init()
{ {
depth_ = 0; depth_ = 0;
@ -85,9 +134,10 @@ void XMLStreamParser::init()
XML_SetNamespaceDeclHandler(p_, &start_namespace_decl_, &end_namespace_decl_); XML_SetNamespaceDeclHandler(p_, &start_namespace_decl_, &end_namespace_decl_);
} }
void XMLStreamParser::handle_error() void XMLStreamParser::handle_error()
{ {
XML_Error e(XML_GetErrorCode (p_)); XML_Error e(XML_GetErrorCode(p_));
if (e == XML_ERROR_ABORTED) if (e == XML_ERROR_ABORTED)
{ {
@ -110,46 +160,6 @@ void XMLStreamParser::handle_error()
throw XMLStreamParserException(iname_, XML_GetCurrentLineNumber(p_), XML_GetCurrentColumnNumber(p_), XML_ErrorString(e)); throw XMLStreamParserException(iname_, XML_GetCurrentLineNumber(p_), XML_GetCurrentColumnNumber(p_), XML_ErrorString(e));
} }
struct stream_exception_controller
{
~stream_exception_controller()
{
istream::iostate s = is_.rdstate();
s &= ~istream::failbit;
// If our error state (sans failbit) intersects with the
// exception state then that means we have an active
// exception and changing error/exception state will
// cause another to be thrown.
//
if (!(old_state_ & s))
{
// Clear failbit if it was caused by eof.
//
if (is_.fail() && is_.eof())
is_.clear(s);
is_.exceptions(old_state_);
}
}
stream_exception_controller(istream& is)
: is_(is), old_state_(is_.exceptions())
{
is_.exceptions(old_state_ & ~istream::failbit);
}
private:
stream_exception_controller(const stream_exception_controller&);
stream_exception_controller&
operator=(const stream_exception_controller&);
private:
istream& is_;
istream::iostate old_state_;
};
XMLStreamParser::EventType XMLStreamParser::next() XMLStreamParser::EventType XMLStreamParser::next()
{ {
if (state_ == state_next) if (state_ == state_next)
@ -183,6 +193,7 @@ XMLStreamParser::EventType XMLStreamParser::next()
} }
} }
const string& XMLStreamParser::attribute(const QName& qn) const const string& XMLStreamParser::attribute(const QName& qn) const
{ {
if (const ElementEntry* e = getElement()) if (const ElementEntry* e = getElement())
@ -203,6 +214,7 @@ const string& XMLStreamParser::attribute(const QName& qn) const
throw XMLStreamParserException(*this, "attribute '" + qn.string() + "' expected"); throw XMLStreamParserException(*this, "attribute '" + qn.string() + "' expected");
} }
string XMLStreamParser::attribute(const QName& qn, const string& dv) const string XMLStreamParser::attribute(const QName& qn, const string& dv) const
{ {
if (const ElementEntry* e = getElement()) if (const ElementEntry* e = getElement())
@ -223,6 +235,7 @@ string XMLStreamParser::attribute(const QName& qn, const string& dv) const
return dv; return dv;
} }
bool XMLStreamParser::attributePresent(const QName& qn) const bool XMLStreamParser::attributePresent(const QName& qn) const
{ {
if (const ElementEntry* e = getElement()) if (const ElementEntry* e = getElement())
@ -243,18 +256,21 @@ bool XMLStreamParser::attributePresent(const QName& qn) const
return false; return false;
} }
void XMLStreamParser::nextExpect(EventType e) void XMLStreamParser::nextExpect(EventType e)
{ {
if (next() != e) if (next() != e)
throw XMLStreamParserException(*this, string(parser_event_str[e]) + " expected"); throw XMLStreamParserException(*this, string(parser_event_str[e]) + " expected");
} }
void XMLStreamParser::nextExpect(EventType e, const string& ns, const string& n) void XMLStreamParser::nextExpect(EventType e, const string& ns, const string& n)
{ {
if (next() != e || namespace_() != ns || name() != n) if (next() != e || namespace_() != ns || name() != n)
throw XMLStreamParserException(*this, string(parser_event_str[e]) + " '" + QName(ns, n).string() + "' expected"); throw XMLStreamParserException(*this, string(parser_event_str[e]) + " '" + QName(ns, n).string() + "' expected");
} }
string XMLStreamParser::element() string XMLStreamParser::element()
{ {
content(Content::Simple); content(Content::Simple);
@ -278,6 +294,7 @@ string XMLStreamParser::element()
return r; return r;
} }
string XMLStreamParser::element(const QName& qn, const string& dv) string XMLStreamParser::element(const QName& qn, const string& dv)
{ {
if (peek() == StartElement && qname() == qn) if (peek() == StartElement && qname() == qn)
@ -289,6 +306,7 @@ string XMLStreamParser::element(const QName& qn, const string& dv)
return dv; return dv;
} }
const XMLStreamParser::ElementEntry* XMLStreamParser::get_element_() const const XMLStreamParser::ElementEntry* XMLStreamParser::get_element_() const
{ {
// The start_element_() Expat handler may have already provisioned // The start_element_() Expat handler may have already provisioned
@ -310,6 +328,7 @@ const XMLStreamParser::ElementEntry* XMLStreamParser::get_element_() const
return r; return r;
} }
void XMLStreamParser::pop_element() void XMLStreamParser::pop_element()
{ {
// Make sure there are no unhandled attributes left. // Make sure there are no unhandled attributes left.
@ -330,6 +349,7 @@ void XMLStreamParser::pop_element()
element_state_.pop_back(); element_state_.pop_back();
} }
XMLStreamParser::EventType XMLStreamParser::next_(bool peek) XMLStreamParser::EventType XMLStreamParser::next_(bool peek)
{ {
EventType e(next_body()); EventType e(next_body());
@ -387,6 +407,7 @@ XMLStreamParser::EventType XMLStreamParser::next_(bool peek)
return e; return e;
} }
XMLStreamParser::EventType XMLStreamParser::next_body() XMLStreamParser::EventType XMLStreamParser::next_body()
{ {
// See if we have any start namespace declarations we need to return. // See if we have any start namespace declarations we need to return.
@ -487,9 +508,9 @@ XMLStreamParser::EventType XMLStreamParser::next_body()
} }
// Fall through. // Fall through.
} }
// The end namespace declaration comes before the end element // The end namespace declaration comes before the end element
// which means it can follow pretty much any other event. // which means it can follow pretty much any other event.
// //
default: default:
{ {
event_ = EndNamespaceDecl; event_ = EndNamespaceDecl;
@ -521,51 +542,51 @@ XMLStreamParser::EventType XMLStreamParser::next_body()
switch (ps.parsing) switch (ps.parsing)
{ {
case XML_INITIALIZED: case XML_INITIALIZED:
{ {
// As if we finished the previous chunk. // As if we finished the previous chunk.
break; break;
} }
case XML_PARSING: case XML_PARSING:
{ {
assert(false); assert(false);
return event_ = Eof; return event_ = Eof;
} }
case XML_FINISHED: case XML_FINISHED:
{ {
return event_ = Eof; return event_ = Eof;
} }
case XML_SUSPENDED: case XML_SUSPENDED:
{ {
switch (XML_ResumeParser(p_)) switch (XML_ResumeParser(p_))
{ {
case XML_STATUS_SUSPENDED: case XML_STATUS_SUSPENDED:
{ {
// If the XMLStreamParser is again in the suspended state, then // If the XMLStreamParser is again in the suspended state, then
// that means we have the next event. // that means we have the next event.
// //
return event_; return event_;
} }
case XML_STATUS_OK: case XML_STATUS_OK:
{ {
// Otherwise, we need to get and parse the next chunk of data // Otherwise, we need to get and parse the next chunk of data
// unless this was the last chunk, in which case this is eof. // unless this was the last chunk, in which case this is eof.
// //
if (ps.finalBuffer) if (ps.finalBuffer)
return event_ = Eof; return event_ = Eof;
break; break;
} }
case XML_STATUS_ERROR: case XML_STATUS_ERROR:
handle_error(); handle_error();
} }
break; break;
} }
} }
// Get and parse the next chunk of data until we get the next event // Get and parse the next chunk of data until we get the next event
// or reach eof. // or reach eof.
// //
if (!accumulate_) if (!accumulate_)
event_ = Eof; event_ = Eof;
@ -619,6 +640,7 @@ XMLStreamParser::EventType XMLStreamParser::next_body()
return event_; return event_;
} }
static void splitName(const XML_Char* s, QName& qn) static void splitName(const XML_Char* s, QName& qn)
{ {
string& ns(qn.namespace_()); string& ns(qn.namespace_());
@ -653,230 +675,236 @@ static void splitName(const XML_Char* s, QName& qn)
} }
} }
void XMLCALL XMLStreamParser::start_element_(void* v, const XML_Char* name, const XML_Char** atts) void XMLCALL XMLStreamParser::start_element_(void* v, const XML_Char* name, const XML_Char** atts)
{ {
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v)); XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
XML_ParsingStatus ps; XML_ParsingStatus ps;
XML_GetParsingStatus(p.p_, &ps); XML_GetParsingStatus(p.p_, &ps);
// Expat has a (mis)-feature of a possibily calling handlers even // Expat has a (mis)-feature of a possibily calling handlers even
// after the non-resumable XML_StopParser call. // after the non-resumable XML_StopParser call.
// //
if (ps.parsing == XML_FINISHED) if (ps.parsing == XML_FINISHED)
return; return;
// Cannot be a followup event. // Cannot be a followup event.
// //
assert(ps.parsing == XML_PARSING); assert(ps.parsing == XML_PARSING);
// When accumulating characters in simple content, we expect to // When accumulating characters in simple content, we expect to
// see more characters or end element. Seeing start element is // see more characters or end element. Seeing start element is
// possible but means violation of the content model. // possible but means violation of the content model.
// //
if (p.accumulate_) if (p.accumulate_)
{ {
// It would have been easier to throw the exception directly, // It would have been easier to throw the exception directly,
// however, the Expat code is most likely not exception safe. // however, the Expat code is most likely not exception safe.
// //
p.line_ = XML_GetCurrentLineNumber(p.p_); p.line_ = XML_GetCurrentLineNumber(p.p_);
p.column_ = XML_GetCurrentColumnNumber(p.p_); p.column_ = XML_GetCurrentColumnNumber(p.p_);
XML_StopParser(p.p_, false); XML_StopParser(p.p_, false);
return; return;
} }
p.event_ = StartElement; p.event_ = StartElement;
splitName(name, p.qname_); splitName(name, p.qname_);
p.line_ = XML_GetCurrentLineNumber(p.p_); p.line_ = XML_GetCurrentLineNumber(p.p_);
p.column_ = XML_GetCurrentColumnNumber(p.p_); p.column_ = XML_GetCurrentColumnNumber(p.p_);
// Handle attributes. // Handle attributes.
// //
if (*atts != 0) if (*atts != 0)
{ {
bool am((p.feature_ & RECEIVE_ATTRIBUTE_MAP) != 0); bool am((p.feature_ & RECEIVE_ATTRIBUTE_MAP) != 0);
bool ae((p.feature_ & RECEIVE_ATTRIBUTES_EVENT) != 0); bool ae((p.feature_ & RECEIVE_ATTRIBUTES_EVENT) != 0);
// Provision an entry for this element. // Provision an entry for this element.
// //
ElementEntry* pe(0); ElementEntry* pe(0);
if (am) if (am)
{ {
p.element_state_.push_back(ElementEntry(p.depth_ + 1)); p.element_state_.push_back(ElementEntry(p.depth_ + 1));
pe = &p.element_state_.back(); pe = &p.element_state_.back();
} }
if (am || ae) if (am || ae)
{ {
for (; *atts != 0; atts += 2) for (; *atts != 0; atts += 2)
{ {
if (am) if (am)
{ {
QName qn; QName qn;
splitName(*atts, qn); splitName(*atts, qn);
AttributeMapType::value_type v(qn, AttributeValueType()); AttributeMapType::value_type v(qn, AttributeValueType());
v.second.value = *(atts + 1); v.second.value = *(atts + 1);
v.second.handled = false; v.second.handled = false;
pe->attr_map_.insert(v); pe->attr_map_.insert(v);
} }
else else
{ {
p.attr_.push_back(attribute_type()); p.attr_.push_back(attribute_type());
splitName(*atts, p.attr_.back().qname); splitName(*atts, p.attr_.back().qname);
p.attr_.back().value = *(atts + 1); p.attr_.back().value = *(atts + 1);
} }
} }
if (am) if (am)
pe->attr_unhandled_ = pe->attr_map_.size(); pe->attr_unhandled_ = pe->attr_map_.size();
} }
} }
XML_StopParser(p.p_, true);
}
XML_StopParser(p.p_, true);
}
void XMLCALL XMLStreamParser::end_element_(void* v, const XML_Char* name) void XMLCALL XMLStreamParser::end_element_(void* v, const XML_Char* name)
{ {
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v)); XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
XML_ParsingStatus ps; XML_ParsingStatus ps;
XML_GetParsingStatus(p.p_, &ps); XML_GetParsingStatus(p.p_, &ps);
// Expat has a (mis)-feature of a possibily calling handlers even // Expat has a (mis)-feature of a possibily calling handlers even
// after the non-resumable XML_StopParser call. // after the non-resumable XML_StopParser call.
// //
if (ps.parsing == XML_FINISHED) if (ps.parsing == XML_FINISHED)
return; return;
// This can be a followup event for empty elements (<foo/>). In this // This can be a followup event for empty elements (<foo/>). In this
// case the element name is already set. // case the element name is already set.
// //
if (ps.parsing != XML_PARSING) if (ps.parsing != XML_PARSING)
p.queue_ = EndElement; p.queue_ = EndElement;
else else
{ {
splitName(name, p.qname_); splitName(name, p.qname_);
// If we are accumulating characters, then queue this event. // If we are accumulating characters, then queue this event.
// //
if (p.accumulate_) if (p.accumulate_)
p.queue_ = EndElement; p.queue_ = EndElement;
else else
{ {
p.event_ = EndElement; p.event_ = EndElement;
p.line_ = XML_GetCurrentLineNumber(p.p_); p.line_ = XML_GetCurrentLineNumber(p.p_);
p.column_ = XML_GetCurrentColumnNumber(p.p_); p.column_ = XML_GetCurrentColumnNumber(p.p_);
} }
XML_StopParser(p.p_, true); XML_StopParser(p.p_, true);
} }
} }
void XMLCALL XMLStreamParser::characters_(void* v, const XML_Char* s, int n)
{
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
XML_ParsingStatus ps; void XMLCALL XMLStreamParser::characters_(void* v, const XML_Char* s, int n)
XML_GetParsingStatus(p.p_, &ps);
// Expat has a (mis)-feature of a possibily calling handlers even
// after the non-resumable XML_StopParser call.
//
if (ps.parsing == XML_FINISHED)
return;
Content cont(p.content());
// If this is empty or complex content, see if these are whitespaces.
//
switch (cont)
{
case Content::Empty:
case Content::Complex:
{
for (int i(0); i != n; ++i)
{
char c(s[i]);
if (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09)
continue;
// It would have been easier to throw the exception directly,
// however, the Expat code is most likely not exception safe.
//
p.line_ = XML_GetCurrentLineNumber(p.p_);
p.column_ = XML_GetCurrentColumnNumber(p.p_);
XML_StopParser(p.p_, false);
break;
}
return;
}
default:
break;
}
// Append the characters if we are accumulating. This can also be a
// followup event for another character event. In this case also
// append the data.
//
if (p.accumulate_ || ps.parsing != XML_PARSING)
{
assert(p.event_ == Characters);
p.value_.append(s, n);
}
else
{ {
p.event_ = Characters; XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
p.value_.assign(s, n);
p.line_ = XML_GetCurrentLineNumber(p.p_); XML_ParsingStatus ps;
p.column_ = XML_GetCurrentColumnNumber(p.p_); XML_GetParsingStatus(p.p_, &ps);
// In simple content we need to accumulate all the characters // Expat has a (mis)-feature of a possibily calling handlers even
// into a single event. To do this we will let the XMLStreamParser run // after the non-resumable XML_StopParser call.
// until we reach the end of the element. //
// if (ps.parsing == XML_FINISHED)
if (cont == Content::Simple) return;
p.accumulate_ = true;
else Content cont(p.content());
XML_StopParser(p.p_, true);
} // If this is empty or complex content, see if these are whitespaces.
//
switch (cont)
{
case Content::Empty:
case Content::Complex:
{
for (int i(0); i != n; ++i)
{
char c(s[i]);
if (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09)
continue;
// It would have been easier to throw the exception directly,
// however, the Expat code is most likely not exception safe.
//
p.line_ = XML_GetCurrentLineNumber(p.p_);
p.column_ = XML_GetCurrentColumnNumber(p.p_);
XML_StopParser(p.p_, false);
break;
}
return;
}
default:
break;
}
// Append the characters if we are accumulating. This can also be a
// followup event for another character event. In this case also
// append the data.
//
if (p.accumulate_ || ps.parsing != XML_PARSING)
{
assert(p.event_ == Characters);
p.value_.append(s, n);
}
else
{
p.event_ = Characters;
p.value_.assign(s, n);
p.line_ = XML_GetCurrentLineNumber(p.p_);
p.column_ = XML_GetCurrentColumnNumber(p.p_);
// In simple content we need to accumulate all the characters
// into a single event. To do this we will let the XMLStreamParser run
// until we reach the end of the element.
//
if (cont == Content::Simple)
p.accumulate_ = true;
else
XML_StopParser(p.p_, true);
}
} }
void XMLCALL XMLStreamParser::start_namespace_decl_(void* v, const XML_Char* prefix, const XML_Char* ns) void XMLCALL XMLStreamParser::start_namespace_decl_(void* v, const XML_Char* prefix, const XML_Char* ns)
{ {
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v)); XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
XML_ParsingStatus ps; XML_ParsingStatus ps;
XML_GetParsingStatus(p.p_, &ps); XML_GetParsingStatus(p.p_, &ps);
// Expat has a (mis)-feature of a possibily calling handlers even // Expat has a (mis)-feature of a possibily calling handlers even
// after the non-resumable XML_StopParser call. // after the non-resumable XML_StopParser call.
// //
if (ps.parsing == XML_FINISHED) if (ps.parsing == XML_FINISHED)
return; return;
p.start_ns_.push_back(QName()); p.start_ns_.push_back(QName());
p.start_ns_.back().prefix() = (prefix != 0 ? prefix : ""); p.start_ns_.back().prefix() = (prefix != 0 ? prefix : "");
p.start_ns_.back().namespace_() = (ns != 0 ? ns : ""); p.start_ns_.back().namespace_() = (ns != 0 ? ns : "");
} }
void XMLCALL XMLStreamParser::end_namespace_decl_(void* v, const XML_Char* prefix) void XMLCALL XMLStreamParser::end_namespace_decl_(void* v, const XML_Char* prefix)
{ {
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v)); XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
XML_ParsingStatus ps; XML_ParsingStatus ps;
XML_GetParsingStatus(p.p_, &ps); XML_GetParsingStatus(p.p_, &ps);
// Expat has a (mis)-feature of a possibily calling handlers even // Expat has a (mis)-feature of a possibily calling handlers even
// after the non-resumable XML_StopParser call. // after the non-resumable XML_StopParser call.
// //
if (ps.parsing == XML_FINISHED) if (ps.parsing == XML_FINISHED)
return; return;
p.end_ns_.push_back(QName());
p.end_ns_.back().prefix() = (prefix != 0 ? prefix : "");
}
p.end_ns_.push_back(QName());
p.end_ns_.back().prefix() = (prefix != 0 ? prefix : "");
}
} }
} }

View File

@ -10,8 +10,8 @@
/// All rights reserved. /// All rights reserved.
/// ///
#include "XMLStreamParserException.h" #include "Poco/XML/XMLStreamParserException.h"
#include "XMLStreamParser.h" #include "Poco/XML/XMLStreamParser.h"
using namespace std; using namespace std;
@ -20,22 +20,26 @@ namespace Poco
namespace XML namespace XML
{ {
XMLStreamParserException::~XMLStreamParserException() throw () XMLStreamParserException::~XMLStreamParserException() throw ()
{ {
} }
XMLStreamParserException::XMLStreamParserException(const string& n, Poco::UInt64 l, Poco::UInt64 c, const string& d) 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(); init();
} }
XMLStreamParserException::XMLStreamParserException(const XMLStreamParser& p, const std::string& d) XMLStreamParserException::XMLStreamParserException(const XMLStreamParser& p, const std::string& d)
: name_(p.input_name()), line_(p.line()), column_(p.column()), description_(d) : name_(p.input_name()), line_(p.line()), column_(p.column()), description_(d)
{ {
init(); init();
} }
void XMLStreamParserException::init() void XMLStreamParserException::init()
{ {
std::ostringstream os; std::ostringstream os;
@ -45,10 +49,12 @@ void XMLStreamParserException::init()
what_ = os.str(); what_ = os.str();
} }
char const* XMLStreamParserException::what() const throw () char const* XMLStreamParserException::what() const throw ()
{ {
return what_.c_str(); return what_.c_str();
} }
} /* namespace XML */ } /* namespace XML */
} /* namespace Poco */ } /* namespace Poco */

View File

@ -2,8 +2,8 @@
// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC // copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC
// license : MIT; see accompanying LICENSE file // license : MIT; see accompanying LICENSE file
#include "XMLStreamSerializer.h" #include "Poco/XML/XMLStreamSerializer.h"
#include "XMLStreamSerializerException.h" #include "Poco/XML/XMLStreamSerializerException.h"
#include <new> // std::bad_alloc #include <new> // std::bad_alloc
#include <cstring> // std::strlen #include <cstring> // std::strlen
@ -14,8 +14,7 @@ namespace Poco
{ {
namespace XML namespace XML
{ {
// XMLStreamSerializer
//
extern "C" genxStatus genx_write(void* p, constUtf8 us) extern "C" genxStatus genx_write(void* p, constUtf8 us)
{ {
// It would have been easier to throw the exception directly, // It would have been easier to throw the exception directly,
@ -27,6 +26,7 @@ extern "C" genxStatus genx_write(void* p, constUtf8 us)
return os->good() ? GENX_SUCCESS : GENX_IO_ERROR; return os->good() ? GENX_SUCCESS : GENX_IO_ERROR;
} }
extern "C" genxStatus genx_write_bound(void* p, constUtf8 start, constUtf8 end) extern "C" genxStatus genx_write_bound(void* p, constUtf8 start, constUtf8 end)
{ {
ostream* os(static_cast<ostream*>(p)); ostream* os(static_cast<ostream*>(p));
@ -36,6 +36,7 @@ extern "C" genxStatus genx_write_bound(void* p, constUtf8 start, constUtf8 end)
return os->good() ? GENX_SUCCESS : GENX_IO_ERROR; return os->good() ? GENX_SUCCESS : GENX_IO_ERROR;
} }
extern "C" genxStatus genx_flush(void* p) extern "C" genxStatus genx_flush(void* p)
{ {
ostream* os(static_cast<ostream*>(p)); ostream* os(static_cast<ostream*>(p));
@ -43,12 +44,14 @@ extern "C" genxStatus genx_flush(void* p)
return os->good() ? GENX_SUCCESS : GENX_IO_ERROR; return os->good() ? GENX_SUCCESS : GENX_IO_ERROR;
} }
XMLStreamSerializer::~XMLStreamSerializer() XMLStreamSerializer::~XMLStreamSerializer()
{ {
if (s_ != 0) if (s_ != 0)
genxDispose (s_); genxDispose (s_);
} }
XMLStreamSerializer::XMLStreamSerializer(ostream& os, const string& oname, unsigned short ind) XMLStreamSerializer::XMLStreamSerializer(ostream& os, const string& oname, unsigned short ind)
: os_(os), os_state_(os.exceptions()), oname_(oname), depth_(0) : os_(os), os_state_(os.exceptions()), oname_(oname), depth_(0)
{ {
@ -81,6 +84,7 @@ XMLStreamSerializer::XMLStreamSerializer(ostream& os, const string& oname, unsig
} }
} }
void XMLStreamSerializer::handleError(genxStatus e) void XMLStreamSerializer::handleError(genxStatus e)
{ {
switch (e) switch (e)
@ -100,6 +104,7 @@ void XMLStreamSerializer::handleError(genxStatus e)
} }
} }
void XMLStreamSerializer::startElement(const string& ns, const string& name) void XMLStreamSerializer::startElement(const string& ns, const string& name)
{ {
if (genxStatus e = genxStartElementLiteral(s_, reinterpret_cast<constUtf8>(ns.empty() ? 0 : ns.c_str()), reinterpret_cast<constUtf8>(name.c_str()))) if (genxStatus e = genxStartElementLiteral(s_, reinterpret_cast<constUtf8>(ns.empty() ? 0 : ns.c_str()), reinterpret_cast<constUtf8>(name.c_str())))
@ -108,6 +113,7 @@ void XMLStreamSerializer::startElement(const string& ns, const string& name)
depth_++; depth_++;
} }
void XMLStreamSerializer::endElement() void XMLStreamSerializer::endElement()
{ {
if (genxStatus e = genxEndElement(s_)) if (genxStatus e = genxEndElement(s_))
@ -126,24 +132,28 @@ void XMLStreamSerializer::endElement()
} }
} }
void XMLStreamSerializer::element(const string& ns, const string& n, const string& v) void XMLStreamSerializer::element(const string& ns, const string& n, const string& v)
{ {
startElement(ns, n); startElement(ns, n);
element(v); element(v);
} }
void XMLStreamSerializer::startAttribute(const string& ns, const string& name) void XMLStreamSerializer::startAttribute(const string& ns, const string& name)
{ {
if (genxStatus e = genxStartAttributeLiteral(s_, reinterpret_cast<constUtf8>(ns.empty() ? 0 : ns.c_str()), reinterpret_cast<constUtf8>(name.c_str()))) if (genxStatus e = genxStartAttributeLiteral(s_, reinterpret_cast<constUtf8>(ns.empty() ? 0 : ns.c_str()), reinterpret_cast<constUtf8>(name.c_str())))
handleError(e); handleError(e);
} }
void XMLStreamSerializer::endAttribute() void XMLStreamSerializer::endAttribute()
{ {
if (genxStatus e = genxEndAttribute(s_)) if (genxStatus e = genxEndAttribute(s_))
handleError(e); handleError(e);
} }
void XMLStreamSerializer::attribute(const string& ns, const string& name, const string& value) void XMLStreamSerializer::attribute(const string& ns, const string& name, const string& value)
{ {
if (genxStatus e = genxAddAttributeLiteral(s_, reinterpret_cast<constUtf8>(ns.empty() ? 0 : ns.c_str()), reinterpret_cast<constUtf8>(name.c_str()), if (genxStatus e = genxAddAttributeLiteral(s_, reinterpret_cast<constUtf8>(ns.empty() ? 0 : ns.c_str()), reinterpret_cast<constUtf8>(name.c_str()),
@ -151,12 +161,14 @@ void XMLStreamSerializer::attribute(const string& ns, const string& name, const
handleError(e); handleError(e);
} }
void XMLStreamSerializer::characters(const string& value) void XMLStreamSerializer::characters(const string& value)
{ {
if (genxStatus e = genxAddCountedText(s_, reinterpret_cast<constUtf8>(value.c_str()), value.size())) if (genxStatus e = genxAddCountedText(s_, reinterpret_cast<constUtf8>(value.c_str()), value.size()))
handleError(e); handleError(e);
} }
void XMLStreamSerializer::namespaceDecl(const string& ns, const string& p) void XMLStreamSerializer::namespaceDecl(const string& ns, const string& p)
{ {
if (genxStatus e = if (genxStatus e =
@ -166,6 +178,7 @@ void XMLStreamSerializer::namespaceDecl(const string& ns, const string& p)
handleError(e); handleError(e);
} }
void XMLStreamSerializer::xmlDecl(const string& ver, const string& enc, const string& stl) void XMLStreamSerializer::xmlDecl(const string& ver, const string& enc, const string& stl)
{ {
if (genxStatus e = genxXmlDeclaration(s_, reinterpret_cast<constUtf8>(ver.c_str()), (enc.empty() ? 0 : reinterpret_cast<constUtf8>(enc.c_str())), if (genxStatus e = genxXmlDeclaration(s_, reinterpret_cast<constUtf8>(ver.c_str()), (enc.empty() ? 0 : reinterpret_cast<constUtf8>(enc.c_str())),
@ -173,6 +186,7 @@ void XMLStreamSerializer::xmlDecl(const string& ver, const string& enc, const st
handleError(e); handleError(e);
} }
bool XMLStreamSerializer::lookupNamespacePrefix(const string& ns, string& p) bool XMLStreamSerializer::lookupNamespacePrefix(const string& ns, string& p)
{ {
// Currently Genx will create a namespace mapping if one doesn't // Currently Genx will create a namespace mapping if one doesn't
@ -187,5 +201,6 @@ bool XMLStreamSerializer::lookupNamespacePrefix(const string& ns, string& p)
p = reinterpret_cast<const char*>(genxGetNamespacePrefix(gns)); p = reinterpret_cast<const char*>(genxGetNamespacePrefix(gns));
return true; return true;
} }
} }
} }

View File

@ -10,8 +10,8 @@
/// All rights reserved. /// All rights reserved.
/// ///
#include "XMLStreamParserException.h" #include "Poco/XML/XMLStreamParserException.h"
#include "XMLStreamSerializer.h" #include "Poco/XML/XMLStreamSerializer.h"
using namespace std; using namespace std;
@ -20,8 +20,6 @@ namespace Poco
namespace XML namespace XML
{ {
// XMLStreamSerializerException
//
XMLStreamSerializerException::~XMLStreamSerializerException() throw () XMLStreamSerializerException::~XMLStreamSerializerException() throw ()
{ {
} }
@ -33,7 +31,7 @@ XMLStreamSerializerException::XMLStreamSerializerException(const string& n, cons
} }
XMLStreamSerializerException::XMLStreamSerializerException(const XMLStreamSerializer& s, const std::string& d) XMLStreamSerializerException::XMLStreamSerializerException(const XMLStreamSerializer& s, const std::string& d)
: name_(s.outputName()), description_(d) : name_(s.outputName()), description_(d)
{ {
init(); init();
} }
@ -50,6 +48,19 @@ void XMLStreamSerializerException::init()
what_ += description_; what_ += description_;
} }
const char* XMLStreamSerializerException::name() const throw ()
{
return name_.c_str();
}
const std::string& XMLStreamSerializerException::description() const
{
return description_;
}
char const* XMLStreamSerializerException::what() const throw () char const* XMLStreamSerializerException::what() const throw ()
{ {
return what_.c_str(); return what_.c_str();

View File

@ -11,7 +11,7 @@
* This version is generated semi-automatically from the source code of the * This version is generated semi-automatically from the source code of the
* XML specification via emacs global replace and keyboard macros * XML specification via emacs global replace and keyboard macros
*/ */
#include "genx.h" #include "Poco/XML/genx.h"
static void charProp(char * p, int c, int prop) static void charProp(char * p, int c, int prop)
{ {

View File

@ -11,7 +11,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "genx.h" #include "Poco/XML/genx.h"
#define Boolean int #define Boolean int
#define True 1 #define True 1