2005-08-04 22:42:30 +02:00
|
|
|
#ifndef ARABICA_XPATH_FUNCTION_HOLDER_HPP
|
|
|
|
#define ARABICA_XPATH_FUNCTION_HOLDER_HPP
|
|
|
|
|
|
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
#include "xpath_value.hpp"
|
|
|
|
#include "xpath_function.hpp"
|
|
|
|
|
|
|
|
namespace Arabica
|
|
|
|
{
|
|
|
|
namespace XPath
|
|
|
|
{
|
|
|
|
|
2005-08-18 11:15:08 +02:00
|
|
|
template<class function_type, class string_type, class string_adaptor>
|
|
|
|
XPathFunction<string_type, string_adaptor>* CreateFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& argExprs) { return new function_type(argExprs); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-18 11:15:08 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class FunctionHolder : public XPathExpression<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2005-08-18 11:15:08 +02:00
|
|
|
FunctionHolder(XPathFunction<string_type, string_adaptor>* func) :
|
2005-08-04 22:42:30 +02:00
|
|
|
func_(func)
|
|
|
|
{
|
|
|
|
} // FunctionHolder
|
|
|
|
|
|
|
|
virtual ~FunctionHolder()
|
|
|
|
{
|
|
|
|
delete func_;
|
|
|
|
} // ~FunctionHolder
|
|
|
|
|
2005-08-18 11:15:08 +02:00
|
|
|
virtual XPathValuePtr<string_type> evaluate(const DOM::Node<string_type>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 11:15:08 +02:00
|
|
|
return XPathValuePtr<string_type>(func_->evaluate(context, executionContext));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
|
2005-08-18 11:15:08 +02:00
|
|
|
static FunctionHolder* createFunction(const string_type& name,
|
|
|
|
const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& argExprs,
|
|
|
|
const CompilationContext<string_type, string_adaptor>& context)
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
for(const NamedFunction* fn = FunctionLookupTable; fn->name != 0; ++fn)
|
|
|
|
if(name == fn->name)
|
|
|
|
return new FunctionHolder(fn->creator(argExprs));
|
|
|
|
|
2005-08-18 11:15:08 +02:00
|
|
|
XPathFunction<string_type, string_adaptor>* func = context.functionResolver().resolveFunction(name, argExprs);
|
2005-08-04 22:42:30 +02:00
|
|
|
if(func == 0)
|
2005-08-18 11:15:08 +02:00
|
|
|
throw std::runtime_error("Function " + string_adaptor().asStdString(name) + " not implemented");
|
2005-08-04 22:42:30 +02:00
|
|
|
return new FunctionHolder(func);
|
|
|
|
} // createFunction
|
|
|
|
|
|
|
|
private:
|
2005-08-18 11:15:08 +02:00
|
|
|
XPathFunction<string_type, string_adaptor>* func_;
|
|
|
|
|
|
|
|
typedef XPathFunction<string_type, string_adaptor>* (*CreateFnPtr)(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& argExprs);
|
|
|
|
|
|
|
|
struct NamedFunction { const char* name; CreateFnPtr creator; };
|
|
|
|
|
|
|
|
static const NamedFunction FunctionLookupTable[];
|
|
|
|
}; // class FunctionHolder
|
|
|
|
|
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
const typename FunctionHolder<string_type, string_adaptor>::NamedFunction
|
|
|
|
FunctionHolder<string_type, string_adaptor>::FunctionLookupTable[] =
|
|
|
|
{ // node-set functions
|
2005-08-18 11:33:19 +02:00
|
|
|
{ "position", CreateFn<PositionFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{ "last", CreateFn<LastFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{ "count", CreateFn<CountFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{ "local-name", CreateFn<LocalNameFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{ "namespace-uri", CreateFn<NamespaceURIFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{ "name", CreateFn<NameFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
2005-08-18 11:15:08 +02:00
|
|
|
// string functions
|
2005-08-18 13:32:29 +02:00
|
|
|
{"string", CreateFn<StringFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"concat", CreateFn<ConcatFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"starts-with", CreateFn<StartsWithFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"contains", CreateFn<ContainsFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"substring-before", CreateFn<SubstringBeforeFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"substring-after", CreateFn<SubstringAfterFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"substring", CreateFn<SubstringFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"string-length", CreateFn<StringLengthFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"normalize-space", CreateFn<NormalizeSpaceFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"translate", CreateFn<TranslateFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
2005-08-18 11:15:08 +02:00
|
|
|
// boolean functions
|
2005-08-18 15:18:33 +02:00
|
|
|
{"boolean", CreateFn<BooleanFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"not", CreateFn<NotFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"true", CreateFn<TrueFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"false", CreateFn<FalseFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
2005-08-18 11:15:08 +02:00
|
|
|
// number functions
|
2005-08-18 15:18:33 +02:00
|
|
|
{"number", CreateFn<NumberFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"sum", CreateFn<SumFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"floor", CreateFn<FloorFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"ceiling", CreateFn<CeilingFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
|
|
|
{"round", CreateFn<RoundFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
2005-08-18 11:15:08 +02:00
|
|
|
{0, 0}
|
|
|
|
};
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
} // namespace XPath
|
|
|
|
} // namespace Arabica
|
|
|
|
|
|
|
|
#endif
|