From d2f52af2f6e33d7b8ae6e48463f296585e7dea5f Mon Sep 17 00:00:00 2001 From: paulc Date: Thu, 1 Oct 2015 15:15:09 +0000 Subject: [PATCH] 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 --- libs/yscript/jsobjects.cpp | 42 +++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/libs/yscript/jsobjects.cpp b/libs/yscript/jsobjects.cpp index 06f9eb57..9024dc8c 100644 --- a/libs/yscript/jsobjects.cpp +++ b/libs/yscript/jsobjects.cpp @@ -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(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(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(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(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; }