From 8f05c7de54336daefb214a754de35367098b6510 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 7 Jul 2014 22:25:03 +0200 Subject: 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 --- ixslt.cc | 6 +++--- src/function/external_text_formatter.cc | 20 ++++++++------------ src/function/external_text_formatter.h | 2 +- src/function/read_directory.cc | 18 +++++------------- src/function/read_directory.h | 3 ++- src/function/read_file.cc | 20 ++++++++------------ src/function/read_file.h | 3 ++- src/function/transform.cc | 18 +++++------------- src/function/transform.h | 2 +- src/function/write_file.cc | 23 +++++++---------------- src/function/write_file.h | 2 +- src/support/dom/document_cache.cc | 28 ++++++++++++++++++++++++++-- src/support/dom/document_cache.h | 15 ++++++++++++++- src/support/dom/document_cache_item.cc | 10 +++------- src/support/dom/document_cache_item.h | 6 ++---- src/transformer_facade.cc | 24 +++++++----------------- 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& 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 -#include -#include -#include #include #include @@ -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("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 -#include -#include - #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("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 -#include -#include #include #include @@ -62,21 +59,17 @@ boost::optional 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("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 -#include -#include -#include - #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("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 #include -#include -#include -#include - #include #include @@ -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("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 +#include + #include +#include "support/xerces_string_guard.h" + namespace InputXSLT { +auto DomDocumentCache::createDocument() -> document_ptr { + return document_ptr( + xercesc::DOMImplementation::getImplementation()->createDocument( + nullptr, + *XercesStringGuard("content"), + nullptr + ) + ); +} + DomDocumentCache::DomDocumentCache(): write_mutex_(), cache_() { } -xalan::XalanDocument* DomDocumentCache::create(xercesc::DOMDocument* document) { +xalan::XalanDocument* DomDocumentCache::create(document_ptr&& document) { std::lock_guard 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; + + 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 #include -#include -#include - #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("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(); } -- cgit v1.2.3