001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.functions.arrays;
020
021
022import lucee.runtime.PageContext;
023import lucee.runtime.exp.CasterException;
024import lucee.runtime.exp.FunctionException;
025import lucee.runtime.exp.PageException;
026import lucee.runtime.functions.BIF;
027import lucee.runtime.op.Caster;
028import lucee.runtime.op.Decision;
029import lucee.runtime.op.Operator;
030import lucee.runtime.type.Array;
031import lucee.runtime.type.Closure;
032import lucee.runtime.type.UDF;
033
034public final class ArrayFind extends BIF {
035
036        private static final long serialVersionUID = -3282048672805234115L;
037
038        public static double call(PageContext pc , Array array, Object value) throws PageException {
039                if(value instanceof UDF) 
040                return find(pc,array,(UDF)value);
041        
042                
043                return find(array,value,true);
044    }
045        
046        @Override
047        public Object invoke(PageContext pc, Object[] args) throws PageException {
048                return call(pc,Caster.toArray(args[0]),args[1]);
049        }
050
051    public static int find(PageContext pc ,Array array, UDF udf) throws PageException {
052        int len=array.size();
053        
054        Object[] arr=new Object[1];
055        Object res;
056        Boolean b;
057        for(int i=1;i<=len;i++) {
058            arr[0]=array.get(i,null);
059            if(arr[0]!=null) {
060                res=udf.call(pc, arr, false);
061                b=Caster.toBoolean(res,null);
062                if(b==null) throw new FunctionException(pc,"ArrayFind",2,"function","return value of the "+(udf instanceof Closure?"closure":"function ["+udf.getFunctionName()+"]")+" cannot be casted to a boolean value.",CasterException.createMessage(res, "boolean"));
063                if(b.booleanValue())return i;
064            }
065        }
066        return 0;
067    }
068        
069    public static int find(Array array, Object value, boolean caseSensitive) {
070        int len=array.size();
071        boolean valueIsSimple=Decision.isSimpleValue(value);
072        Object o;
073        for(int i=1;i<=len;i++) {
074            o=array.get(i,null);
075            if(o!=null && Operator.equalsEL(o, value,caseSensitive,!valueIsSimple)) return i;
076        }
077        return 0;
078    }
079}