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 **/
019/**
020 * Implements the CFML Function listdeleteat
021 */
022package lucee.runtime.functions.list;
023
024import lucee.runtime.PageContext;
025import lucee.runtime.exp.ExpressionException;
026import lucee.runtime.exp.FunctionException;
027import lucee.runtime.exp.PageException;
028import lucee.runtime.functions.BIF;
029import lucee.runtime.op.Caster;
030
031public final class ListDeleteAt extends BIF {
032        
033        private static char[] DEFAULT_DELIMITER=new char[]{','};
034        
035        public static String call(PageContext pc , String list, double posNumber) throws ExpressionException {
036                return _call(pc,list,(int)posNumber,DEFAULT_DELIMITER,false);
037        }
038        
039        public static String call(PageContext pc, String list, double posNumber, String del) throws ExpressionException {
040                return _call(pc, list, (int)posNumber, del.toCharArray(),false);
041        }
042        
043        public static String call(PageContext pc, String list, double posNumber, String del, boolean includeEmptyFields) throws ExpressionException {
044                return _call(pc, list, (int)posNumber, del.toCharArray(),includeEmptyFields);
045        }
046
047
048    @Override
049        public Object invoke(PageContext pc, Object[] args) throws PageException {
050        if(args.length==2)
051                        return call(pc, Caster.toString(args[0]), Caster.toDoubleValue(args[1]));
052        if(args.length==3)
053                        return call(pc, Caster.toString(args[0]), Caster.toDoubleValue(args[1]), Caster.toString(args[2]));
054        if(args.length==4)
055                        return call(pc, Caster.toString(args[0]), Caster.toDoubleValue(args[1]), Caster.toString(args[2]), Caster.toBooleanValue(args[3]));
056        
057                throw new FunctionException(pc, "ListDeleteAt", 2, 4, args.length);
058        }
059        
060
061        
062
063        public static String _call(PageContext pc, String list, int pos, char[] del, boolean includeEmptyFields) throws ExpressionException {
064        
065        StringBuilder sb = new StringBuilder();
066        int len=list.length();
067        int index=0;
068        char last=0,c;
069        
070        if(pos<1) throw new FunctionException(pc,"ListDeleteAt",2,"index","index must be greater than 0");
071        
072        pos--;
073        
074        int i=0;
075        
076        // ignore all delimiter at start
077        if(!includeEmptyFields)for(;i<len;i++){
078                c=list.charAt(i);
079                if(!equal(del,c)) break;
080                sb.append(c);
081        }
082        
083        // before
084        for(;i<len;i++){
085                
086                c=list.charAt(i);
087                if(index==pos && !equal(del,c)) break;
088                if(equal(del,c)) {
089                        if(includeEmptyFields || !equal(del,last))
090                                index++;
091                }
092                sb.append(c);
093                last=c;
094        }
095        
096        
097        // suppress item
098        for(;i<len;i++){
099                if(equal(del,list.charAt(i))) break;
100        }
101        
102        // ignore following delimiter
103        for(;i<len;i++){
104                if(!equal(del,list.charAt(i))) break;
105        }
106        
107        if(i==len){
108                
109                while(sb.length()>0 && equal(del,sb.charAt(sb.length()-1))) {
110                        sb.delete(sb.length()-1, sb.length());
111                }
112                if(pos>index) throw new FunctionException(pc,"ListDeleteAt",2,"index","index must be a integer between 1 and "+index);
113                
114                return sb.toString();
115        }
116        
117        
118        // fill the rest
119        for(;i<len;i++){
120                sb.append(list.charAt(i));
121        }
122        
123        return sb.toString();
124    }
125        
126        
127    private static boolean equal(char[] del, char c) {
128        for(int i=0;i<del.length;i++){
129                if(del[i]==c) return true;
130        }
131                return false;
132        }
133
134
135        
136        
137}