SAX events not fired when they could be
---------------------------------------
Key: XERCESC-1607
URL: http://issues.apache.org/jira/browse/XERCESC-1607
Project: Xerces-C++
Type: Bug
Components: SAX/SAX2
Versions: 2.5.0, 2.7.0
Environment: Solaris 2.8, 2.10 SPARC - Sun Studio 11
Reporter: Gary Hughes
If a BinInputStream returns a valid fragment of XML that should generate SAX
parse events it does not necessarily do so before called readBytes again, if
the BinInputStream blocks on the subsequent read the XML already returned is
not processed as soon as it could be. This is not a problem when reading a file
as the XML is eventually processed when EOF is reached however if the XML is
being streamed across a socket the BinInputStream never reaches EOF and the XML
is not processed.
Sample program follows, see the comments in BinInputStream::readBytes, error
checking etc is largely ignored for brevity.
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/framework/XMLPScanToken.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <iostream>
#include <algorithm>
#include <unistd.h>
class Handler: public XERCES_CPP_NAMESPACE::DefaultHandler
{
void warning(const XERCES_CPP_NAMESPACE::SAXParseException& exception)
{
std::cout << "WARNING: " <<
XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage()) <<
std::endl;
}
void error(const XERCES_CPP_NAMESPACE::SAXParseException& exception)
{
std::cout << "ERROR: " <<
XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage()) <<
std::endl;
}
void fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exception)
{
std::cout << "FATAL ERROR: " <<
XERCES_CPP_NAMESPACE::XMLString::transcode(exception.getMessage()) <<
std::endl;
}
void endElement(const XMLCh* const uri, const XMLCh* const localname, const
XMLCh* const qname)
{
std::cout << "END ELEMENT" << std::endl;
}
void startDocument()
{
std::cout << "START DOCUMENT" << std::endl;
}
void startElement(const XMLCh* const uri, const XMLCh* const localname,
const XMLCh* const qname, const XERCES_CPP_NAMESPACE::Attributes& attrs)
{
std::cout << "START ELEMENT" << std::endl;
}
};
class BinInputStream : public XERCES_CPP_NAMESPACE::BinInputStream
{
public:
bool getIsOpen() const
{
return true;
}
unsigned int curPos() const
{
return 0;
}
unsigned int readBytes(XMLByte* const toFill,
const unsigned int maxToRead)
{
//
// The first time this is called we return some valid XML which
// should cause the parser to fire events. The second time it is
// called we sleep to simulate a blocking read.
//
// Even though the parser has a valid chunk of XML it does not
// fire any events other than start document.
//
// If the sleep is removed the parser gets EOF and fires the
// events as expected.
//
static size_t callCount = 0;
if(callCount > 0)
{
sleep(10000);
return 0;
}
++callCount;
std::string xml
(
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"
"<document>"
" <element/>"
"</document>"
);
std::copy(xml.begin(),
xml.end(),
toFill);
return xml.size();
}
};
class InputSource : public XERCES_CPP_NAMESPACE::InputSource
{
public:
virtual XERCES_CPP_NAMESPACE::BinInputStream* makeStream() const
{
return new BinInputStream;
}
};
int main(int argc, char** argv)
{
XERCES_CPP_NAMESPACE::XMLPlatformUtils::Initialize();
XERCES_CPP_NAMESPACE::SAX2XMLReader* reader =
XERCES_CPP_NAMESPACE::XMLReaderFactory::createXMLReader();
Handler* handler = new Handler;
reader->setContentHandler(handler);
reader->setErrorHandler(handler);
XERCES_CPP_NAMESPACE::XMLPScanToken scanToken;
InputSource* inputSource = new InputSource;
if(!reader->parseFirst(*inputSource, scanToken))
return 1;
while(reader->parseNext(scanToken));
return 0;
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]