package railo.transformer.bytecode.literal;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import railo.commons.lang.StringUtil;
import railo.runtime.config.ConfigImpl;
import railo.runtime.op.Caster;
import railo.transformer.bytecode.BytecodeContext;
import railo.transformer.bytecode.BytecodeException;
import railo.transformer.bytecode.Literal;
import railo.transformer.bytecode.Page;
import railo.transformer.bytecode.Position;
import railo.transformer.bytecode.expression.ExprString;
import railo.transformer.bytecode.expression.ExpressionBase;
import railo.transformer.bytecode.op.OpString;
import railo.transformer.bytecode.util.Types;
/**
* A Literal String
*/
public class LitString extends ExpressionBase implements Literal,ExprString {
public static final int MAX_SIZE = 65535;
public static final int TYPE_ORIGINAL = 0;
public static final int TYPE_UPPER = 1;
public static final int TYPE_LOWER = 2;
public static final LitString EMPTY = new LitString("",null,null);
private String str;
private boolean fromBracket;
public static ExprString toExprString(String str, Position start,Position end) {
return new LitString(str,start,end);
}
public static ExprString toExprString(String str) {
return new LitString(str,null,null);
}
public static LitString toLitString(String str) {
return new LitString(str,null,null);
}
/**
* constructor of the class
* @param str
* @param line
*/
public LitString(String str, Position start,Position end) {
super(start,end);
this.str=str;
}
/**
* @see railo.transformer.bytecode.Literal#getString()
*/
public String getString() {
return str;
}
/**
* @see railo.transformer.bytecode.expression.Expression#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int)
*/
private static Type _writeOut(BytecodeContext bc, int mode,String str) throws BytecodeException {
// write to a file instead to the bytecode
// str(0,10);
//print.ds(str);
int externalizeStringGTE=((ConfigImpl)bc.getPageSource().getMapping().getConfig()).getExternalizeStringGTE();
if(externalizeStringGTE>-1 && str.length()>externalizeStringGTE && StringUtil.indexOfIgnoreCase(bc.getMethod().getName(),"call")!=-1) {
try{
GeneratorAdapter ga = bc.getAdapter();
Page page = bc.getPage();
Range range= page.registerString(bc,str);
ga.visitVarInsn(Opcodes.ALOAD, 0);
ga.visitVarInsn(Opcodes.ALOAD, 1);
ga.push(range.from);
ga.push(range.to);
ga.visitMethodInsn(Opcodes.INVOKEVIRTUAL, bc.getClassName(), "str", "(Lrailo/runtime/PageContext;II)Ljava/lang/String;");
return Types.STRING;
}
catch(Throwable t){}
}
if(str.length()>MAX_SIZE) {
ExprString expr=_toExpr(str);
expr.writeOut(bc, mode);
}
else {
bc.getAdapter().push(str);
}
return Types.STRING;
}
public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
return _writeOut(bc, mode, str);
}
public Type writeOut(BytecodeContext bc, int mode, int caseType) throws BytecodeException {
if(TYPE_UPPER==caseType) return _writeOut(bc, mode, str.toUpperCase());
if(TYPE_LOWER==caseType) return _writeOut(bc, mode, str.toLowerCase());
return _writeOut(bc, mode, str);
}
private static ExprString _toExpr(String str) {
int size=MAX_SIZE-1;
ExprString left = LitString.toExprString(str.substring(0,size));
str = str.substring(size);
ExprString right = (str.length()>size)?_toExpr(str):toExprString(str);
return OpString.toExprString(left, right, false);
}
/**
* @see railo.transformer.bytecode.Literal#getDouble(java.lang.Double)
*/
public Double getDouble(Double defaultValue) {
return Caster.toDouble(getString(),defaultValue);
}
/**
* @see railo.transformer.bytecode.Literal#getBoolean(java.lang.Boolean)
*/
public Boolean getBoolean(Boolean defaultValue) {
return Caster.toBoolean(getString(),defaultValue);
}
/**
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if(this==obj) return true;
if(!(obj instanceof LitString)) return false;
return str.equals(((LitString)obj).str);
}
/**
*
* @see java.lang.Object#toString()
*/
public String toString() {
return str;
}
public void upperCase() {
str=str.toUpperCase();
}
public void lowerCase() {
str=str.toLowerCase();
}
public LitString duplicate() {
return new LitString(str,getStart(),getEnd());
}
public void fromBracket(boolean fromBracket) {
this.fromBracket=fromBracket;
}
public boolean fromBracket() {
return fromBracket;
}
public static class Range {
public final int from;
public final int to;
public Range(int from, int to) {
this.from=from;
this.to=to;
}
public String toString(){
return "from:"+from+";to:"+to+";";
}
}
/* *
* @see railo.transformer.bytecode.expression.Expression#getType()
* /
public int getType() {
return Types._STRING;
}*/
}