diff options
author | Adrian Kummerländer | 2014-05-03 22:04:16 +0200 |
---|---|---|
committer | Adrian Kummerländer | 2014-05-03 22:04:16 +0200 |
commit | 261170cc5b6661106877dc2611dab281f4d91348 (patch) | |
tree | 8482f249c090af5ca462f7e36a4b87082185f027 /src/function | |
parent | e5ed418907f09bf8905463f42a44593d51159bc9 (diff) | |
download | InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.gz InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.bz2 InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.lz InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.xz InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.zst InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.zip |
Revamped DomDocumentCache with regard to thread safety
* DomDocumentCache::item class now is _finalized_ by default and doesn't perform document instantiation, just lifetime management
** xercesc::DOMDocument is instantiated inside the external function implementations and committed to the document cache for conversion to a xalan document
* added mutex with scoped lock to prevent concurrent write access to the std::unordered_map contained withing DomDocumentCache
* functionality of the _get_ member method was split into _get_ and _create_
** added typedef for std::pair specialization type "optional_item" that functions as the return value of _create_ and _get_
* "locator->getSystemId()" was leaking memory as xerces doesn't manage the lifetime of the returned heap-allocated char array
** analog to XMLCh* strings
** transformed XercesStringGuard into template class to be instantiated on either XMLCh or char
Diffstat (limited to 'src/function')
-rw-r--r-- | src/function/read_directory.cc | 43 | ||||
-rw-r--r-- | src/function/read_file.cc | 35 | ||||
-rw-r--r-- | src/function/read_xml_file.cc | 33 |
3 files changed, 78 insertions, 33 deletions
diff --git a/src/function/read_directory.cc b/src/function/read_directory.cc index b13be2b..f8f99d6 100644 --- a/src/function/read_directory.cc +++ b/src/function/read_directory.cc @@ -21,7 +21,11 @@ xalan::XObjectPtr FunctionReadDirectory::execute( ) const { const FilesystemContext fs_context( boost::filesystem::path( - xercesc::XMLString::transcode(locator->getSystemId() + 7) + *XercesStringGuard<char>( + xercesc::XMLString::transcode( + locator->getSystemId() + 7 + ) + ) ).parent_path().string() ); @@ -29,13 +33,17 @@ xalan::XObjectPtr FunctionReadDirectory::execute( fs_context.resolve(argument->str()) ); - DomDocumentCache::item* const cachedDocument( + DomDocumentCache::optional_item optionalCachedDocument( this->document_cache_->get(directoryPath.string()) ); - if ( !cachedDocument->isFinalized() ) { + if ( !optionalCachedDocument.first ) { xercesc::DOMDocument* const domDocument( - cachedDocument->getXercesDocument() + xercesc::DOMImplementation::getImplementation()->createDocument( + nullptr, + *XercesStringGuard<XMLCh>("content"), + nullptr + ) ); xercesc::DOMNode* const rootNode( @@ -47,30 +55,30 @@ xalan::XObjectPtr FunctionReadDirectory::execute( argument->str(), [&domDocument, &rootNode](const boost::filesystem::path& p) { xercesc::DOMElement* const itemNode( - domDocument->createElement(*XercesStringGuard("result")) + domDocument->createElement(*XercesStringGuard<XMLCh>("result")) ); switch ( boost::filesystem::status(p).type() ) { case boost::filesystem::regular_file: { itemNode->setAttribute( - *XercesStringGuard("type"), - *XercesStringGuard("file") + *XercesStringGuard<XMLCh>("type"), + *XercesStringGuard<XMLCh>("file") ); break; }; case boost::filesystem::directory_file: { itemNode->setAttribute( - *XercesStringGuard("type"), - *XercesStringGuard("directory") + *XercesStringGuard<XMLCh>("type"), + *XercesStringGuard<XMLCh>("directory") ); break; }; default: { itemNode->setAttribute( - *XercesStringGuard("type"), - *XercesStringGuard("misc") + *XercesStringGuard<XMLCh>("type"), + *XercesStringGuard<XMLCh>("misc") ); break; @@ -79,7 +87,7 @@ xalan::XObjectPtr FunctionReadDirectory::execute( xercesc::DOMText* const textNode( domDocument->createTextNode( - *XercesStringGuard(p.filename().string()) + *XercesStringGuard<XMLCh>(p.filename().string()) ) ); @@ -88,11 +96,16 @@ xalan::XObjectPtr FunctionReadDirectory::execute( }); } else { xercesc::DOMElement* const resultNode( - domDocument->createElement(*XercesStringGuard("error")) + domDocument->createElement(*XercesStringGuard<XMLCh>("error")) ); rootNode->appendChild(resultNode); } + + optionalCachedDocument = this->document_cache_->create( + directoryPath.string(), + domDocument + ); } xalan::XPathExecutionContext::BorrowReturnMutableNodeRefList nodeList( @@ -100,7 +113,9 @@ xalan::XObjectPtr FunctionReadDirectory::execute( ); nodeList->addNodes( - *cachedDocument->getXalanDocument()->getDocumentElement()->getChildNodes() + *optionalCachedDocument.second->getXalanDocument() + ->getDocumentElement() + ->getChildNodes() ); return executionContext.getXObjectFactory().createNodeSet(nodeList); diff --git a/src/function/read_file.cc b/src/function/read_file.cc index 7634d54..633559e 100644 --- a/src/function/read_file.cc +++ b/src/function/read_file.cc @@ -36,7 +36,11 @@ xalan::XObjectPtr FunctionReadFile::execute( ) const { const FilesystemContext fs_context( boost::filesystem::path( - xercesc::XMLString::transcode(locator->getSystemId() + 7) + *XercesStringGuard<char>( + xercesc::XMLString::transcode( + locator->getSystemId() + 7 + ) + ) ).parent_path().string() ); @@ -44,13 +48,17 @@ xalan::XObjectPtr FunctionReadFile::execute( fs_context.resolve(argument->str()) ); - DomDocumentCache::item* const cachedDocument( + DomDocumentCache::optional_item optionalCachedDocument( this->document_cache_->get(filePath.string()) ); - if ( !cachedDocument->isFinalized() ) { + if ( !optionalCachedDocument.first ) { xercesc::DOMDocument* const domDocument( - cachedDocument->getXercesDocument() + xercesc::DOMImplementation::getImplementation()->createDocument( + nullptr, + *XercesStringGuard<XMLCh>("content"), + nullptr + ) ); xercesc::DOMNode* const rootNode( @@ -59,17 +67,17 @@ xalan::XObjectPtr FunctionReadFile::execute( if ( boost::filesystem::is_regular_file(filePath) ) { xercesc::DOMElement* const resultNode( - domDocument->createElement(*XercesStringGuard("result")) + domDocument->createElement(*XercesStringGuard<XMLCh>("result")) ); resultNode->setAttribute( - *XercesStringGuard("name"), - *XercesStringGuard(filePath.filename().string()) + *XercesStringGuard<XMLCh>("name"), + *XercesStringGuard<XMLCh>(filePath.filename().string()) ); xercesc::DOMText* const resultTextNode( domDocument->createTextNode( - *XercesStringGuard(readFile(filePath)) + *XercesStringGuard<XMLCh>(readFile(filePath)) ) ); @@ -77,11 +85,16 @@ xalan::XObjectPtr FunctionReadFile::execute( rootNode->appendChild(resultNode); } else { xercesc::DOMElement* const resultNode( - domDocument->createElement(*XercesStringGuard("error")) + domDocument->createElement(*XercesStringGuard<XMLCh>("error")) ); rootNode->appendChild(resultNode); } + + optionalCachedDocument = this->document_cache_->create( + filePath.string(), + domDocument + ); } xalan::XPathExecutionContext::BorrowReturnMutableNodeRefList nodeList( @@ -89,7 +102,9 @@ xalan::XObjectPtr FunctionReadFile::execute( ); nodeList->addNodes( - *cachedDocument->getXalanDocument()->getDocumentElement()->getChildNodes() + *optionalCachedDocument.second->getXalanDocument() + ->getDocumentElement() + ->getChildNodes() ); return executionContext.getXObjectFactory().createNodeSet(nodeList); diff --git a/src/function/read_xml_file.cc b/src/function/read_xml_file.cc index 608e71a..dc98fc7 100644 --- a/src/function/read_xml_file.cc +++ b/src/function/read_xml_file.cc @@ -42,7 +42,11 @@ xalan::XObjectPtr FunctionReadXmlFile::execute( ) const { const FilesystemContext fs_context( boost::filesystem::path( - xercesc::XMLString::transcode(locator->getSystemId() + 7) + *XercesStringGuard<char>( + xercesc::XMLString::transcode( + locator->getSystemId() + 7 + ) + ) ).parent_path().string() ); @@ -50,13 +54,17 @@ xalan::XObjectPtr FunctionReadXmlFile::execute( fs_context.resolve(argument->str()) ); - DomDocumentCache::item* const cachedDocument( + DomDocumentCache::optional_item optionalCachedDocument( this->document_cache_->get(filePath.string()) ); - if ( !cachedDocument->isFinalized() ) { + if ( !optionalCachedDocument.first ) { xercesc::DOMDocument* const domDocument( - cachedDocument->getXercesDocument() + xercesc::DOMImplementation::getImplementation()->createDocument( + nullptr, + *XercesStringGuard<XMLCh>("content"), + nullptr + ) ); xercesc::DOMNode* const rootNode( @@ -65,12 +73,12 @@ xalan::XObjectPtr FunctionReadXmlFile::execute( if ( boost::filesystem::is_regular_file(filePath) ) { xercesc::DOMElement* const resultNode( - domDocument->createElement(*XercesStringGuard("result")) + domDocument->createElement(*XercesStringGuard<XMLCh>("result")) ); resultNode->setAttribute( - *XercesStringGuard("name"), - *XercesStringGuard(filePath.filename().string()) + *XercesStringGuard<XMLCh>("name"), + *XercesStringGuard<XMLCh>(filePath.filename().string()) ); xercesc::DOMNode* const resultTreeNode( @@ -81,11 +89,16 @@ xalan::XObjectPtr FunctionReadXmlFile::execute( rootNode->appendChild(resultNode); } else { xercesc::DOMElement* const resultNode( - domDocument->createElement(*XercesStringGuard("error")) + domDocument->createElement(*XercesStringGuard<XMLCh>("error")) ); rootNode->appendChild(resultNode); } + + optionalCachedDocument = this->document_cache_->create( + filePath.string(), + domDocument + ); } xalan::XPathExecutionContext::BorrowReturnMutableNodeRefList nodeList( @@ -93,7 +106,9 @@ xalan::XObjectPtr FunctionReadXmlFile::execute( ); nodeList->addNodes( - *cachedDocument->getXalanDocument()->getDocumentElement()->getChildNodes() + *optionalCachedDocument.second->getXalanDocument() + ->getDocumentElement() + ->getChildNodes() ); return executionContext.getXObjectFactory().createNodeSet(nodeList); |