summaryrefslogtreecommitdiff
path: root/sax/source/fastparser/fastparser.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sax/source/fastparser/fastparser.cxx')
-rw-r--r--sax/source/fastparser/fastparser.cxx19
1 files changed, 18 insertions, 1 deletions
diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx
index 38a4bbb750b4..e1d22d215f78 100644
--- a/sax/source/fastparser/fastparser.cxx
+++ b/sax/source/fastparser/fastparser.cxx
@@ -237,6 +237,7 @@ public:
private:
bool consume(EventList *);
void deleteUsedEvents();
+ void sendPendingCharacters();
sal_Int32 GetToken( const xmlChar* pName, sal_Int32 nameLen );
sal_Int32 GetTokenWithPrefix( const xmlChar* pPrefix, int prefixLen, const xmlChar* pName, int nameLen ) throw (::com::sun::star::xml::sax::SAXException);
@@ -257,6 +258,7 @@ private:
Entity *mpTop; /// std::stack::top() is amazingly slow => cache this.
::std::stack< Entity > maEntities; /// Entity stack for each call of parseStream().
+ OUString pendingCharacters; /// Data from characters() callback that needs to be sent.
};
} // namespace sax_fastparser
@@ -1048,6 +1050,8 @@ void FastSaxParserImpl::parse()
void FastSaxParserImpl::callbackStartElement(const xmlChar *localName , const xmlChar* prefix, const xmlChar* URI,
int numNamespaces, const xmlChar** namespaces, int numAttributes, int /*defaultedAttributes*/, const xmlChar **attributes)
{
+ if( !pendingCharacters.isEmpty())
+ sendPendingCharacters();
Entity& rEntity = getEntity();
if( rEntity.maNamespaceCount.empty() )
{
@@ -1154,6 +1158,8 @@ void FastSaxParserImpl::callbackStartElement(const xmlChar *localName , const xm
void FastSaxParserImpl::callbackEndElement( const xmlChar*, const xmlChar*, const xmlChar* )
{
+ if( !pendingCharacters.isEmpty())
+ sendPendingCharacters();
Entity& rEntity = getEntity();
assert( !rEntity.maNamespaceCount.empty() );
if( !rEntity.maNamespaceCount.empty() )
@@ -1172,9 +1178,20 @@ void FastSaxParserImpl::callbackEndElement( const xmlChar*, const xmlChar*, cons
void FastSaxParserImpl::callbackCharacters( const xmlChar* s, int nLen )
{
+ // SAX interface allows that the characters callback splits content of one XML node
+ // (e.g. because there's an entity that needs decoding), however for consumers it's
+ // simpler FastSaxParser's character callback provides the whole string at once,
+ // so merge data from possible multiple calls and send them at once (before the element
+ // ends or another one starts).
+ pendingCharacters += OUString( XML_CAST( s ), nLen, RTL_TEXTENCODING_UTF8 );
+}
+
+void FastSaxParserImpl::sendPendingCharacters()
+{
Entity& rEntity = getEntity();
Event& rEvent = rEntity.getEvent( CHARACTERS );
- rEvent.msChars = OUString( XML_CAST( s ), nLen, RTL_TEXTENCODING_UTF8);
+ rEvent.msChars = pendingCharacters;
+ pendingCharacters.clear();
if (rEntity.mbEnableThreads)
produce();
else