From 943768ad437011756395b86958399992e6822604 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Wed, 14 May 2014 16:41:58 +0200 Subject: Added ArgumentCount parameter to FunctionBase template * constructDocument member method is provided with a FunctionBase::argument_array instance * improved argument validation in FunctionBase * this parameter was added to support FunctionBase as a base class for FunctionTransform --- src/function/base.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 6 deletions(-) (limited to 'src/function/base.h') diff --git a/src/function/base.h b/src/function/base.h index fe9f6ff..5604186 100644 --- a/src/function/base.h +++ b/src/function/base.h @@ -7,6 +7,8 @@ #include #include +#include +#include #include "common.h" #include "support/dom/document_cache.h" @@ -14,19 +16,44 @@ namespace InputXSLT { -template +template < + class Implementation, + std::size_t ArgumentCount +> class FunctionBase : public xalan::Function { public: + typedef std::array< + boost::filesystem::path, + ArgumentCount + > argument_array; + FunctionBase(): document_cache_(std::make_shared()) { } virtual xalan::XObjectPtr execute( xalan::XPathExecutionContext& executionContext, - xalan::XalanNode*, - const xalan::XObjectPtr argument, + xalan::XalanNode* context, + const XObjectArgVectorType& rawArguments, const xalan::Locator* locator ) const { + this->validateArguments( + rawArguments, + executionContext, + context, + locator + ); + const FilesystemContext fsContext(locator); + argument_array pathArguments; + + std::transform( + rawArguments.begin(), + rawArguments.end(), + pathArguments.begin(), + [&fsContext](const xalan::XObjectPtr& ptr) -> boost::filesystem::path { + return fsContext.resolve(ptr->str()); + } + ); xalan::XalanDocument* const domDocument( this->document_cache_->create( @@ -34,7 +61,7 @@ class FunctionBase : public xalan::Function { const_cast(this) )->constructDocument( fsContext, - fsContext.resolve(argument->str()) + pathArguments ) ) ); @@ -61,16 +88,43 @@ class FunctionBase : public xalan::Function { FunctionBase& operator=(const FunctionBase&) = delete; bool operator==(const FunctionBase&) const = delete; - protected: + private: std::shared_ptr document_cache_; const xalan::XalanDOMString& getError( xalan::XalanDOMString& result) const { - result.assign("The function expects one argument of type string."); + result.assign(std::string( + "The function expects " + + std::to_string(ArgumentCount) + + " argument(s) of type string." + ).data()); return result; } + inline void validateArguments( + const XObjectArgVectorType& rawArguments, + xalan::XPathExecutionContext& executionContext, + xalan::XalanNode* context, + const xalan::Locator* locator + ) const { + const bool notNull = std::none_of( + rawArguments.begin(), + rawArguments.end(), + [](const xalan::XObjectPtr& ptr) -> bool { + return ptr.null(); + } + ); + + if ( rawArguments.size() != ArgumentCount && notNull ) { + xalan::XPathExecutionContext::GetAndReleaseCachedString guard( + executionContext + ); + + this->generalError(executionContext, context, locator); + } + } + }; } -- cgit v1.2.3