Added an optional user context pointer to expression evaluations.

git-svn-id: http://yate.null.ro/svn/yate/trunk@4808 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2012-01-17 18:11:45 +00:00
parent 60102b4db6
commit 8c082767d1
2 changed files with 55 additions and 42 deletions

View File

@ -78,12 +78,12 @@ const TokenDict s_operators_sql[] =
bool ExpExtender::runFunction(const ExpEvaluator* eval, ObjList& stack, const ExpOperation& oper)
bool ExpExtender::runFunction(const ExpEvaluator* eval, ObjList& stack, const ExpOperation& oper, void* context)
{
return false;
}
bool ExpExtender::runField(const ExpEvaluator* eval, ObjList& stack, const ExpOperation& oper)
bool ExpExtender::runField(const ExpEvaluator* eval, ObjList& stack, const ExpOperation& oper, void* context)
{
return false;
}
@ -498,9 +498,9 @@ ExpOperation* ExpEvaluator::popOne(ObjList& stack)
return static_cast<ExpOperation*>(o);
}
bool ExpEvaluator::runOperation(ObjList& stack, const ExpOperation& oper) const
bool ExpEvaluator::runOperation(ObjList& stack, const ExpOperation& oper, void* context) const
{
DDebug(DebugAll,"runOperation(%p,%u) %s",&stack,oper.opcode(),getOperator(oper.opcode()));
DDebug(DebugAll,"runOperation(%p,%u,%p) %s",&stack,oper.opcode(),context,getOperator(oper.opcode()));
switch (oper.opcode()) {
case OpcPush:
stack.append(new ExpOperation(oper));
@ -654,9 +654,9 @@ bool ExpEvaluator::runOperation(ObjList& stack, const ExpOperation& oper) const
}
break;
case OpcFunc:
return runFunction(stack,oper);
return runFunction(stack,oper,context);
case OpcField:
return runField(stack,oper);
return runField(stack,oper,context);
default:
Debug(DebugStub,"Please implement operation %u",oper.opcode());
return false;
@ -664,10 +664,10 @@ bool ExpEvaluator::runOperation(ObjList& stack, const ExpOperation& oper) const
return true;
}
bool ExpEvaluator::runFunction(ObjList& stack, const ExpOperation& oper) const
bool ExpEvaluator::runFunction(ObjList& stack, const ExpOperation& oper, void* context) const
{
DDebug(DebugAll,"runFunction(%p,'%s' %ld) ext=%p",
&stack,oper.name().c_str(),oper.number(),(void*)m_extender);
DDebug(DebugAll,"runFunction(%p,'%s' %ld, %p) ext=%p",
&stack,oper.name().c_str(),oper.number(),context,(void*)m_extender);
if (oper.name() == YSTRING("chr")) {
String res;
for (long int i = oper.number(); i; i--) {
@ -686,22 +686,22 @@ bool ExpEvaluator::runFunction(ObjList& stack, const ExpOperation& oper) const
stack.append(new ExpOperation(Time::secNow()));
return true;
}
return m_extender && m_extender->runFunction(this,stack,oper);
return m_extender && m_extender->runFunction(this,stack,oper,context);
}
bool ExpEvaluator::runField(ObjList& stack, const ExpOperation& oper) const
bool ExpEvaluator::runField(ObjList& stack, const ExpOperation& oper, void* context) const
{
DDebug(DebugAll,"runField(%p,'%s') ext=%p",
&stack,oper.name().c_str(),(void*)m_extender);
return m_extender && m_extender->runField(this,stack,oper);
DDebug(DebugAll,"runField(%p,'%s',%p) ext=%p",
&stack,oper.name().c_str(),context,(void*)m_extender);
return m_extender && m_extender->runField(this,stack,oper,context);
}
bool ExpEvaluator::runEvaluate(ObjList& stack) const
bool ExpEvaluator::runEvaluate(ObjList& stack, void* context) const
{
DDebug(DebugInfo,"runEvaluate(%p)",&stack);
DDebug(DebugInfo,"runEvaluate(%p,%p)",&stack,context);
for (ObjList* l = m_opcodes.skipNull(); l; l = l->skipNext()) {
const ExpOperation* o = static_cast<const ExpOperation*>(l->get());
if (!runOperation(stack,*o))
if (!runOperation(stack,*o,context))
return false;
}
return true;
@ -720,20 +720,20 @@ int ExpEvaluator::compile(const char* expr)
return skipWhites(expr) ? 0 : res;
}
bool ExpEvaluator::evaluate(ObjList* results) const
bool ExpEvaluator::evaluate(ObjList* results, void* context) const
{
ObjList res;
if (results)
results->clear();
else
results = &res;
return runEvaluate(*results);
return runEvaluate(*results,context);
}
int ExpEvaluator::evaluate(NamedList& results, unsigned int index, const char* prefix) const
int ExpEvaluator::evaluate(NamedList& results, unsigned int index, const char* prefix, void* context) const
{
ObjList stack;
if (!evaluate(stack))
if (!evaluate(stack,context))
return -1;
String idx(prefix);
if (index)
@ -750,7 +750,7 @@ int ExpEvaluator::evaluate(NamedList& results, unsigned int index, const char* p
return column;
}
int ExpEvaluator::evaluate(Array& results, unsigned int index) const
int ExpEvaluator::evaluate(Array& results, unsigned int index, void* context) const
{
Debug(DebugStub,"Please implement ExpEvaluator::evaluate(Array)");
return -1;
@ -817,12 +817,12 @@ void TableEvaluator::extender(ExpExtender* ext)
m_limit.extender(ext);
}
bool TableEvaluator::evalWhere()
bool TableEvaluator::evalWhere(void* context)
{
if (m_where.null())
return true;
ObjList res;
if (!m_where.evaluate(res))
if (!m_where.evaluate(res,context))
return false;
ObjList* first = res.skipNull();
if (!first)
@ -831,21 +831,21 @@ bool TableEvaluator::evalWhere()
return (o->opcode() == ExpEvaluator::OpcPush) && o->number();
}
bool TableEvaluator::evalSelect(ObjList& results)
bool TableEvaluator::evalSelect(ObjList& results, void* context)
{
if (m_select.null())
return false;
return m_select.evaluate(results);
return m_select.evaluate(results,context);
}
unsigned int TableEvaluator::evalLimit()
unsigned int TableEvaluator::evalLimit(void* context)
{
if (m_limitVal == (unsigned int)-2) {
m_limitVal = (unsigned int)-1;
// hack: use a loop so we can break out of it
while (!m_limit.null()) {
ObjList res;
if (!m_limit.evaluate(res))
if (!m_limit.evaluate(res,context))
break;
ObjList* first = res.skipNull();
if (!first)

View File

@ -3871,18 +3871,20 @@ public:
* @param stack Evaluation stack in use, parameters are popped off this stack
* and results are pushed back on stack
* @param oper Function to evaluate
* @param context Pointer to arbitrary data passed from evaluation methods
* @return True if evaluation succeeded
*/
virtual bool runFunction(const ExpEvaluator* eval, ObjList& stack, const ExpOperation& oper);
virtual bool runFunction(const ExpEvaluator* eval, ObjList& stack, const ExpOperation& oper, void* context);
/**
* Try to evaluate a single field
* @param eval Pointer to the caller evaluator object
* @param stack Evaluation stack in use, field value must be pushed on it
* @param oper Field to evaluate
* @param context Pointer to arbitrary data passed from evaluation methods
* @return True if evaluation succeeded
*/
virtual bool runField(const ExpEvaluator* eval, ObjList& stack, const ExpOperation& oper);
virtual bool runField(const ExpEvaluator* eval, ObjList& stack, const ExpOperation& oper, void* context);
};
/**
@ -3993,34 +3995,38 @@ public:
/**
* Evaluate the expression, optionally return results
* @param results List to fill with results row
* @param context Pointer to arbitrary data to be passed to called methods
* @return True if expression evaluation succeeded, false on failure
*/
bool evaluate(ObjList* results) const;
bool evaluate(ObjList* results, void* context = 0) const;
/**
* Evaluate the expression, return computed results
* @param results List to fill with results row
* @param context Pointer to arbitrary data to be passed to called methods
* @return True if expression evaluation succeeded, false on failure
*/
inline bool evaluate(ObjList& results) const
{ return evaluate(&results); }
inline bool evaluate(ObjList& results, void* context = 0) const
{ return evaluate(&results,context); }
/**
* Evaluate the expression, return computed results
* @param results List of parameters to populate with results row
* @param index Index of result row, zero to not include an index
* @param prefix Prefix to prepend to parameter names
* @param context Pointer to arbitrary data to be passed to called methods
* @return Number of result columns, -1 on failure
*/
int evaluate(NamedList& results, unsigned int index = 0, const char* prefix = 0) const;
int evaluate(NamedList& results, unsigned int index = 0, const char* prefix = 0, void* context = 0) const;
/**
* Evaluate the expression, return computed results
* @param results Array of result rows to populate
* @param index Index of result row, zero to just set column headers
* @param context Pointer to arbitrary data to be passed to called methods
* @return Number of result columns, -1 on failure
*/
int evaluate(Array& results, unsigned int index) const;
int evaluate(Array& results, unsigned int index, void* context = 0) const;
/**
* Simplify the expression, performs constant folding
@ -4198,35 +4204,39 @@ protected:
/**
* Try to evaluate the expression
* @param stack Evaluation stack in use, results are left on stack
* @param context Pointer to arbitrary data to be passed to called methods
* @return True if evaluation succeeded
*/
virtual bool runEvaluate(ObjList& stack) const;
virtual bool runEvaluate(ObjList& stack, void* context = 0) const;
/**
* Try to evaluate a single operation
* @param stack Evaluation stack in use, operands are popped off this stack
* and results are pushed back on stack
* @param oper Operation to execute
* @param context Pointer to arbitrary data to be passed to called methods
* @return True if evaluation succeeded
*/
virtual bool runOperation(ObjList& stack, const ExpOperation& oper) const;
virtual bool runOperation(ObjList& stack, const ExpOperation& oper, void* context = 0) const;
/**
* Try to evaluate a single function
* @param stack Evaluation stack in use, parameters are popped off this stack
* and results are pushed back on stack
* @param oper Function to evaluate
* @param context Pointer to arbitrary data to be passed to called methods
* @return True if evaluation succeeded
*/
virtual bool runFunction(ObjList& stack, const ExpOperation& oper) const;
virtual bool runFunction(ObjList& stack, const ExpOperation& oper, void* context = 0) const;
/**
* Try to evaluate a single field
* @param stack Evaluation stack in use, field value must be pushed on it
* @param oper Field to evaluate
* @param context Pointer to arbitrary data to be passed to called methods
* @return True if evaluation succeeded
*/
virtual bool runField(ObjList& stack, const ExpOperation& oper) const;
virtual bool runField(ObjList& stack, const ExpOperation& oper, void* context = 0) const;
/**
* Internally used operator dictionary
@ -4351,22 +4361,25 @@ public:
/**
* Evaluate the WHERE (selector) expression
* @param context Pointer to arbitrary data to be passed to called methods
* @return True if the current row is part of selection
*/
virtual bool evalWhere();
virtual bool evalWhere(void* context = 0);
/**
* Evaluate the SELECT (results) expression
* @param results List to fill with results row
* @param context Pointer to arbitrary data to be passed to called methods
* @return True if evaluation succeeded
*/
virtual bool evalSelect(ObjList& results);
virtual bool evalSelect(ObjList& results, void* context = 0);
/**
* Evaluate the LIMIT expression and cache the result
* @param context Pointer to arbitrary data to be passed to called methods
* @return Desired maximum number or result rows
*/
virtual unsigned int evalLimit();
virtual unsigned int evalLimit(void* context = 0);
/**
* Set the expression extender to use in all evaluators