arabica/XPath/impl/xpath_function_holder.hpp

93 lines
4.8 KiB
C++
Raw Normal View History

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