mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-16 19:54:38 +01:00
XMLStream API fixes
This commit is contained in:
parent
11211d345d
commit
9bc8d3c851
@ -25,6 +25,12 @@ else()
|
||||
)
|
||||
endif (POCO_UNBUNDLED)
|
||||
|
||||
# GENX lib
|
||||
POCO_SOURCES( SRCS genx
|
||||
src/genx.c
|
||||
src/char-props.c
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
#TODO: Is XML_STATIC only required with Windows? What does it do?
|
||||
add_definitions(-DXML_STATIC -DXML_NS -DXML_DTD -DHAVE_EXPAT_CONFIG_H)
|
||||
|
@ -12,7 +12,7 @@ COMMONFLAGS += -DXML_NS -DXML_DTD -DHAVE_EXPAT_CONFIG_H
|
||||
|
||||
objects = AbstractContainerNode AbstractNode Attr AttrMap Attributes \
|
||||
AttributesImpl CDATASection CharacterData ChildNodesList Comment \
|
||||
Content ContentHandler DOMBuilder DOMException DOMImplementation DOMObject \
|
||||
ContentHandler DOMBuilder DOMException DOMImplementation DOMObject \
|
||||
DOMParser DOMSerializer DOMWriter DTDHandler DTDMap DeclHandler \
|
||||
DefaultHandler Document DocumentEvent DocumentFragment DocumentType \
|
||||
Element ElementsByTagNameList Entity EntityReference EntityResolver \
|
||||
|
@ -27,19 +27,10 @@ struct XML_API XMLStreamSerializerException:
|
||||
virtual ~XMLStreamSerializerException() throw ();
|
||||
|
||||
XMLStreamSerializerException(const std::string& name, const std::string& description);
|
||||
|
||||
XMLStreamSerializerException(const XMLStreamSerializer&, const std::string& description);
|
||||
|
||||
const char* name() const throw ()
|
||||
{
|
||||
return name_.c_str();
|
||||
}
|
||||
|
||||
const std::string& description() const
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
|
||||
const char* name() const throw ();
|
||||
const std::string& description() const;
|
||||
virtual const char* what() const throw ();
|
||||
|
||||
private:
|
||||
|
@ -2,7 +2,7 @@
|
||||
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
|
||||
// license : MIT; see accompanying LICENSE file
|
||||
|
||||
#include "QName.h"
|
||||
#include "Poco/XML/QName.h"
|
||||
#include <ostream>
|
||||
|
||||
using namespace std;
|
||||
|
@ -2,8 +2,8 @@
|
||||
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
|
||||
// license : MIT; see accompanying LICENSE file
|
||||
|
||||
#include "XMLStreamParser.h"
|
||||
#include "XMLStreamParserException.h"
|
||||
#include "Poco/XML/XMLStreamParser.h"
|
||||
#include "Poco/XML/XMLStreamParserException.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
|
||||
// license : MIT; see accompanying LICENSE file
|
||||
|
||||
#include "Poco/XML/XMLStreamParser.h"
|
||||
#include <new> // std::bad_alloc
|
||||
#include <cassert>
|
||||
#include <cstring> // std::strchr
|
||||
@ -9,33 +10,81 @@
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "XMLStreamParser.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Poco
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
// XMLStreamParser
|
||||
//
|
||||
|
||||
XMLStreamParser::~XMLStreamParser()
|
||||
{
|
||||
if (p_ != 0)
|
||||
XML_ParserFree (p_);
|
||||
XML_ParserFree(p_);
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamParser::init()
|
||||
{
|
||||
depth_ = 0;
|
||||
@ -85,9 +134,10 @@ void XMLStreamParser::init()
|
||||
XML_SetNamespaceDeclHandler(p_, &start_namespace_decl_, &end_namespace_decl_);
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamParser::handle_error()
|
||||
{
|
||||
XML_Error e(XML_GetErrorCode (p_));
|
||||
XML_Error e(XML_GetErrorCode(p_));
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if (state_ == state_next)
|
||||
@ -183,6 +193,7 @@ XMLStreamParser::EventType XMLStreamParser::next()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const string& XMLStreamParser::attribute(const QName& qn) const
|
||||
{
|
||||
if (const ElementEntry* e = getElement())
|
||||
@ -203,6 +214,7 @@ const string& XMLStreamParser::attribute(const QName& qn) const
|
||||
throw XMLStreamParserException(*this, "attribute '" + qn.string() + "' expected");
|
||||
}
|
||||
|
||||
|
||||
string XMLStreamParser::attribute(const QName& qn, const string& dv) const
|
||||
{
|
||||
if (const ElementEntry* e = getElement())
|
||||
@ -223,6 +235,7 @@ string XMLStreamParser::attribute(const QName& qn, const string& dv) const
|
||||
return dv;
|
||||
}
|
||||
|
||||
|
||||
bool XMLStreamParser::attributePresent(const QName& qn) const
|
||||
{
|
||||
if (const ElementEntry* e = getElement())
|
||||
@ -243,18 +256,21 @@ bool XMLStreamParser::attributePresent(const QName& qn) const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamParser::nextExpect(EventType e)
|
||||
{
|
||||
if (next() != e)
|
||||
throw XMLStreamParserException(*this, string(parser_event_str[e]) + " expected");
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamParser::nextExpect(EventType e, const string& ns, const string& n)
|
||||
{
|
||||
if (next() != e || namespace_() != ns || name() != n)
|
||||
throw XMLStreamParserException(*this, string(parser_event_str[e]) + " '" + QName(ns, n).string() + "' expected");
|
||||
}
|
||||
|
||||
|
||||
string XMLStreamParser::element()
|
||||
{
|
||||
content(Content::Simple);
|
||||
@ -278,6 +294,7 @@ string XMLStreamParser::element()
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
string XMLStreamParser::element(const QName& qn, const string& dv)
|
||||
{
|
||||
if (peek() == StartElement && qname() == qn)
|
||||
@ -289,6 +306,7 @@ string XMLStreamParser::element(const QName& qn, const string& dv)
|
||||
return dv;
|
||||
}
|
||||
|
||||
|
||||
const XMLStreamParser::ElementEntry* XMLStreamParser::get_element_() const
|
||||
{
|
||||
// The start_element_() Expat handler may have already provisioned
|
||||
@ -310,6 +328,7 @@ const XMLStreamParser::ElementEntry* XMLStreamParser::get_element_() const
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamParser::pop_element()
|
||||
{
|
||||
// Make sure there are no unhandled attributes left.
|
||||
@ -330,6 +349,7 @@ void XMLStreamParser::pop_element()
|
||||
element_state_.pop_back();
|
||||
}
|
||||
|
||||
|
||||
XMLStreamParser::EventType XMLStreamParser::next_(bool peek)
|
||||
{
|
||||
EventType e(next_body());
|
||||
@ -387,6 +407,7 @@ XMLStreamParser::EventType XMLStreamParser::next_(bool peek)
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
XMLStreamParser::EventType XMLStreamParser::next_body()
|
||||
{
|
||||
// See if we have any start namespace declarations we need to return.
|
||||
@ -487,9 +508,9 @@ XMLStreamParser::EventType XMLStreamParser::next_body()
|
||||
}
|
||||
// Fall through.
|
||||
}
|
||||
// The end namespace declaration comes before the end element
|
||||
// which means it can follow pretty much any other event.
|
||||
//
|
||||
// The end namespace declaration comes before the end element
|
||||
// which means it can follow pretty much any other event.
|
||||
//
|
||||
default:
|
||||
{
|
||||
event_ = EndNamespaceDecl;
|
||||
@ -521,51 +542,51 @@ XMLStreamParser::EventType XMLStreamParser::next_body()
|
||||
|
||||
switch (ps.parsing)
|
||||
{
|
||||
case XML_INITIALIZED:
|
||||
{
|
||||
// As if we finished the previous chunk.
|
||||
break;
|
||||
}
|
||||
case XML_PARSING:
|
||||
{
|
||||
assert(false);
|
||||
return event_ = Eof;
|
||||
}
|
||||
case XML_FINISHED:
|
||||
{
|
||||
return event_ = Eof;
|
||||
}
|
||||
case XML_SUSPENDED:
|
||||
{
|
||||
switch (XML_ResumeParser(p_))
|
||||
{
|
||||
case XML_STATUS_SUSPENDED:
|
||||
{
|
||||
// If the XMLStreamParser is again in the suspended state, then
|
||||
// that means we have the next event.
|
||||
//
|
||||
return event_;
|
||||
}
|
||||
case XML_STATUS_OK:
|
||||
{
|
||||
// Otherwise, we need to get and parse the next chunk of data
|
||||
// unless this was the last chunk, in which case this is eof.
|
||||
//
|
||||
if (ps.finalBuffer)
|
||||
return event_ = Eof;
|
||||
case XML_INITIALIZED:
|
||||
{
|
||||
// As if we finished the previous chunk.
|
||||
break;
|
||||
}
|
||||
case XML_PARSING:
|
||||
{
|
||||
assert(false);
|
||||
return event_ = Eof;
|
||||
}
|
||||
case XML_FINISHED:
|
||||
{
|
||||
return event_ = Eof;
|
||||
}
|
||||
case XML_SUSPENDED:
|
||||
{
|
||||
switch (XML_ResumeParser(p_))
|
||||
{
|
||||
case XML_STATUS_SUSPENDED:
|
||||
{
|
||||
// If the XMLStreamParser is again in the suspended state, then
|
||||
// that means we have the next event.
|
||||
//
|
||||
return event_;
|
||||
}
|
||||
case XML_STATUS_OK:
|
||||
{
|
||||
// Otherwise, we need to get and parse the next chunk of data
|
||||
// unless this was the last chunk, in which case this is eof.
|
||||
//
|
||||
if (ps.finalBuffer)
|
||||
return event_ = Eof;
|
||||
|
||||
break;
|
||||
}
|
||||
case XML_STATUS_ERROR:
|
||||
handle_error();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XML_STATUS_ERROR:
|
||||
handle_error();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get and parse the next chunk of data until we get the next event
|
||||
// or reach eof.
|
||||
//
|
||||
// Get and parse the next chunk of data until we get the next event
|
||||
// or reach eof.
|
||||
//
|
||||
if (!accumulate_)
|
||||
event_ = Eof;
|
||||
|
||||
@ -619,6 +640,7 @@ XMLStreamParser::EventType XMLStreamParser::next_body()
|
||||
return event_;
|
||||
}
|
||||
|
||||
|
||||
static void splitName(const XML_Char* s, QName& qn)
|
||||
{
|
||||
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)
|
||||
{
|
||||
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
|
||||
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
|
||||
|
||||
XML_ParsingStatus ps;
|
||||
XML_GetParsingStatus(p.p_, &ps);
|
||||
XML_ParsingStatus ps;
|
||||
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;
|
||||
// Expat has a (mis)-feature of a possibily calling handlers even
|
||||
// after the non-resumable XML_StopParser call.
|
||||
//
|
||||
if (ps.parsing == XML_FINISHED)
|
||||
return;
|
||||
|
||||
// Cannot be a followup event.
|
||||
//
|
||||
assert(ps.parsing == XML_PARSING);
|
||||
// Cannot be a followup event.
|
||||
//
|
||||
assert(ps.parsing == XML_PARSING);
|
||||
|
||||
// When accumulating characters in simple content, we expect to
|
||||
// see more characters or end element. Seeing start element is
|
||||
// possible but means violation of the content model.
|
||||
//
|
||||
if (p.accumulate_)
|
||||
{
|
||||
// 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);
|
||||
return;
|
||||
}
|
||||
// When accumulating characters in simple content, we expect to
|
||||
// see more characters or end element. Seeing start element is
|
||||
// possible but means violation of the content model.
|
||||
//
|
||||
if (p.accumulate_)
|
||||
{
|
||||
// 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);
|
||||
return;
|
||||
}
|
||||
|
||||
p.event_ = StartElement;
|
||||
splitName(name, p.qname_);
|
||||
p.event_ = StartElement;
|
||||
splitName(name, p.qname_);
|
||||
|
||||
p.line_ = XML_GetCurrentLineNumber(p.p_);
|
||||
p.column_ = XML_GetCurrentColumnNumber(p.p_);
|
||||
p.line_ = XML_GetCurrentLineNumber(p.p_);
|
||||
p.column_ = XML_GetCurrentColumnNumber(p.p_);
|
||||
|
||||
// Handle attributes.
|
||||
//
|
||||
if (*atts != 0)
|
||||
{
|
||||
bool am((p.feature_ & RECEIVE_ATTRIBUTE_MAP) != 0);
|
||||
bool ae((p.feature_ & RECEIVE_ATTRIBUTES_EVENT) != 0);
|
||||
// Handle attributes.
|
||||
//
|
||||
if (*atts != 0)
|
||||
{
|
||||
bool am((p.feature_ & RECEIVE_ATTRIBUTE_MAP) != 0);
|
||||
bool ae((p.feature_ & RECEIVE_ATTRIBUTES_EVENT) != 0);
|
||||
|
||||
// Provision an entry for this element.
|
||||
//
|
||||
ElementEntry* pe(0);
|
||||
if (am)
|
||||
{
|
||||
p.element_state_.push_back(ElementEntry(p.depth_ + 1));
|
||||
pe = &p.element_state_.back();
|
||||
}
|
||||
// Provision an entry for this element.
|
||||
//
|
||||
ElementEntry* pe(0);
|
||||
if (am)
|
||||
{
|
||||
p.element_state_.push_back(ElementEntry(p.depth_ + 1));
|
||||
pe = &p.element_state_.back();
|
||||
}
|
||||
|
||||
if (am || ae)
|
||||
{
|
||||
for (; *atts != 0; atts += 2)
|
||||
{
|
||||
if (am)
|
||||
{
|
||||
QName qn;
|
||||
splitName(*atts, qn);
|
||||
AttributeMapType::value_type v(qn, AttributeValueType());
|
||||
v.second.value = *(atts + 1);
|
||||
v.second.handled = false;
|
||||
pe->attr_map_.insert(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.attr_.push_back(attribute_type());
|
||||
splitName(*atts, p.attr_.back().qname);
|
||||
p.attr_.back().value = *(atts + 1);
|
||||
}
|
||||
}
|
||||
if (am || ae)
|
||||
{
|
||||
for (; *atts != 0; atts += 2)
|
||||
{
|
||||
if (am)
|
||||
{
|
||||
QName qn;
|
||||
splitName(*atts, qn);
|
||||
AttributeMapType::value_type v(qn, AttributeValueType());
|
||||
v.second.value = *(atts + 1);
|
||||
v.second.handled = false;
|
||||
pe->attr_map_.insert(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.attr_.push_back(attribute_type());
|
||||
splitName(*atts, p.attr_.back().qname);
|
||||
p.attr_.back().value = *(atts + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (am)
|
||||
pe->attr_unhandled_ = pe->attr_map_.size();
|
||||
}
|
||||
}
|
||||
if (am)
|
||||
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)
|
||||
{
|
||||
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
|
||||
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
|
||||
|
||||
XML_ParsingStatus ps;
|
||||
XML_GetParsingStatus(p.p_, &ps);
|
||||
XML_ParsingStatus ps;
|
||||
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;
|
||||
// Expat has a (mis)-feature of a possibily calling handlers even
|
||||
// after the non-resumable XML_StopParser call.
|
||||
//
|
||||
if (ps.parsing == XML_FINISHED)
|
||||
return;
|
||||
|
||||
// This can be a followup event for empty elements (<foo/>). In this
|
||||
// case the element name is already set.
|
||||
//
|
||||
if (ps.parsing != XML_PARSING)
|
||||
p.queue_ = EndElement;
|
||||
else
|
||||
{
|
||||
splitName(name, p.qname_);
|
||||
// This can be a followup event for empty elements (<foo/>). In this
|
||||
// case the element name is already set.
|
||||
//
|
||||
if (ps.parsing != XML_PARSING)
|
||||
p.queue_ = EndElement;
|
||||
else
|
||||
{
|
||||
splitName(name, p.qname_);
|
||||
|
||||
// If we are accumulating characters, then queue this event.
|
||||
//
|
||||
if (p.accumulate_)
|
||||
p.queue_ = EndElement;
|
||||
else
|
||||
{
|
||||
p.event_ = EndElement;
|
||||
// If we are accumulating characters, then queue this event.
|
||||
//
|
||||
if (p.accumulate_)
|
||||
p.queue_ = EndElement;
|
||||
else
|
||||
{
|
||||
p.event_ = EndElement;
|
||||
|
||||
p.line_ = XML_GetCurrentLineNumber(p.p_);
|
||||
p.column_ = XML_GetCurrentColumnNumber(p.p_);
|
||||
}
|
||||
p.line_ = XML_GetCurrentLineNumber(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;
|
||||
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
|
||||
void XMLCALL XMLStreamParser::characters_(void* v, const XML_Char* s, int n)
|
||||
{
|
||||
p.event_ = Characters;
|
||||
p.value_.assign(s, n);
|
||||
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
|
||||
|
||||
p.line_ = XML_GetCurrentLineNumber(p.p_);
|
||||
p.column_ = XML_GetCurrentColumnNumber(p.p_);
|
||||
XML_ParsingStatus ps;
|
||||
XML_GetParsingStatus(p.p_, &ps);
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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;
|
||||
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)
|
||||
{
|
||||
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
|
||||
XMLStreamParser& p(*static_cast<XMLStreamParser*>(v));
|
||||
|
||||
XML_ParsingStatus ps;
|
||||
XML_GetParsingStatus(p.p_, &ps);
|
||||
XML_ParsingStatus ps;
|
||||
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;
|
||||
// Expat has a (mis)-feature of a possibily calling handlers even
|
||||
// after the non-resumable XML_StopParser call.
|
||||
//
|
||||
if (ps.parsing == XML_FINISHED)
|
||||
return;
|
||||
|
||||
p.start_ns_.push_back(QName());
|
||||
p.start_ns_.back().prefix() = (prefix != 0 ? prefix : "");
|
||||
p.start_ns_.back().namespace_() = (ns != 0 ? ns : "");
|
||||
p.start_ns_.push_back(QName());
|
||||
p.start_ns_.back().prefix() = (prefix != 0 ? prefix : "");
|
||||
p.start_ns_.back().namespace_() = (ns != 0 ? ns : "");
|
||||
}
|
||||
|
||||
|
||||
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_GetParsingStatus(p.p_, &ps);
|
||||
XML_ParsingStatus ps;
|
||||
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;
|
||||
// Expat has a (mis)-feature of a possibily calling handlers even
|
||||
// after the non-resumable XML_StopParser call.
|
||||
//
|
||||
if (ps.parsing == XML_FINISHED)
|
||||
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 : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,8 @@
|
||||
/// All rights reserved.
|
||||
///
|
||||
|
||||
#include "XMLStreamParserException.h"
|
||||
#include "XMLStreamParser.h"
|
||||
#include "Poco/XML/XMLStreamParserException.h"
|
||||
#include "Poco/XML/XMLStreamParser.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -20,22 +20,26 @@ namespace Poco
|
||||
namespace XML
|
||||
{
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
XMLStreamParserException::XMLStreamParserException(const XMLStreamParser& p, const std::string& d)
|
||||
: name_(p.input_name()), line_(p.line()), column_(p.column()), description_(d)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamParserException::init()
|
||||
{
|
||||
std::ostringstream os;
|
||||
@ -45,10 +49,12 @@ void XMLStreamParserException::init()
|
||||
what_ = os.str();
|
||||
}
|
||||
|
||||
|
||||
char const* XMLStreamParserException::what() const throw ()
|
||||
{
|
||||
return what_.c_str();
|
||||
}
|
||||
|
||||
|
||||
} /* namespace XML */
|
||||
} /* namespace Poco */
|
||||
|
@ -2,8 +2,8 @@
|
||||
// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC
|
||||
// license : MIT; see accompanying LICENSE file
|
||||
|
||||
#include "XMLStreamSerializer.h"
|
||||
#include "XMLStreamSerializerException.h"
|
||||
#include "Poco/XML/XMLStreamSerializer.h"
|
||||
#include "Poco/XML/XMLStreamSerializerException.h"
|
||||
|
||||
#include <new> // std::bad_alloc
|
||||
#include <cstring> // std::strlen
|
||||
@ -14,8 +14,7 @@ namespace Poco
|
||||
{
|
||||
namespace XML
|
||||
{
|
||||
// XMLStreamSerializer
|
||||
//
|
||||
|
||||
extern "C" genxStatus genx_write(void* p, constUtf8 us)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
extern "C" genxStatus genx_write_bound(void* p, constUtf8 start, constUtf8 end)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
extern "C" genxStatus genx_flush(void* 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;
|
||||
}
|
||||
|
||||
|
||||
XMLStreamSerializer::~XMLStreamSerializer()
|
||||
{
|
||||
if (s_ != 0)
|
||||
genxDispose (s_);
|
||||
}
|
||||
|
||||
|
||||
XMLStreamSerializer::XMLStreamSerializer(ostream& os, const string& oname, unsigned short ind)
|
||||
: 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)
|
||||
{
|
||||
switch (e)
|
||||
@ -100,6 +104,7 @@ void XMLStreamSerializer::handleError(genxStatus e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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())))
|
||||
@ -108,6 +113,7 @@ void XMLStreamSerializer::startElement(const string& ns, const string& name)
|
||||
depth_++;
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamSerializer::endElement()
|
||||
{
|
||||
if (genxStatus e = genxEndElement(s_))
|
||||
@ -126,24 +132,28 @@ void XMLStreamSerializer::endElement()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamSerializer::element(const string& ns, const string& n, const string& v)
|
||||
{
|
||||
startElement(ns, n);
|
||||
element(v);
|
||||
}
|
||||
|
||||
|
||||
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())))
|
||||
handleError(e);
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamSerializer::endAttribute()
|
||||
{
|
||||
if (genxStatus e = genxEndAttribute(s_))
|
||||
handleError(e);
|
||||
}
|
||||
|
||||
|
||||
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()),
|
||||
@ -151,12 +161,14 @@ void XMLStreamSerializer::attribute(const string& ns, const string& name, const
|
||||
handleError(e);
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamSerializer::characters(const string& value)
|
||||
{
|
||||
if (genxStatus e = genxAddCountedText(s_, reinterpret_cast<constUtf8>(value.c_str()), value.size()))
|
||||
handleError(e);
|
||||
}
|
||||
|
||||
|
||||
void XMLStreamSerializer::namespaceDecl(const string& ns, const string& p)
|
||||
{
|
||||
if (genxStatus e =
|
||||
@ -166,6 +178,7 @@ void XMLStreamSerializer::namespaceDecl(const string& ns, const string& p)
|
||||
handleError(e);
|
||||
}
|
||||
|
||||
|
||||
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())),
|
||||
@ -173,6 +186,7 @@ void XMLStreamSerializer::xmlDecl(const string& ver, const string& enc, const st
|
||||
handleError(e);
|
||||
}
|
||||
|
||||
|
||||
bool XMLStreamSerializer::lookupNamespacePrefix(const string& ns, string& p)
|
||||
{
|
||||
// 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));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,8 @@
|
||||
/// All rights reserved.
|
||||
///
|
||||
|
||||
#include "XMLStreamParserException.h"
|
||||
#include "XMLStreamSerializer.h"
|
||||
#include "Poco/XML/XMLStreamParserException.h"
|
||||
#include "Poco/XML/XMLStreamSerializer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -20,8 +20,6 @@ namespace Poco
|
||||
namespace XML
|
||||
{
|
||||
|
||||
// XMLStreamSerializerException
|
||||
//
|
||||
XMLStreamSerializerException::~XMLStreamSerializerException() throw ()
|
||||
{
|
||||
}
|
||||
@ -33,7 +31,7 @@ XMLStreamSerializerException::XMLStreamSerializerException(const string& n, cons
|
||||
}
|
||||
|
||||
XMLStreamSerializerException::XMLStreamSerializerException(const XMLStreamSerializer& s, const std::string& d)
|
||||
: name_(s.outputName()), description_(d)
|
||||
: name_(s.outputName()), description_(d)
|
||||
{
|
||||
init();
|
||||
}
|
||||
@ -50,6 +48,19 @@ void XMLStreamSerializerException::init()
|
||||
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 ()
|
||||
{
|
||||
return what_.c_str();
|
||||
|
@ -11,7 +11,7 @@
|
||||
* This version is generated semi-automatically from the source code of the
|
||||
* 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)
|
||||
{
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "genx.h"
|
||||
#include "Poco/XML/genx.h"
|
||||
|
||||
#define Boolean int
|
||||
#define True 1
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user