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.ArrayImpl;
032import lucee.runtime.type.Closure;
033import lucee.runtime.type.UDF;
034
035public final class ArrayFindAll extends BIF {
036
037        private static final long serialVersionUID = -1757019034608924098L;
038
039        public static Array call(PageContext pc , Array array, Object value) throws PageException {
040        if(value instanceof UDF)
041                return find(pc,array,(UDF)value);
042                return find(array,value,true);
043    }
044        
045        @Override
046        public Object invoke(PageContext pc, Object[] args) throws PageException {
047                return call(pc,Caster.toArray(args[0]),args[1]);
048        }
049        
050
051    public static Array find(PageContext pc , Array array, UDF udf) throws PageException {
052        Array rtn=new ArrayImpl();
053        int len=array.size();
054        
055        Object[] arr=new Object[1];
056        Object res;
057        Boolean b;
058        for(int i=1;i<=len;i++) {
059            arr[0]=array.get(i,null);
060            if(arr[0]!=null) {
061                res=udf.call(pc, arr, false);
062                b=Caster.toBoolean(res,null);
063                if(b==null) throw new FunctionException(pc,"ArrayFindAll",2,"function","return value of the "+(udf instanceof Closure?"closure":"function ["+udf.getFunctionName()+"]")+" cannot be casted to a boolean value.",CasterException.createMessage(res, "boolean"));
064                if(b.booleanValue()) {
065                        rtn.appendEL(Caster.toDouble(i));
066                }
067            }
068        }
069        return rtn;
070    }
071        
072    public static Array find(Array array, Object value, boolean caseSensitive) throws PageException {
073        Array rtn=new ArrayImpl();
074        int len=array.size();
075        boolean valueIsSimple=Decision.isSimpleValue(value);
076        Object o;
077        for(int i=1;i<=len;i++) {
078            o=array.get(i,null);
079            if(o!=null && Operator.equals(o, value,caseSensitive,!valueIsSimple)) {
080                rtn.appendEL(Caster.toDouble(i));
081            }
082        }
083        return rtn;
084    }
085}