KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > SwitchHandler


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2005 Dave Brosius
4  * Copyright (C) 2005 University of Maryland
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */

20 package edu.umd.cs.findbugs;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.List JavaDoc;
24
25 import edu.umd.cs.findbugs.visitclass.DismantleBytecode;
26
27
28 public class SwitchHandler
29 {
30     private List JavaDoc<SwitchDetails> switchOffsetStack;
31     
32     public SwitchHandler() {
33         switchOffsetStack = new ArrayList JavaDoc<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