1 20 package edu.umd.cs.findbugs; 21 22 import java.util.ArrayList ; 23 import java.util.List ; 24 25 import edu.umd.cs.findbugs.visitclass.DismantleBytecode; 26 27 28 public class SwitchHandler 29 { 30 private List <SwitchDetails> switchOffsetStack; 31 32 public SwitchHandler() { 33 switchOffsetStack = new ArrayList <SwitchDetails>(); 34 } 35 36 public void enterSwitch( DismantleBytecode dbc ) { 37 38 SwitchDetails details = new SwitchDetails( dbc.getPC(), dbc.getSwitchOffsets(), dbc.getDefaultSwitchOffset()); 39 40 int size = switchOffsetStack.size(); 41 while (--size >= 0) { 42 SwitchDetails existingDetail = switchOffsetStack.get(size); 43 if (details.switchPC > (existingDetail.switchPC + existingDetail.swOffsets[existingDetail.swOffsets.length-1])) 44 switchOffsetStack.remove(size); 45 } 46 switchOffsetStack.add(details); 47 } 48 49 public boolean isOnSwitchOffset( DismantleBytecode dbc ) { 50 int pc = dbc.getPC(); 51 if (pc == getDefaultOffset()) 52 return false; 53 54 return (pc == getNextSwitchOffset(dbc)); 55 } 56 57 public int getNextSwitchOffset( DismantleBytecode dbc ) { 58 int size = switchOffsetStack.size(); 59 while (size > 0) { 60 SwitchDetails details = switchOffsetStack.get(size-1); 61 62 int nextSwitchOffset = details.getNextSwitchOffset(dbc.getPC()); 63 if (nextSwitchOffset >= 0) 64 return nextSwitchOffset; 65 66 switchOffsetStack.remove(size-1); 67 size--; 68 } 69 70 return -1; 71 } 72 73 public int getDefaultOffset() { 74 int size = switchOffsetStack.size(); 75 if (size == 0) 76 return -1; 77 78 SwitchDetails details = switchOffsetStack.get(size-1); 79 return details.getDefaultOffset(); 80 } 81 82 public static class SwitchDetails 83 { 84 int switchPC; 85 int[] swOffsets; 86 int defaultOffset; 87 int nextOffset; 88 89 public SwitchDetails(int pc, int[] offsets, int defOffset) { 90 switchPC = pc; 91 int uniqueOffsets = 0; 92 int lastValue = -1; 93 for (int offset : offsets) { 94 if (offset != lastValue) { 95 uniqueOffsets++; 96 lastValue = offset; 97 } 98 } 99 100 swOffsets = new int[uniqueOffsets]; 101 int insertPos = 0; 102 lastValue = -1; 103 for (int offset1 : offsets) { 104 if (offset1 != lastValue) { 105 swOffsets[insertPos++] = offset1; 106 lastValue = offset1; 107 } 108 } 109 defaultOffset = defOffset; 110 nextOffset = 0; 111 } 112 113 public int getNextSwitchOffset(int currentPC) { 114 while ((nextOffset < swOffsets.length) && (currentPC > (switchPC + swOffsets[nextOffset]))) 115 nextOffset++; 116 117 if (nextOffset >= swOffsets.length) 118 return -1; 119 120 return switchPC + swOffsets[nextOffset]; 121 } 122 123 public int getDefaultOffset() { 124 return switchPC + defaultOffset; 125 } 126 } 127 } 128 | Popular Tags |