001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 * Copyright (c) 2015, Lucee Assosication Switzerland
005 *
006 * This library is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either 
009 * version 2.1 of the License, or (at your option) any later version.
010 * 
011 * This library is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 * 
016 * You should have received a copy of the GNU Lesser General Public 
017 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
018 * 
019 **/
020package lucee.runtime.interpreter;
021
022import lucee.commons.lang.NumberUtil;
023import lucee.runtime.exp.PageException;
024import lucee.runtime.interpreter.ref.Ref;
025import lucee.runtime.interpreter.ref.literal.LStringBuffer;
026
027public class JSONExpressionInterpreter extends CFMLExpressionInterpreter {
028        public JSONExpressionInterpreter(){
029                this(false);
030    }
031        
032        public JSONExpressionInterpreter(boolean strict){// strict is set to true, it should not be compatible with CFMLExpressionInterpreter
033                allowNullConstant=true;
034    }
035        
036        @Override
037    protected Ref string() throws PageException {
038        
039        // Init Parameter
040        char quoter = cfml.getCurrentLower();
041        LStringBuffer str=new LStringBuffer();
042        
043        while(cfml.hasNext()) {
044            cfml.next();
045            // check sharp
046            if(cfml.isCurrent('\\')) {
047                if(cfml.isNext(quoter)){
048                    cfml.next();
049                    str.append(quoter);
050                }
051                else if(cfml.isNext('\\')){
052                    cfml.next();
053                    str.append('\\');
054                }
055                else if(cfml.isNext('"')){
056                    cfml.next();
057                    str.append('"');
058                }
059                else if(cfml.isNext('\'')){
060                    cfml.next();
061                    str.append('\'');
062                }
063                else if(cfml.isNext('t')){
064                    cfml.next();
065                    str.append('\t');
066                }
067                else if(cfml.isNext('n')){
068                    cfml.next();
069                    str.append('\n');
070                }
071                else if(cfml.isNext('b')){
072                    cfml.next();
073                    str.append('\b');
074                }
075                else if(cfml.isNext('f')){
076                    cfml.next();
077                    str.append('\f');
078                }
079                else if(cfml.isNext('r')){
080                    cfml.next();
081                    str.append('\r');
082                }
083                else if(cfml.isNext('u')){
084                    cfml.next();
085                    StringBuilder sb=new StringBuilder();
086                    int i=0;
087                    
088                    for(;i<4 && cfml.hasNext();i++){
089                        cfml.next();
090                        sb.append(cfml.getCurrent());
091                    }
092                    if(i<4){
093                        str.append("\\u");
094                        str.append(sb.toString());
095                    }
096                    else{
097                        int asc = NumberUtil.hexToInt(sb.toString(),-1);
098                        if(asc!=-1)str.append((char)asc);
099                        else {
100                                str.append("\\u");
101                                str.append(sb.toString());
102                        }
103                    }   
104                    
105                }
106                else if(cfml.isNext('/')){
107                    cfml.next();
108                    str.append('/');
109                }
110                else {
111                        str.append('\\');
112                }     
113            }
114            else if(cfml.isCurrent(quoter)) {
115                break;          
116            }
117            // all other character
118            else {
119                str.append(cfml.getCurrent());
120            }
121        }
122        if(!cfml.forwardIfCurrent(quoter))
123            throw new InterpreterException("Invalid String Literal Syntax Closing ["+quoter+"] not found");
124        
125        cfml.removeSpace();
126        mode=STATIC;
127        return str;
128    }
129
130}