1 package alt.jiapi.reflect; 2 3 import java.io.ByteArrayOutputStream ; 4 5 import alt.jiapi.reflect.Instruction; 6 import alt.jiapi.reflect.instruction.Opcodes; 7 8 16 public class SwitchInstruction extends Instruction { 17 private Instruction deflt; 18 private Instruction[] targets; 19 20 private int padding; 25 private int defaultOffset; 26 private int nPairs; 27 28 private int[] keys; 29 private int[] targetOffsets; 30 31 42 43 47 SwitchInstruction(byte[] bytes, int padding, int nPairs) { 48 super(bytes); 49 this.padding = padding; 50 this.defaultOffset = toInt(bytes, 1 + padding); 51 this.nPairs = nPairs; 52 53 this.keys = new int[nPairs]; 54 this.targetOffsets = new int[nPairs]; 55 56 if (bytes[0] == Opcodes.LOOKUPSWITCH) { 57 59 for (int i = 0; i < keys.length; i++) { 60 int start = (1 + padding + 8) + (i*4*2); 61 keys[i] = toInt(bytes, start); 62 } 63 64 for (int i = 0; i < targetOffsets.length; i++) { 65 int start = (1 + padding + 8) + (i*4*2) + 4; 66 targetOffsets[i] = toInt(bytes, start); 67 } 68 } 69 else { 70 72 int low = toInt(bytes, padding + 5); 73 int high = toInt(bytes, padding + 9); 74 75 for (int i = low; i < high ; i++) { 76 keys[i] = i; 77 } 78 79 for (int i = 0; i < targetOffsets.length; i++) { 80 int start = (padding + 13) + (i*4); 81 targetOffsets[i] = toInt(bytes, start); 82 } 83 } 84 } 85 86 92 public Instruction getDefault() { 93 return deflt; 94 } 95 96 102 public Target[] getTargets() { 103 Target[] __targets = new Target[targets.length]; 104 for (int i = 0; i < __targets.length; i++) { 105 __targets[i] = new Target(keys[i], targets[i]); 106 } 107 108 return __targets; 109 } 110 111 117 private Instruction[] __getTargets() { 118 return targets; 119 } 120 121 126 private int[] __getKeys() { 127 return keys; 128 } 129 130 public String toString() { 131 StringBuffer sb = new StringBuffer (super.toString()); 132 sb.append(", default:"); 133 sb.append(getDefault()); 134 sb.append("(offset:"); 135 sb.append(getDefault().getOffset()); 136 sb.append(")"); 137 sb.append(", "); 138 139 Target[] t = getTargets(); 140 for (int i = 0; i < t.length; i++) { 141 sb.append("{"); 142 sb.append(t[i].getKey()); 143 sb.append(":"); 144 sb.append(t[i].getTarget()); 145 sb.append("(offset:"); 146 sb.append(t[i].getTarget().getOffset()); 147 sb.append(")"); 148 sb.append("}"); 149 } 150 151 return sb.toString(); 152 } 153 154 155 156 157 158 public byte[] getBytes() { 159 byte[] bytes = super.getBytes(); 160 int offset = getOffset(); 161 162 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 163 baos.write(getOpcode()); 164 165 166 int pCount = 3 - (offset % 4); 167 for (int i = 0; i < pCount; i++) { 168 baos.write(0); } 170 171 172 int dOffset = getDefault().getOffset(); 174 byte[] dBytes = toBytes(dOffset - offset - pCount -1 ); 175 for (int i = 0; i < dBytes.length; i++) { 176 baos.write(dBytes[i]); 177 } 178 179 180 if (getOpcode() == Opcodes.LOOKUPSWITCH) { 181 183 byte[] np = toBytes(targets.length); 185 for (int i = 0; i < np.length; i++) { 186 baos.write(np[i]); 187 } 188 189 for (int i = 0; i < targets.length; i++) { 191 try { 192 baos.write(toBytes(keys[i])); 193 baos.write(toBytes(targets[i].getOffset() - offset -pCount-1)); 194 } 195 catch(Exception e) { 196 } 198 } 199 } 200 else { 201 int low = keys[0]; 203 int high = keys[keys.length - 1]; 204 205 try { 207 baos.write(toBytes(low)); 208 baos.write(toBytes(high)); 209 } 210 catch(Exception e) { 211 } 213 214 for (int i = 0; i < targets.length; i++) { 215 try { 216 baos.write(toBytes(targets[i].getOffset() - 217 offset - pCount - 1)); 218 } 219 catch(Exception e) { 220 } 222 } 223 } 224 225 byte[] __bytes = baos.toByteArray(); 226 return __bytes; 227 } 228 229 230 233 int getDefaultOffset() { 234 return defaultOffset; 235 } 236 237 240 void setDefault(Instruction deflt) { 241 this.deflt = deflt; 242 } 243 244 247 int[] getTargetOffsets() { 248 return targetOffsets; 249 } 250 251 254 void setTargets(Instruction[] targets) { 255 this.targets = targets; 256 } 257 258 259 262 int toInt(byte[] bytes, int start) { 263 byte b1 = bytes[start]; 264 byte b2 = bytes[start + 1]; 265 byte b3 = bytes[start + 2]; 266 byte b4 = bytes[start + 3]; 267 268 int i = (b1 << 24) & 0xff000000 | (b2 << 16) & 0xff0000| 269 (b3 << 8) & 0xff00 | (b4 & 0xff); 270 271 return i; 272 } 273 274 276 byte[] toBytes(int i) { 277 byte [] bytes = new byte[4]; 278 279 bytes[0] = (byte)((i >> 24) & 0xff); 280 bytes[1] = (byte)((i >> 16) & 0xff); 281 bytes[2] = (byte)((i >> 8) & 0xff); 282 bytes[3] = (byte)((i & 0xff)); 283 284 return bytes; 285 } 286 287 288 291 public class Target { 292 private int key; 293 private Instruction target; 294 295 Target(int key, Instruction target) { 296 this.key = key; 297 this.target = target; 298 } 299 300 303 public int getKey() { 304 return key; 305 } 306 307 310 public Instruction getTarget() { 311 return target; 312 } 313 } 314 } 315 | Popular Tags |