1 16 package net.sf.cglib.util; 17 18 import java.util.*; 19 import net.sf.cglib.core.*; 20 import org.objectweb.asm.ClassVisitor; 21 import org.objectweb.asm.Label; 22 import org.objectweb.asm.Type; 23 24 27 abstract public class StringSwitcher { 28 private static final Type STRING_SWITCHER = 29 TypeUtils.parseType("net.sf.cglib.util.StringSwitcher"); 30 private static final Signature INT_VALUE = 31 TypeUtils.parseSignature("int intValue(String)"); 32 private static final StringSwitcherKey KEY_FACTORY = 33 (StringSwitcherKey)KeyFactory.create(StringSwitcherKey.class); 34 35 interface StringSwitcherKey { 36 public Object newInstance(String [] strings, int[] ints, boolean fixedInput); 37 } 38 39 48 public static StringSwitcher create(String [] strings, int[] ints, boolean fixedInput) { 49 Generator gen = new Generator(); 50 gen.setStrings(strings); 51 gen.setInts(ints); 52 gen.setFixedInput(fixedInput); 53 return gen.create(); 54 } 55 56 protected StringSwitcher() { 57 } 58 59 66 abstract public int intValue(String s); 67 68 public static class Generator extends AbstractClassGenerator { 69 private static final Source SOURCE = new Source(StringSwitcher.class.getName()); 70 71 private String [] strings; 72 private int[] ints; 73 private boolean fixedInput; 74 75 public Generator() { 76 super(SOURCE); 77 } 78 79 84 public void setStrings(String [] strings) { 85 this.strings = strings; 86 } 87 88 93 public void setInts(int[] ints) { 94 this.ints = ints; 95 } 96 97 102 public void setFixedInput(boolean fixedInput) { 103 this.fixedInput = fixedInput; 104 } 105 106 protected ClassLoader getDefaultClassLoader() { 107 return getClass().getClassLoader(); 108 } 109 110 113 public StringSwitcher create() { 114 setNamePrefix(StringSwitcher.class.getName()); 115 Object key = KEY_FACTORY.newInstance(strings, ints, fixedInput); 116 return (StringSwitcher)super.create(key); 117 } 118 119 public void generateClass(ClassVisitor v) throws Exception { 120 ClassEmitter ce = new ClassEmitter(v); 121 ce.begin_class(Constants.V1_2, 122 Constants.ACC_PUBLIC, 123 getClassName(), 124 STRING_SWITCHER, 125 null, 126 Constants.SOURCE_FILE); 127 EmitUtils.null_constructor(ce); 128 final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, INT_VALUE, null); 129 e.load_arg(0); 130 final List stringList = Arrays.asList(strings); 131 int style = fixedInput ? Constants.SWITCH_STYLE_HASHONLY : Constants.SWITCH_STYLE_HASH; 132 EmitUtils.string_switch(e, strings, style, new ObjectSwitchCallback() { 133 public void processCase(Object key, Label end) { 134 e.push(ints[stringList.indexOf(key)]); 135 e.return_value(); 136 } 137 public void processDefault() { 138 e.push(-1); 139 e.return_value(); 140 } 141 }); 142 e.end_method(); 143 ce.end_class(); 144 } 145 146 protected Object firstInstance(Class type) { 147 return (StringSwitcher)ReflectUtils.newInstance(type); 148 } 149 150 protected Object nextInstance(Object instance) { 151 return instance; 152 } 153 } 154 } 155 | Popular Tags |