24#include <libxml/xmlerror.h>
35#include <com/sun/star/xml/sax/SAXParseException.hpp>
36#include <com/sun/star/ucb/XCommandEnvironment.hpp>
37#include <com/sun/star/task/XInteractionHandler.hpp>
38#include <com/sun/star/ucb/SimpleFileAccess.hpp>
45using namespace css::io;
46using namespace css::lang;
47using namespace css::ucb;
48using namespace css::uno;
49using namespace css::xml::dom;
50using namespace css::xml::sax;
52using css::task::XInteractionHandler;
53using css::xml::sax::InputSource;
60 class CDefaultEntityResolver :
public cppu::WeakImplHelper< XEntityResolver >
63 virtual InputSource SAL_CALL resolveEntity(
const OUString& sPublicId,
const OUString& sSystemId )
override
66 is.sPublicId = sPublicId;
67 is.sSystemId = sSystemId;
71 Reference< XCommandEnvironment > aEnvironment(
73 Reference< XProgressHandler >() ));
76 is.aInputStream = aContent.openStream();
77 }
catch (
const css::uno::Exception&) {
79 is.aInputStream.clear();
89 : m_xEntityResolver(new CDefaultEntityResolver)
99 return {
"com.sun.star.xml.dom.DocumentBuilder" };
104 return "com.sun.star.comp.xml.dom.DocumentBuilder";
115 return Reference< XDOMImplementation >();
130 std::scoped_lock
const g(
m_Mutex);
133 xmlDocPtr pDocument = xmlNewDoc(
reinterpret_cast<const xmlChar*
>(
"1.0"));
139 return OUString(ctxt->lastError.message, strlen(ctxt->lastError.message), RTL_TEXTENCODING_ASCII_US) +
141 OUString::number(
static_cast<sal_Int32
>(ctxt->lastError.line)) +
143 OUString::number(
static_cast<sal_Int32
>(ctxt->lastError.int2));
153 typedef struct context {
164 context_t *pctx =
static_cast<context_t*
>(context);
165 if (!pctx->rInputStream.is())
170 int nread = pctx->rInputStream->readBytes(chunk, len);
173 memcpy(buffer, chunk.getConstArray(), nread);
175 }
catch (
const css::uno::Exception&) {
184 context_t *pctx =
static_cast<context_t*
>(context);
185 if (!pctx->rInputStream.is())
190 pctx->rInputStream->closeInput();
191 if (pctx->freeOnClose)
194 }
catch (
const css::uno::Exception&) {
201 const xmlChar *publicId,
202 const xmlChar *systemId)
205 xmlParserCtxtPtr ctxt =
static_cast<xmlParserCtxtPtr
>(
ctx);
209 if (systemId !=
nullptr)
210 sysid = OUString(
reinterpret_cast<char const *
>(systemId), strlen(
reinterpret_cast<char const *
>(systemId)), RTL_TEXTENCODING_UTF8);
212 if (publicId !=
nullptr)
213 pubid = OUString(
reinterpret_cast<char const *
>(publicId), strlen(
reinterpret_cast<char const *
>(publicId)), RTL_TEXTENCODING_UTF8);
216 InputSource src =
resolver->resolveEntity(pubid, sysid);
221 context_t *c =
new context_t;
222 c->rInputStream = src.aInputStream;
224 c->freeOnClose =
true;
227 xmlParserInputBufferPtr pBuffer =
229 xmlParserInputPtr pInput =
230 xmlNewIOInputStream(ctxt, pBuffer, XML_CHAR_ENCODING_NONE);
235 static xmlParserInputPtr external_entity_loader(
const char *URL,
const char * , xmlParserCtxtPtr ctxt)
247 xmlParserCtxtPtr
const pctx =
static_cast<xmlParserCtxtPtr
>(
ctx);
259 css::xml::sax::SAXParseException saxex;
261 saxex.LineNumber =
static_cast<sal_Int32
>(pctx->lastError.line);
262 saxex.ColumnNumber =
static_cast<sal_Int32
>(pctx->lastError.int2);
268 catch (
const css::uno::Exception &)
280 xmlParserCtxtPtr
const pctx =
static_cast<xmlParserCtxtPtr
>(
ctx);
291 css::xml::sax::SAXParseException saxex;
293 saxex.LineNumber =
static_cast<sal_Int32
>(pctx->lastError.line);
294 saxex.ColumnNumber =
static_cast<sal_Int32
>(pctx->lastError.int2);
300 catch (
const css::uno::Exception &)
310 css::xml::sax::SAXParseException saxex;
312 saxex.LineNumber =
static_cast<sal_Int32
>(ctxt->lastError.line);
313 saxex.ColumnNumber =
static_cast<sal_Int32
>(ctxt->lastError.int2);
319 struct XmlFreeParserCtxt {
320 void operator ()(xmlParserCtxt * p)
const { xmlFreeParserCtxt(p); }
331 std::scoped_lock
const g(
m_Mutex);
339 c.freeOnClose =
false;
341 std::unique_ptr<xmlParserCtxt, XmlFreeParserCtxt>
const pContext(
346 pContext->_private =
this;
351 xmlDocPtr
const pDoc = xmlCtxtReadIO(pContext.get(),
354 if (pDoc ==
nullptr) {
362 std::scoped_lock
const g(
m_Mutex);
364 std::unique_ptr<xmlParserCtxt, XmlFreeParserCtxt>
const pContext(
366 pContext->_private =
this;
372 char *uri =
const_cast<char*
>(oUri.getStr());
373 xmlDocPtr pDoc = xmlCtxtReadFile(pContext.get(), uri,
nullptr, 0);
375 Reference< XDocument > xRet;
379 if (pDoc ==
nullptr) {
380 Reference < XSimpleFileAccess3 > xStreamAccess(
382 Reference< XInputStream > xInStream = xStreamAccess->openFileRead( sUri );
387 xRet =
parse( xInStream );
389 xInStream->closeInput();
401 std::scoped_lock
const g(
m_Mutex);
408 std::scoped_lock
const g(
m_Mutex);
416 std::scoped_lock
const g(
m_Mutex);
422extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
424 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any>
const&)
const css::uno::Reference< css::xml::sax::XErrorHandler > & getErrorHandler() const
virtual OUString SAL_CALL getImplementationName() override
virtual sal_Bool SAL_CALL isNamespaceAware() override
Indicates whether or not this parser is configured to understand namespaces.
virtual void SAL_CALL setErrorHandler(const css::uno::Reference< css::xml::sax::XErrorHandler > &eh) override
Specify the ErrorHandler to be used to report errors present in the XML document to be parsed.
std::recursive_mutex m_Mutex
css::uno::Reference< css::xml::sax::XEntityResolver > getEntityResolver()
virtual css::uno::Reference< css::xml::dom::XDocument > SAL_CALL parseURI(const OUString &uri) override
Parse the content of the given URI as an XML document and return a new DOM Document object.
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual void SAL_CALL setEntityResolver(const css::uno::Reference< css::xml::sax::XEntityResolver > &er) override
Specify the EntityResolver to be used to resolve entities present in the XML document to be parsed.
virtual sal_Bool SAL_CALL isValidating() override
Indicates whether or not this parser is configured to validate XML documents.
virtual css::uno::Reference< css::xml::dom::XDocument > SAL_CALL newDocument() override
Obtain a new instance of a DOM Document object to build a DOM tree with.
css::uno::Reference< css::xml::sax::XErrorHandler > m_xErrorHandler
virtual css::uno::Reference< css::xml::dom::XDocument > SAL_CALL parse(const css::uno::Reference< css::io::XInputStream > &is) override
Parse the content of the given InputStream as an XML document and return a new DOM Document object.
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
css::uno::Reference< css::xml::sax::XEntityResolver > m_xEntityResolver
virtual css::uno::Reference< css::xml::dom::XDOMImplementation > SAL_CALL getDOMImplementation() override
Obtain an instance of a DOMImplementation object.
static ::rtl::Reference< CDocument > CreateCDocument(xmlDocPtr const pDoc)
factory: only way to create instance!
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< XInputStream > rInputStream
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * unoxml_CDocumentBuilder_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
static void throwEx(xmlParserCtxtPtr ctxt)
static int xmlIO_close_func(void *context)
static OUString make_error_message(xmlParserCtxtPtr ctxt)
static int xmlIO_read_func(void *context, char *buffer, int len)
static xmlParserInputPtr resolve_func(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
static void warning_func(void *ctx, const char *,...)
static void error_func(void *ctx, const char *,...)
Reference< XComponentContext > getProcessComponentContext()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)