Added JS Array.lastIndexOf() method.

Fixed fromIndex behavior for indexOf() and lastIndexOf().
Added optional extra parameter to allow searching a field in an array of objects.


git-svn-id: http://yate.null.ro/svn/yate/trunk@6050 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2015-10-01 15:15:09 +00:00
parent e0f16e2941
commit d2f52af2f6
1 changed files with 37 additions and 5 deletions

View File

@ -550,6 +550,7 @@ JsArray::JsArray(Mutex* mtx)
params().addParam(new ExpFunction("splice"));
params().addParam(new ExpFunction("sort"));
params().addParam(new ExpFunction("indexOf"));
params().addParam(new ExpFunction("lastIndexOf"));
params().addParam("length","0");
}
@ -848,7 +849,9 @@ bool JsArray::runNative(ObjList& stack, const ExpOperation& oper, GenObject* con
for (int32_t i = 0; i < length(); i++)
result.append(params()[String(i)],separator);
ExpEvaluator::pushOne(stack,new ExpOperation(result));
} else if (oper.name() == YSTRING("indexOf")) {
} else if (oper.name() == YSTRING("indexOf") || oper.name() == YSTRING("lastIndexOf")) {
// arr.indexOf(searchElement[,startIndex = 0[,"fieldName"]])
// arr.lastIndexOf(searchElement[,startIndex = arr.length-1[,"fieldName"]])
ObjList args;
if (!extractArgs(this,stack,oper,context,args)) {
Debug(DebugWarn,"Failed to extract arguments!");
@ -857,19 +860,47 @@ bool JsArray::runNative(ObjList& stack, const ExpOperation& oper, GenObject* con
ExpOperation* op1 = static_cast<ExpOperation*>(args.remove(false));
if (!op1)
return false;
ExpWrapper* w1 = YOBJECT(ExpWrapper,op1);
ExpOperation* fld = 0;
int dir = 1;
int pos = 0;
if (oper.name().at(0) == 'l') {
dir = -1;
pos = length() - 1;
}
if (args.skipNull()) {
String* spos = static_cast<String*>(args.remove(false));
if (spos)
pos = spos->toInteger(0);
if (spos) {
pos = spos->toInteger(pos);
if (pos < 0)
pos += length();
if (dir > 0) {
if (pos < 0)
pos = 0;
}
else if (pos >= length())
pos = length() - 1;
}
TelEngine::destruct(spos);
fld = static_cast<ExpOperation*>(args.remove(false));
}
int index = -1;
for (int i = pos;i < length();i++) {
for (int i = pos; ; i += dir) {
if (dir > 0) {
if (i >= length())
break;
}
else if (i < 0)
break;
ExpOperation* op2 = static_cast<ExpOperation*>(params().getParam(String(i)));
if (op2 && !TelEngine::null(fld)) {
const ExpExtender* ext = YOBJECT(ExpExtender,op2);
if (!ext)
continue;
op2 = YOBJECT(ExpOperation,ext->getField(stack,*fld,context));
}
if (!op2 || op2->opcode() != op1->opcode())
continue;
ExpWrapper* w1 = YOBJECT(ExpWrapper,op1);
ExpWrapper* w2 = YOBJECT(ExpWrapper,op2);
if (w1 || w2) {
if (w1 && w2 && w1->object() == w2->object()) {
@ -882,6 +913,7 @@ bool JsArray::runNative(ObjList& stack, const ExpOperation& oper, GenObject* con
}
}
TelEngine::destruct(op1);
TelEngine::destruct(fld);
ExpEvaluator::pushOne(stack,new ExpOperation((int64_t)index));
return true;
}