[ http://issues.apache.org/jira/browse/XERCESC-1607?page=comments#action_12417734 ]
Tobias Schuette commented on XERCESC-1607: ------------------------------------------ if you don't already know, this behaviour is caused by the buffer refreshing strategy used in XMLReader::xcodeMoreChars, which tries to load another batch of raw bytes if the bytes left in the buffer is under the magic value of 100. > 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]
