1 54 package org.logicalcobwebs.cglib.util; 55 56 import java.util.*; 57 import org.logicalcobwebs.cglib.core.*; 58 import org.logicalcobwebs.asm.ClassVisitor; 59 import org.logicalcobwebs.asm.Label; 60 import org.logicalcobwebs.asm.Type; 61 62 65 abstract public class StringSwitcher { 66 private static final Type STRING_SWITCHER = 67 TypeUtils.parseType("org.logicalcobwebs.cglib.util.StringSwitcher"); 68 private static final Signature INT_VALUE = 69 TypeUtils.parseSignature("int intValue(String)"); 70 private static final StringSwitcherKey KEY_FACTORY = 71 (StringSwitcherKey)KeyFactory.create(StringSwitcherKey.class); 72 73 interface StringSwitcherKey { 74 public Object newInstance(String [] strings, int[] ints, boolean fixedInput); 75 } 76 77 86 public static StringSwitcher create(String [] strings, int[] ints, boolean fixedInput) { 87 Generator gen = new Generator(); 88 gen.setStrings(strings); 89 gen.setInts(ints); 90 gen.setFixedInput(fixedInput); 91 return gen.create(); 92 } 93 94 protected StringSwitcher() { 95 } 96 97 104 abstract public int intValue(String s); 105 106 public static class Generator extends AbstractClassGenerator { 107 private static final Source SOURCE = new Source(StringSwitcher.class.getName()); 108 109 private String [] strings; 110 private int[] ints; 111 private boolean fixedInput; 112 113 public Generator() { 114 super(SOURCE); 115 } 116 117 122 public void setStrings(String [] strings) { 123 this.strings = strings; 124 } 125 126 131 public void setInts(int[] ints) { 132 this.ints = ints; 133 } 134 135 140 public void setFixedInput(boolean fixedInput) { 141 this.fixedInput = fixedInput; 142 } 143 144 protected ClassLoader getDefaultClassLoader() { 145 return getClass().getClassLoader(); 146 } 147 148 151 public StringSwitcher create() { 152 setNamePrefix(StringSwitcher.class.getName()); 153 Object key = KEY_FACTORY.newInstance(strings, ints, fixedInput); 154 return (StringSwitcher)super.create(key); 155 } 156 157 public void generateClass(ClassVisitor v) throws Exception { 158 ClassEmitter ce = new ClassEmitter(v); 159 ce.begin_class(Constants.ACC_PUBLIC, 160 getClassName(), 161 STRING_SWITCHER, 162 null, 163 Constants.SOURCE_FILE); 164 EmitUtils.null_constructor(ce); 165 final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, INT_VALUE, null, null); 166 e.load_arg(0); 167 final List stringList = Arrays.asList(strings); 168 int style = fixedInput ? Constants.SWITCH_STYLE_HASHONLY : Constants.SWITCH_STYLE_HASH; 169 EmitUtils.string_switch(e, strings, style, new ObjectSwitchCallback() { 170 public void processCase(Object key, Label end) { 171 e.push(ints[stringList.indexOf(key)]); 172 e.return_value(); 173 } 174 public void processDefault() { 175 e.push(-1); 176 e.return_value(); 177 } 178 }); 179 e.end_method(); 180 ce.end_class(); 181 } 182 183 protected Object firstInstance(Class type) { 184 return (StringSwitcher)ReflectUtils.newInstance(type); 185 } 186 187 protected Object nextInstance(Object instance) { 188 return instance; 189 } 190 } 191 } 192 | Popular Tags |