aboutsummaryrefslogtreecommitdiff
path: root/src/function/read_directory.cc
diff options
context:
space:
mode:
authorAdrian Kummerländer2014-04-26 11:21:10 +0200
committerAdrian Kummerländer2014-04-26 11:21:10 +0200
commit0b611b7bd28851fe8096b3d2c121c68e231ada11 (patch)
tree80352794dce96cec2b86659e5a8260fb9a7686c2 /src/function/read_directory.cc
parent938ed7622656c3494ae8fdb83bc2ad4b1f31d901 (diff)
downloadInputXSLT-0b611b7bd28851fe8096b3d2c121c68e231ada11.tar
InputXSLT-0b611b7bd28851fe8096b3d2c121c68e231ada11.tar.gz
InputXSLT-0b611b7bd28851fe8096b3d2c121c68e231ada11.tar.bz2
InputXSLT-0b611b7bd28851fe8096b3d2c121c68e231ada11.tar.lz
InputXSLT-0b611b7bd28851fe8096b3d2c121c68e231ada11.tar.xz
InputXSLT-0b611b7bd28851fe8096b3d2c121c68e231ada11.tar.zst
InputXSLT-0b611b7bd28851fe8096b3d2c121c68e231ada11.zip
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
Diffstat (limited to 'src/function/read_directory.cc')
-rw-r--r--src/function/read_directory.cc103
1 files changed, 60 insertions, 43 deletions
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 <xercesc/dom/DOMText.hpp>
#include <xercesc/util/XMLString.hpp>
+#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<std::stack<DomDocumentGuard>>()) { }
+ 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;
}