From 7b872121000d4db4026d0c90fcb95a10f1e43694 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Wed, 25 Jun 2014 20:23:35 +0200 Subject: Added support for resolving non-existing paths * previous logic for resolving boost::filesystem::path parameters in the XObjectValue class actively tried to resolve existing files ** this contradicts the planned introduction of e.g. a external "write-file" function * callers of external functions with path arguments now have to enclose them in square brackets if include path resolution is required ** analog to the usage of the "xsl:import" tag * moved "getPathFromSystemId" from compilation local method into static method of IncludeEntityResolver * changed test cases accordingly --- src/support/include_entity_resolver.cc | 66 +++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 28 deletions(-) (limited to 'src/support/include_entity_resolver.cc') diff --git a/src/support/include_entity_resolver.cc b/src/support/include_entity_resolver.cc index e1c9f96..07577c1 100644 --- a/src/support/include_entity_resolver.cc +++ b/src/support/include_entity_resolver.cc @@ -4,35 +4,29 @@ #include "boost/filesystem.hpp" +#include "support/xalan_string.h" #include "support/xerces_string_guard.h" namespace { -using InputXSLT::XercesStringGuard; - -inline boost::filesystem::path getPathFromSystemId( - const XMLCh* const systemId) { - return boost::filesystem::path( - *XercesStringGuard(systemId) + 7 - ); -} - -boost::optional extractFilePath(const XMLCh* const rawPath) { - const std::string filePath = *XercesStringGuard(rawPath); - const std::size_t leadingDelimiter = filePath.find_first_of('['); - const std::size_t closingDelimiter = filePath.find_last_of(']'); +boost::optional extractFilePath( + const std::string& rawPath) { + const std::size_t leadingDelimiter = rawPath.find_first_of('['); + const std::size_t closingDelimiter = rawPath.find_last_of(']'); if ( leadingDelimiter != std::string::npos && closingDelimiter != std::string::npos && leadingDelimiter < closingDelimiter ) { return boost::make_optional( - filePath.substr( - leadingDelimiter + 1, - closingDelimiter - leadingDelimiter - 1 + boost::filesystem::path( + rawPath.substr( + leadingDelimiter + 1, + closingDelimiter - leadingDelimiter - 1 + ) ) ); } else { - return boost::optional(); + return boost::optional(); } } @@ -40,6 +34,13 @@ boost::optional extractFilePath(const XMLCh* const rawPath) { namespace InputXSLT { +boost::filesystem::path IncludeEntityResolver::getPathFromSystemId( + const XMLCh* const systemId) { + return boost::filesystem::path( + *XercesStringGuard(systemId) + 7 + ); +} + IncludeEntityResolver::IncludeEntityResolver( const std::vector& path): path_(path.begin(), path.end()) { } @@ -49,36 +50,45 @@ xercesc::InputSource* IncludeEntityResolver::resolveEntity( const XMLCh* const systemId ) { if ( systemId != nullptr ) { - return new xercesc::LocalFileInputSource( - *XercesStringGuard(this->resolve(systemId).string()) + const std::string systemIdString( + *XercesStringGuard(systemId) ); + + if ( auto resolvedPath = this->resolve(systemIdString) ) { + return new xercesc::LocalFileInputSource( + *XercesStringGuard((*resolvedPath).string()) + ); + } else { + return new xercesc::LocalFileInputSource( + *XercesStringGuard(systemIdString) + ); + } } else { return nullptr; } } -boost::filesystem::path IncludeEntityResolver::resolve( - const XMLCh* const rawPath) const { +boost::optional IncludeEntityResolver::resolve( + const std::string& rawPath) const { if ( auto filePath = extractFilePath(rawPath) ) { - if ( auto resolvedPath = this->resolve(*filePath) ) { - return *resolvedPath; + if ( auto resolvedPath = this->tryIncludePaths(*filePath) ) { + return boost::make_optional(*resolvedPath); } else { - return *filePath; + return boost::make_optional(*filePath); } } else { - return getPathFromSystemId(rawPath); + return boost::optional(); } } -boost::optional IncludeEntityResolver::resolve( +boost::optional IncludeEntityResolver::tryIncludePaths( const boost::filesystem::path& filePath) const { for ( auto&& context : this->path_ ) { const boost::filesystem::path resolvedPath( context.resolve(filePath) ); - if ( boost::filesystem::exists(resolvedPath) && - boost::filesystem::is_regular_file(resolvedPath) ) { + if ( boost::filesystem::exists(resolvedPath) ) { return boost::make_optional(resolvedPath); } } -- cgit v1.2.3