UT_Error UT_XML::parse (const char * szFilename) { UT_ASSERT (m_pListener || m_pExpertListener); UT_ASSERT (szFilename); if ((szFilename == 0) || ((m_pListener == 0) && (m_pExpertListener == 0))) return UT_ERROR; if (!reset_all ()) return UT_OUTOFMEM; UT_Error ret = UT_OK; DefaultReader defaultReader; Reader * reader = &defaultReader; if (m_pReader) reader = m_pReader; if (!reader->openFile (szFilename)) { UT_DEBUGMSG (("Could not open file %s\n", szFilename)); return UT_errnoToUTError (); } char buffer[2048]; m_bStopped = false; xmlSAXHandler hdl; xmlParserCtxtPtr ctxt = 0; memset(&hdl, 0, sizeof(hdl)); hdl.getEntity = _getEntity; hdl.startElement = _startElement; hdl.endElement = _endElement; hdl.characters = _charData; hdl.error = _errorSAXFunc; hdl.fatalError = _fatalErrorSAXFunc; hdl.processingInstruction = _processingInstruction; hdl.comment = _comment; hdl.cdataBlock = _cdata; size_t length = reader->readBytes (buffer, sizeof (buffer)); int done = (length < sizeof (buffer)); if (length != 0) { ctxt = xmlCreatePushParserCtxt (&hdl, static_cast<void *>(this), buffer, static_cast<int>(length), szFilename); if (ctxt == NULL) { UT_DEBUGMSG (("Unable to create libxml2 push-parser context!\n")); reader->closeFile (); return UT_ERROR; } xmlSubstituteEntitiesDefault (1); UT_sint32 chucks = -1; while (!done && !m_bStopped) { chucks++; length = reader->readBytes (buffer, sizeof (buffer)); UT_DEBUGMSG(("Done chunk %d length %zd \n",chucks,length)); done = (length < sizeof (buffer)); if (xmlParseChunk (ctxt, buffer, static_cast<int>(length), 0)) { if(getNumMinorErrors() > getNumRecoveredErrors()) { UT_DEBUGMSG (("Error - 1 parsing '%s' (Line: %d, Column: %d)\n", szFilename, xmlSAX2GetLineNumber(ctxt), xmlSAX2GetColumnNumber(ctxt))); ret = UT_IE_IMPORTERROR; break; } } } if (ret == UT_OK) if (!m_bStopped && (getNumMinorErrors() == 0)) { if (xmlParseChunk (ctxt, "", 0, 1)) { UT_DEBUGMSG (("Error -2 parsing '%s' (Line: %d, Column: %d)\n", szFilename, xmlSAX2GetLineNumber(ctxt), xmlSAX2GetColumnNumber(ctxt))); ret = UT_IE_IMPORTERROR; } } if (ret == UT_OK && (getNumMinorErrors() == 0)) if (!ctxt->wellFormed && !m_bStopped) ret = UT_IE_IMPORTERROR; // How does stopping mid-file affect wellFormed? xmlDocPtr myXmlDoc = ctxt->myDoc; xmlFreeParserCtxt (ctxt); xmlFreeDoc(myXmlDoc); } else { UT_DEBUGMSG(("Empty file to parse - not sure how to proceed\n")); } reader->closeFile (); return ret; }