aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2014-07-07 22:25:03 +0200
committerAdrian Kummerlaender2014-07-07 22:25:03 +0200
commit8f05c7de54336daefb214a754de35367098b6510 (patch)
treefc8d2b8309c88a1e57193784ad4f48bfa573952d
parentbe99b28838796ff5e1dc91685d6121a55d962a88 (diff)
downloadInputXSLT-8f05c7de54336daefb214a754de35367098b6510.tar
InputXSLT-8f05c7de54336daefb214a754de35367098b6510.tar.gz
InputXSLT-8f05c7de54336daefb214a754de35367098b6510.tar.bz2
InputXSLT-8f05c7de54336daefb214a754de35367098b6510.tar.lz
InputXSLT-8f05c7de54336daefb214a754de35367098b6510.tar.xz
InputXSLT-8f05c7de54336daefb214a754de35367098b6510.tar.zst
InputXSLT-8f05c7de54336daefb214a754de35367098b6510.zip
Implemented custom xercesc::DOMDocument deleter
* pointers to xercesc::DOMDocument were manually released ** this is now solved using a custom deleter for the appropriate std::unqiue_ptr template specialization * added matching factory method to DomDocumentCache * updated external function implementations accordingly ** "constructDocument" is now expected to return a DomDocumentCache::document_ptr instance * updated TransformerFacade accordingly * this change was implemented to get rid of the manual memory management required by xalan / xerces
-rw-r--r--ixslt.cc6
-rw-r--r--src/function/external_text_formatter.cc20
-rw-r--r--src/function/external_text_formatter.h2
-rw-r--r--src/function/read_directory.cc18
-rw-r--r--src/function/read_directory.h3
-rw-r--r--src/function/read_file.cc20
-rw-r--r--src/function/read_file.h3
-rw-r--r--src/function/transform.cc18
-rw-r--r--src/function/transform.h2
-rw-r--r--src/function/write_file.cc23
-rw-r--r--src/function/write_file.h2
-rw-r--r--src/support/dom/document_cache.cc28
-rw-r--r--src/support/dom/document_cache.h15
-rw-r--r--src/support/dom/document_cache_item.cc10
-rw-r--r--src/support/dom/document_cache_item.h6
-rw-r--r--src/transformer_facade.cc24
16 files changed, 95 insertions, 105 deletions
diff --git a/ixslt.cc b/ixslt.cc
index 048f990..610d28f 100644
--- a/ixslt.cc
+++ b/ixslt.cc
@@ -100,10 +100,10 @@ bool generate(
std::basic_ostream<char>& target,
Arguments&&... arguments
) {
- InputXSLT::TransformerFacade transformer(resolver);
- WarningGuard guard(&transformer);
-
try {
+ InputXSLT::TransformerFacade transformer(resolver);
+ WarningGuard guard(&transformer);
+
xalan::XalanStdOutputStream output(target);
xalan::XalanOutputStreamPrintWriter writer(output);
xalan::FormatterToXML formatter(writer);
diff --git a/src/function/external_text_formatter.cc b/src/function/external_text_formatter.cc
index e7ab1a2..a86c71b 100644
--- a/src/function/external_text_formatter.cc
+++ b/src/function/external_text_formatter.cc
@@ -2,9 +2,6 @@
#include <xalanc/XSLT/XSLTInputSource.hpp>
-#include <xercesc/dom/DOMDocument.hpp>
-#include <xercesc/dom/DOMImplementation.hpp>
-#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <boost/process.hpp>
@@ -42,16 +39,12 @@ inline xercesc::DOMNode* importDocumentElement(
namespace InputXSLT {
-xercesc::DOMDocument* FunctionExternalTextFormatter::constructDocument(
+DomDocumentCache::document_ptr FunctionExternalTextFormatter::constructDocument(
boost::filesystem::path formatterPath,
std::string stdinText
) {
- xercesc::DOMDocument* const domDocument(
- xercesc::DOMImplementation::getImplementation()->createDocument(
- nullptr,
- *XercesStringGuard<XMLCh>("content"),
- nullptr
- )
+ DomDocumentCache::document_ptr domDocument(
+ DomDocumentCache::createDocument()
);
xercesc::DOMNode* const rootNode(
@@ -78,14 +71,17 @@ xercesc::DOMDocument* FunctionExternalTextFormatter::constructDocument(
boost::process::status status = formatterProcess.wait();
- ResultNodeFacade result(domDocument, rootNode, "output");
+ ResultNodeFacade result(domDocument.get(), rootNode, "output");
result.setAttribute("formatter", formatterPath.filename().string());
result.setAttribute("code", std::to_string(status.exit_status()));
if ( status.exited() ) {
try {
result.setContent(
- importDocumentElement(outputStream, domDocument)->getChildNodes()
+ importDocumentElement(
+ outputStream,
+ domDocument.get()
+ )->getChildNodes()
);
result.setAttribute("result", "success");
diff --git a/src/function/external_text_formatter.h b/src/function/external_text_formatter.h
index 4a2fb7e..23e6ab9 100644
--- a/src/function/external_text_formatter.h
+++ b/src/function/external_text_formatter.h
@@ -18,7 +18,7 @@ class FunctionExternalTextFormatter : public FunctionBase<
protected:
friend FunctionBase;
- xercesc::DOMDocument* constructDocument(
+ DomDocumentCache::document_ptr constructDocument(
boost::filesystem::path,
std::string
);
diff --git a/src/function/read_directory.cc b/src/function/read_directory.cc
index d5357e8..ad82217 100644
--- a/src/function/read_directory.cc
+++ b/src/function/read_directory.cc
@@ -1,29 +1,21 @@
#include "read_directory.h"
-#include <xercesc/dom/DOMDocument.hpp>
-#include <xercesc/dom/DOMImplementation.hpp>
-#include <xercesc/dom/DOMElement.hpp>
-
#include "support/xerces_string_guard.h"
#include "support/dom/result_node_facade.h"
namespace InputXSLT {
-xercesc::DOMDocument* FunctionReadDirectory::constructDocument(
+DomDocumentCache::document_ptr FunctionReadDirectory::constructDocument(
boost::filesystem::path directoryPath) {
- xercesc::DOMDocument* const domDocument(
- xercesc::DOMImplementation::getImplementation()->createDocument(
- nullptr,
- *XercesStringGuard<XMLCh>("content"),
- nullptr
- )
+ DomDocumentCache::document_ptr domDocument(
+ DomDocumentCache::createDocument()
);
xercesc::DOMNode* const rootNode(
domDocument->getDocumentElement()
);
- ResultNodeFacade result(domDocument, rootNode, "directory");
+ ResultNodeFacade result(domDocument.get(), rootNode, "directory");
result.setAttribute("path", directoryPath.string());
if ( boost::filesystem::is_directory(directoryPath) ) {
@@ -34,7 +26,7 @@ xercesc::DOMDocument* FunctionReadDirectory::constructDocument(
FilesystemContext::iterate(
directoryPath,
[&domDocument, &resultNode](const boost::filesystem::path& p) {
- ResultNodeFacade result(domDocument, resultNode, "entry");
+ ResultNodeFacade result(domDocument.get(), resultNode, "entry");
switch ( boost::filesystem::status(p).type() ) {
case boost::filesystem::regular_file: {
diff --git a/src/function/read_directory.h b/src/function/read_directory.h
index 898132a..59ece1a 100644
--- a/src/function/read_directory.h
+++ b/src/function/read_directory.h
@@ -17,7 +17,8 @@ class FunctionReadDirectory : public FunctionBase<
protected:
friend FunctionBase;
- xercesc::DOMDocument* constructDocument(boost::filesystem::path);
+ DomDocumentCache::document_ptr constructDocument(
+ boost::filesystem::path);
};
diff --git a/src/function/read_file.cc b/src/function/read_file.cc
index f27a38e..cb1e57f 100644
--- a/src/function/read_file.cc
+++ b/src/function/read_file.cc
@@ -1,8 +1,5 @@
#include "read_file.h"
-#include <xercesc/dom/DOMDocument.hpp>
-#include <xercesc/dom/DOMImplementation.hpp>
-#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
@@ -62,21 +59,17 @@ boost::optional<std::string> readPlainFile(
namespace InputXSLT {
-xercesc::DOMDocument* FunctionReadFile::constructDocument(
+DomDocumentCache::document_ptr FunctionReadFile::constructDocument(
boost::filesystem::path filePath) {
- xercesc::DOMDocument* const domDocument(
- xercesc::DOMImplementation::getImplementation()->createDocument(
- nullptr,
- *XercesStringGuard<XMLCh>("content"),
- nullptr
- )
+ DomDocumentCache::document_ptr domDocument(
+ DomDocumentCache::createDocument()
);
xercesc::DOMNode* const rootNode(
domDocument->getDocumentElement()
);
- ResultNodeFacade result(domDocument, rootNode, "file");
+ ResultNodeFacade result(domDocument.get(), rootNode, "file");
result.setAttribute("path", filePath.string());
if ( boost::filesystem::is_regular_file(filePath) ) {
@@ -84,7 +77,10 @@ xercesc::DOMDocument* FunctionReadFile::constructDocument(
if ( isXmlFile(filePath) ) {
result.setAttribute("type", "xml");
- if ( auto importedNode = readXmlFile(filePath, domDocument) ) {
+ if ( auto importedNode = readXmlFile(
+ filePath,
+ domDocument.get())
+ ) {
result.setContent(*importedNode);
result.setAttribute("result", "success");
diff --git a/src/function/read_file.h b/src/function/read_file.h
index fdd70ac..3026c79 100644
--- a/src/function/read_file.h
+++ b/src/function/read_file.h
@@ -17,7 +17,8 @@ class FunctionReadFile : public FunctionBase<
protected:
friend FunctionBase;
- xercesc::DOMDocument* constructDocument(boost::filesystem::path);
+ DomDocumentCache::document_ptr constructDocument(
+ boost::filesystem::path);
};
diff --git a/src/function/transform.cc b/src/function/transform.cc
index e53b55f..c97897e 100644
--- a/src/function/transform.cc
+++ b/src/function/transform.cc
@@ -2,10 +2,6 @@
#include <xalanc/XercesParserLiaison/FormatterToXercesDOM.hpp>
-#include <xercesc/dom/DOMDocument.hpp>
-#include <xercesc/dom/DOMImplementation.hpp>
-#include <xercesc/dom/DOMElement.hpp>
-
#include "transformer_facade.h"
#include "support/xerces_string_guard.h"
#include "support/dom/result_node_facade.h"
@@ -30,28 +26,24 @@ inline void handleErrors(
namespace InputXSLT {
-xercesc::DOMDocument* FunctionTransform::constructDocument(
+DomDocumentCache::document_ptr FunctionTransform::constructDocument(
xalan::XSLTInputSource inputSource,
xalan::XSLTInputSource transformationSource
) {
- xercesc::DOMDocument* const domDocument(
- xercesc::DOMImplementation::getImplementation()->createDocument(
- nullptr,
- *XercesStringGuard<XMLCh>("content"),
- nullptr
- )
+ DomDocumentCache::document_ptr domDocument(
+ DomDocumentCache::createDocument()
);
xercesc::DOMElement* const rootElement(
domDocument->getDocumentElement()
);
- ResultNodeFacade result(domDocument, rootElement, "transformation");
+ ResultNodeFacade result(domDocument.get(), rootElement, "transformation");
TransformerFacade transformer(this->include_resolver_);
try {
xalan::FormatterToXercesDOM targetFormatter(
- domDocument,
+ domDocument.get(),
result.getResultElement()
);
diff --git a/src/function/transform.h b/src/function/transform.h
index b8e733d..95acba3 100644
--- a/src/function/transform.h
+++ b/src/function/transform.h
@@ -18,7 +18,7 @@ class FunctionTransform : public FunctionBase<
protected:
friend FunctionBase;
- xercesc::DOMDocument* constructDocument(
+ DomDocumentCache::document_ptr constructDocument(
xalan::XSLTInputSource,
xalan::XSLTInputSource
);
diff --git a/src/function/write_file.cc b/src/function/write_file.cc
index 024a87a..872160b 100644
--- a/src/function/write_file.cc
+++ b/src/function/write_file.cc
@@ -5,10 +5,6 @@
#include <xalanc/XMLSupport/FormatterToXML.hpp>
#include <xalanc/XMLSupport/FormatterTreeWalker.hpp>
-#include <xercesc/dom/DOMDocument.hpp>
-#include <xercesc/dom/DOMImplementation.hpp>
-#include <xercesc/dom/DOMElement.hpp>
-
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@@ -34,11 +30,10 @@ bool serializeNodeToFile(
if ( contentType == xalan::XalanNode::TEXT_NODE ) {
file << InputXSLT::toString(contentNode->getNodeValue());
} else {
- xalan::XalanStdOutputStream outputStream(file);
+ xalan::XalanStdOutputStream outputStream(file);
xalan::XalanOutputStreamPrintWriter outputWriter(outputStream);
-
- xalan::FormatterToXML formatter(outputWriter);
- xalan::FormatterTreeWalker walker(formatter);
+ xalan::FormatterToXML formatter(outputWriter);
+ xalan::FormatterTreeWalker walker(formatter);
formatter.startDocument();
@@ -62,23 +57,19 @@ bool serializeNodeToFile(
namespace InputXSLT {
-xercesc::DOMDocument* FunctionWriteFile::constructDocument(
+DomDocumentCache::document_ptr FunctionWriteFile::constructDocument(
boost::filesystem::path filePath,
xalan::XalanNode* const contentNode
) {
- xercesc::DOMDocument* const domDocument(
- xercesc::DOMImplementation::getImplementation()->createDocument(
- nullptr,
- *XercesStringGuard<XMLCh>("content"),
- nullptr
- )
+ DomDocumentCache::document_ptr domDocument(
+ DomDocumentCache::createDocument()
);
xercesc::DOMNode* const rootNode(
domDocument->getDocumentElement()
);
- ResultNodeFacade result(domDocument, rootNode, "file");
+ ResultNodeFacade result(domDocument.get(), rootNode, "file");
result.setAttribute("path", filePath.string());
if ( contentNode != nullptr ) {
diff --git a/src/function/write_file.h b/src/function/write_file.h
index 5fd9f3e..c1d6100 100644
--- a/src/function/write_file.h
+++ b/src/function/write_file.h
@@ -16,7 +16,7 @@ class FunctionWriteFile : public FunctionBase<
protected:
friend FunctionBase;
- xercesc::DOMDocument* constructDocument(
+ DomDocumentCache::document_ptr constructDocument(
boost::filesystem::path,
xalan::XalanNode* const
);
diff --git a/src/support/dom/document_cache.cc b/src/support/dom/document_cache.cc
index 0ad540c..23805b5 100644
--- a/src/support/dom/document_cache.cc
+++ b/src/support/dom/document_cache.cc
@@ -1,19 +1,43 @@
#include "document_cache.h"
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/dom/DOMImplementation.hpp>
+
#include <stdexcept>
+#include "support/xerces_string_guard.h"
+
namespace InputXSLT {
+auto DomDocumentCache::createDocument() -> document_ptr {
+ return document_ptr(
+ xercesc::DOMImplementation::getImplementation()->createDocument(
+ nullptr,
+ *XercesStringGuard<XMLCh>("content"),
+ nullptr
+ )
+ );
+}
+
DomDocumentCache::DomDocumentCache():
write_mutex_(),
cache_() { }
-xalan::XalanDocument* DomDocumentCache::create(xercesc::DOMDocument* document) {
+xalan::XalanDocument* DomDocumentCache::create(document_ptr&& document) {
std::lock_guard<std::mutex> guard(this->write_mutex_);
- this->cache_.emplace(new item(document));
+ this->cache_.emplace(
+ new item(
+ std::move(document)
+ )
+ );
return this->cache_.top()->getXalanDocument();
}
+void DomDocumentCache::document_deleter::operator()(
+ xercesc::DOMDocument* document) {
+ document->release();
+}
+
}
diff --git a/src/support/dom/document_cache.h b/src/support/dom/document_cache.h
index 1f9a9e3..3aeb332 100644
--- a/src/support/dom/document_cache.h
+++ b/src/support/dom/document_cache.h
@@ -14,10 +14,23 @@
namespace InputXSLT {
class DomDocumentCache {
+ class document_deleter {
+ friend std::unique_ptr<xercesc::DOMDocument, document_deleter>;
+
+ void operator()(xercesc::DOMDocument*);
+ };
+
public:
+ typedef std::unique_ptr<
+ xercesc::DOMDocument,
+ document_deleter
+ > document_ptr;
+
+ static document_ptr createDocument();
+
DomDocumentCache();
- xalan::XalanDocument* create(xercesc::DOMDocument*);
+ xalan::XalanDocument* create(document_ptr&&);
private:
class item;
diff --git a/src/support/dom/document_cache_item.cc b/src/support/dom/document_cache_item.cc
index 9798bfa..a684d97 100644
--- a/src/support/dom/document_cache_item.cc
+++ b/src/support/dom/document_cache_item.cc
@@ -2,20 +2,16 @@
namespace InputXSLT {
-DomDocumentCache::item::item(xercesc::DOMDocument* document):
+DomDocumentCache::item::item(document_ptr&& document):
+ document_(std::move(document)),
parser_(),
dom_support_(parser_),
- document_(document),
parsed_source_(
- document_,
+ document_.get(),
parser_,
dom_support_
) { }
-DomDocumentCache::item::~item() {
- this->document_->release();
-}
-
xalan::XalanDocument* DomDocumentCache::item::getXalanDocument() {
return this->parsed_source_.getDocument();
}
diff --git a/src/support/dom/document_cache_item.h b/src/support/dom/document_cache_item.h
index 13fddfc..ebc9172 100644
--- a/src/support/dom/document_cache_item.h
+++ b/src/support/dom/document_cache_item.h
@@ -14,19 +14,17 @@ namespace InputXSLT {
class DomDocumentCache::item {
public:
- ~item();
-
xalan::XalanDocument* getXalanDocument();
protected:
friend DomDocumentCache;
- item(xercesc::DOMDocument*);
+ item(document_ptr&&);
private:
+ document_ptr document_;
xalan::XercesParserLiaison parser_;
xalan::XercesDOMSupport dom_support_;
- xercesc::DOMDocument* const document_;
xalan::XercesDOMWrapperParsedSource parsed_source_;
};
diff --git a/src/transformer_facade.cc b/src/transformer_facade.cc
index 10c8c7a..76b68d6 100644
--- a/src/transformer_facade.cc
+++ b/src/transformer_facade.cc
@@ -11,10 +11,8 @@
#include <xalanc/XercesParserLiaison/XercesDOMSupport.hpp>
#include <xalanc/XalanTransformer/XercesDOMWrapperParsedSource.hpp>
-#include <xercesc/dom/DOMDocument.hpp>
-#include <xercesc/dom/DOMImplementation.hpp>
-
#include "support/xerces_string_guard.h"
+#include "support/dom/document_cache.h"
namespace InputXSLT {
@@ -59,19 +57,15 @@ void TransformerFacade::generate(
) {
ErrorCapacitor errorCapacitor(&this->error_multiplexer_);
- xercesc::DOMDocument* const inputDocument(
- xercesc::DOMImplementation::getImplementation()->createDocument(
- nullptr,
- *XercesStringGuard<XMLCh>("dummy"),
- nullptr
- )
+ DomDocumentCache::document_ptr inputDocument(
+ DomDocumentCache::createDocument()
);
xalan::XercesParserLiaison parserLiaison;
xalan::XercesDOMSupport domSupport(parserLiaison);
xalan::XercesDOMWrapperParsedSource inputParsedSource(
- inputDocument,
+ inputDocument.get(),
parserLiaison,
domSupport
);
@@ -82,8 +76,6 @@ void TransformerFacade::generate(
target
);
- inputDocument->release();
-
errorCapacitor.discharge();
}
@@ -94,12 +86,12 @@ void TransformerFacade::generate(
) {
ErrorCapacitor errorCapacitor(&this->error_multiplexer_);
- xercesc::DOMDocument* const inputDocument(
- xercesc::DOMImplementation::getImplementation()->createDocument()
+ DomDocumentCache::document_ptr inputDocument(
+ DomDocumentCache::createDocument()
);
xalan::FormatterToXercesDOM inputFormatter(
- inputDocument,
+ inputDocument.get(),
inputDocument->getDocumentElement()
);
@@ -121,8 +113,6 @@ void TransformerFacade::generate(
target
);
- inputDocument->release();
-
errorCapacitor.discharge();
}