1 23 24 25 package com.sun.jdo.api.persistence.enhancer.classfile; 26 27 import java.util.Stack ; 28 import java.util.Map ; 29 30 32 33 36 37 public class Descriptor implements VMConstants { 38 42 public static int countMethodArgWords(String sig) { 43 if (sig.charAt(0) != '(') 44 throw new InsnError ("not a method signature"); int count = 0; 46 for (int idx = 1; sig.charAt(idx) != ')'; idx++) { 47 switch (sig.charAt(idx)) { 48 case 'B': 49 case 'C': 50 case 'S': 51 case 'I': 52 case 'F': 53 case 'Z': 54 count++; 55 break; 56 case 'J': 57 case 'D': 58 count += 2; 59 break; 60 case 'L': 61 count++; 62 idx = sig.indexOf(';', idx); 63 break; 64 case '[': 65 count++; 66 while (sig.charAt(idx) == '[' || sig.charAt(idx) == ']') 67 idx++; 68 if (sig.charAt(idx) == 'L') 69 idx = sig.indexOf(';', idx); 70 71 break; 72 default: 73 throw new InsnError("missing case"); } 75 } 76 return count; 77 } 78 79 83 public static int countMethodReturnWords(String sig) { 84 int idx = sig.lastIndexOf(')') + 1; 85 if (idx == 0) 86 throw new InsnError ("not a method signature"); switch (sig.charAt(idx)) { 88 case 'J': 89 case 'D': 90 return 2; 91 case 'B': 92 case 'C': 93 case 'S': 94 case 'I': 95 case 'F': 96 case 'Z': 97 case 'L': 98 case '[': 99 return 1; 100 case 'V': 101 return 0; 102 default: 103 throw new InsnError("missing case"); } 105 } 106 107 111 public static String extractResultSig(String methodSig) { 112 return methodSig.substring(methodSig.indexOf(')')+1); 113 } 114 115 119 public static String extractArgSig(String methodSig) { 120 return methodSig.substring(1, methodSig.indexOf(')')); 121 } 122 123 128 public static String extractReversedArgSig(String methodSig) { 129 StringBuffer buf = new StringBuffer ();; 130 reverseArgSig(buf, methodSig, 1); 131 return buf.toString(); 132 } 133 134 139 private static void reverseArgSig(StringBuffer buf, String methodSig, 140 int idx) { 141 char c = methodSig.charAt(idx); 142 if (c == ')') 143 return; 144 int startIdx = idx; 145 146 switch(c) { 147 case 'B': 148 case 'C': 149 case 'S': 150 case 'I': 151 case 'F': 152 case 'J': 153 case 'D': 154 case 'Z': 155 idx = idx+1; 156 break; 157 case '[': 158 while (methodSig.charAt(idx) == '[' || methodSig.charAt(idx) == ']') 159 idx++; 160 if (methodSig.charAt(idx) != 'L') { 161 idx++; 162 break; 163 } 164 165 case 'L': 166 idx = methodSig.indexOf(';', idx) + 1; 167 break; 168 default: 169 throw new InsnError("bad signature char"); } 171 172 reverseArgSig(buf, methodSig, idx); 173 while (startIdx < idx) 174 buf.append(methodSig.charAt(startIdx++)); 175 } 176 177 180 public static int countFieldWords(String sig) { 182 if (sig == null || sig.length() < 1) 183 throw new InsnError ("not a field signature"); switch (sig.charAt(0)) { 185 case 'J': 186 case 'D': 187 return 2; 188 case 'B': 189 case 'C': 190 case 'S': 191 case 'I': 192 case 'F': 193 case 'Z': 194 case 'L': 195 case '[': 196 return 1; 197 default: 198 throw new InsnError("missing case"); } 200 } 201 202 205 public static int elementType(String sig) { 207 if (sig == null || sig.length() < 1) 208 throw new InsnError ("not a value signature"); switch(sig.charAt(0)) { 210 case 'B': 211 return T_BOOLEAN; 212 case 'C': 213 return T_CHAR; 214 case 'Z': 215 return T_BYTE; 216 case 'S': 217 return T_SHORT; 218 case 'I': 219 return T_INT; 220 case 'J': 221 return T_LONG; 222 case 'F': 223 return T_FLOAT; 224 case 'D': 225 return T_DOUBLE; 226 case '[': 227 return TC_OBJECT; 228 case 'L': 229 return TC_OBJECT; 230 default: 231 throw new InsnError("bad signature char"); } 233 } 234 235 239 public static String elementSig(int valueType) { 240 switch(valueType) { 241 case T_BYTE: 242 return "B"; case T_CHAR: 244 return "C"; case T_BOOLEAN: 246 return "Z"; case T_SHORT: 248 return "S"; case T_INT: 250 return "I"; case T_LONG: 252 return "J"; case T_FLOAT: 254 return "F"; case T_DOUBLE: 256 return "D"; case TC_OBJECT: 258 return "Ljava/lang/Object;"; default: 260 throw new InsnError("bad element type"); } 262 } 263 264 268 public static int elementSize(int elementType) { 269 switch(elementType) { 270 case T_LONG: 271 case T_DOUBLE: 272 case T_TWOWORD: 273 return 2; 274 default: 275 return 1; 276 } 277 } 278 279 285 public static void computeStackTypes(String stackSig, Stack stack) { 286 for (int idx = 0; idx < stackSig.length(); idx++) { 287 int tp = 0; 288 switch(stackSig.charAt(idx)) { 289 case 'B': 290 case 'C': 291 case 'Z': 292 case 'S': 293 case 'I': 294 tp = T_INT; 295 break; 296 case 'F': 297 tp = T_FLOAT; 298 break; 299 case 'J': 300 tp = T_LONG; 301 break; 302 case 'D': 303 tp = T_DOUBLE; 304 break; 305 case '?': 306 tp = T_UNKNOWN; 307 break; 308 case 'W': 309 tp = T_WORD; 310 break; 311 case 'X': 312 tp = T_TWOWORD; 313 break; 314 case 'A': 315 316 tp = TC_OBJECT; 317 break; 318 case '[': 319 tp = TC_OBJECT; 320 while (stackSig.charAt(idx) == '[' || stackSig.charAt(idx) == ']') 321 idx++; 322 if (stackSig.charAt(idx) != 'L') 323 break; 324 325 case 'L': 326 tp = TC_OBJECT; 327 idx = stackSig.indexOf(';', idx); 328 break; 329 default: 330 throw new InsnError("bad signature char"); } 332 stack.push(new Integer (tp)); 333 } 334 } 335 336 342 public static int nextSigElement(String stackSig, int idx) { 343 switch(stackSig.charAt(idx)) { 344 case 'B': 345 case 'C': 346 case 'Z': 347 case 'S': 348 case 'I': 349 case 'F': 350 case 'J': 351 case 'D': 352 break; 353 case '[': 354 while (stackSig.charAt(idx) == '[' || stackSig.charAt(idx) == ']') 355 idx++; 356 if (stackSig.charAt(idx) != 'L') 357 break; 358 359 case 'L': 360 idx = stackSig.indexOf(';', idx); 361 break; 362 default: 363 throw new InsnError("bad signature char"); } 365 366 idx++; 367 return idx; 368 } 369 370 377 public static String remapTypes(String sig, Map classTranslations) { 378 379 StringBuffer buf = null; 380 381 for (int idx = 0; idx < sig.length(); idx++) { 382 char c; 383 switch(c = sig.charAt(idx)) { 384 case '[': 385 386 while ((c = sig.charAt(idx)) == '[' || c == ']') { 387 idx++; 388 if (buf != null) 389 buf.append(c); 390 } 391 392 394 if (sig.charAt(idx) != 'L') 395 break; 396 397 case 'L': 398 399 idx++; 400 int endIdx = sig.indexOf(';', idx); 401 String typeName = sig.substring(idx, endIdx); 402 String mapTo = (String ) classTranslations.get(typeName); 403 if (mapTo != null) { 404 406 if (buf == null) { 407 buf = new StringBuffer (sig.length() + 20); 408 buf.append(sig.substring(0,idx-1)); 409 } 410 typeName = mapTo; 411 } 412 413 if (buf != null) { 414 buf.append('L'); 415 buf.append(typeName); 416 } 417 idx = endIdx; 418 c = ';'; 419 break; 420 } 421 422 if (buf != null) 423 buf.append(c); 424 } 425 return (buf == null) ? sig : (buf.toString()); 426 } 427 428 435 public static String translateClass( 436 String cls, Map classTranslations) { 437 if (cls.charAt(0) == '[') 438 return remapTypes(cls, classTranslations); 439 else { 440 String mapTo = (String ) classTranslations.get(cls); 441 if (mapTo != null) 442 return mapTo; 443 return cls; 444 } 445 } 446 447 451 public static String userFieldSig(String vmSig) { 452 return userFieldSig(vmSig, 0); 453 } 454 455 458 public static String userFieldSig(String vmSig, int idx) { 459 String sigElement = ""; int arrayDims = 0; 461 boolean moreSig = true; 462 while (moreSig) { 463 moreSig = false; 464 char c = vmSig.charAt(idx); 465 switch (c) { 466 case 'B': 467 sigElement = "byte"; break; 469 case 'C': 470 sigElement = "char"; break; 472 case 'Z': 473 sigElement = "boolean"; break; 475 case 'S': 476 sigElement = "short"; break; 478 case 'I': 479 sigElement = "int"; break; 481 case 'F': 482 sigElement = "float"; break; 484 case 'J': 485 sigElement = "long"; break; 487 case 'D': 488 sigElement = "double"; break; 490 case 'V': 491 494 sigElement = "void"; break; 496 case '[': 497 idx++; 498 arrayDims++; 499 moreSig = true; 500 break; 501 case 'L': 502 int nextIdx = vmSig.indexOf(';', idx); 503 sigElement = vmSig.substring(idx+1,nextIdx).replace('/','.'); 504 break; 505 default: 506 throw new InsnError("bad signature char"); } 508 } 509 510 511 if (arrayDims == 0) 512 return sigElement; 513 514 515 StringBuffer buf = new StringBuffer (sigElement.length() + 2 * arrayDims); 516 buf.append(sigElement); 517 while (arrayDims-- > 0) 518 buf.append("[]"); 520 return buf.toString(); 521 } 522 523 527 public static String userMethodArgs(String methodSig) { 528 529 if (methodSig.charAt(0) != '(') 530 throw new InsnError("Invalid method signature"); 532 StringBuffer buf = new StringBuffer (); 533 534 buf.append('('); 535 536 int idx = 1; 537 boolean firstArg = true; 538 while (methodSig.charAt(idx) != ')') { 539 if (firstArg) 540 firstArg = false; 541 else 542 buf.append(", "); 544 buf.append(userFieldSig(methodSig, idx)); 545 idx = nextSigElement(methodSig, idx); 546 } 547 548 buf.append(')'); 549 return buf.toString(); 550 } 551 552 } 553 | Popular Tags |