From 0b611b7bd28851fe8096b3d2c121c68e231ada11 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Sat, 26 Apr 2014 11:21:10 +0200 Subject: Implemented global DOM document cache * the plan to return XML-nodes from each external function requires a better way to manage the lifetime of many xerces DOM document instances and their support class instances ** this is why DomDocumentCache and DomDocumentCache::item were implemented ** based on std::map so we can easily access the result of old function calls * changed external read-directory function to return the children of the document node instead of the document node itself ** removes unnecessary cruft in function calls ** will make returning status codes alongside the function result more pleasing to the eye * updated test transformation to reflect new features --- src/function/read_directory.cc | 103 ++++++++++++++++++++++++----------------- src/function/read_directory.h | 12 ++--- 2 files changed, 63 insertions(+), 52 deletions(-) (limited to 'src/function') diff --git a/src/function/read_directory.cc b/src/function/read_directory.cc index 9711239..677aa1d 100644 --- a/src/function/read_directory.cc +++ b/src/function/read_directory.cc @@ -6,13 +6,15 @@ #include #include +#include "support/utility.h" #include "support/xerces_string_guard.h" namespace InputXSLT { -FunctionReadDirectory::FunctionReadDirectory(const FilesystemContext& context): +FunctionReadDirectory::FunctionReadDirectory(const FilesystemContext& context, + DomDocumentCache& cache): fs_context_(context), - documents_(std::make_shared>()) { } + document_cache_(cache) { } xalan::XObjectPtr FunctionReadDirectory::execute( xalan::XPathExecutionContext& executionContext, @@ -20,53 +22,68 @@ xalan::XObjectPtr FunctionReadDirectory::execute( const xalan::XObjectPtr argument, const xalan::Locator* ) const { - this->documents_->emplace("content"); - DomDocumentGuard& domDocument = this->documents_->top(); - - xercesc::DOMNode* const rootNode = domDocument->getDocumentElement(); + DomDocumentCache::item* const cachedDocument( + this->document_cache_.get(xalanToString(argument->str())) + ); - this->fs_context_.iterate( - argument->str(), - [&domDocument, &rootNode](const boost::filesystem::path& p) { - xercesc::DOMElement* const itemNode( - domDocument->createElement(*XercesStringGuard("item")) + if ( !cachedDocument->isFinalized() ) { + xercesc::DOMDocument* const domDocument( + cachedDocument->getXercesDocument() ); - switch ( boost::filesystem::status(p).type() ) { - case boost::filesystem::regular_file: { - itemNode->setAttribute( - *XercesStringGuard("type"), - *XercesStringGuard("file") - ); - - break; - }; - case boost::filesystem::directory_file: { - itemNode->setAttribute( - *XercesStringGuard("type"), - *XercesStringGuard("directory") - ); - - break; - }; - default: { - break; - }; - } - - xercesc::DOMText* const textNode( - domDocument->createTextNode( - *XercesStringGuard(p.filename().string()) - ) + xercesc::DOMNode* const rootNode( + domDocument->getDocumentElement() ); - itemNode->appendChild(textNode); - rootNode->appendChild(itemNode); - }); + this->fs_context_.iterate( + argument->str(), + [&domDocument, &rootNode](const boost::filesystem::path& p) { + xercesc::DOMElement* const itemNode( + domDocument->createElement(*XercesStringGuard("item")) + ); + + switch ( boost::filesystem::status(p).type() ) { + case boost::filesystem::regular_file: { + itemNode->setAttribute( + *XercesStringGuard("type"), + *XercesStringGuard("file") + ); + + break; + }; + case boost::filesystem::directory_file: { + itemNode->setAttribute( + *XercesStringGuard("type"), + *XercesStringGuard("directory") + ); + + break; + }; + default: { + break; + }; + } + + xercesc::DOMText* const textNode( + domDocument->createTextNode( + *XercesStringGuard(p.filename().string()) + ) + ); + + itemNode->appendChild(textNode); + rootNode->appendChild(itemNode); + }); + } + + xalan::XPathExecutionContext::BorrowReturnMutableNodeRefList nodeList( + executionContext + ); - return executionContext.getXObjectFactory().createNodeSet( - domDocument.finalize() + nodeList->addNodes( + *cachedDocument->getXalanDocument()->getDocumentElement()->getChildNodes() ); + + return executionContext.getXObjectFactory().createNodeSet(nodeList); } FunctionReadDirectory* FunctionReadDirectory::clone( @@ -76,7 +93,7 @@ FunctionReadDirectory* FunctionReadDirectory::clone( const xalan::XalanDOMString& FunctionReadDirectory::getError( xalan::XalanDOMString& result) const { - result.assign("The read-directory() function expects one argument."); + result.assign("The read-directory() function expects one argument of type string."); return result; } diff --git a/src/function/read_directory.h b/src/function/read_directory.h index 782ebed..3fcf389 100644 --- a/src/function/read_directory.h +++ b/src/function/read_directory.h @@ -6,18 +6,15 @@ #include #include -#include -#include - #include "common.h" #include "support/filesystem_context.h" -#include "support/dom_document_guard.h" +#include "support/dom/document_cache.h" namespace InputXSLT { class FunctionReadDirectory : public xalan::Function { public: - FunctionReadDirectory(const FilesystemContext&); + FunctionReadDirectory(const FilesystemContext&, DomDocumentCache&); virtual xalan::XObjectPtr execute( xalan::XPathExecutionContext&, @@ -33,10 +30,7 @@ class FunctionReadDirectory : public xalan::Function { private: const FilesystemContext& fs_context_; - - std::shared_ptr< - std::stack - > documents_; + DomDocumentCache& document_cache_; const xalan::XalanDOMString& getError(xalan::XalanDOMString&) const; -- cgit v1.2.3