KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > evaluation > value > InstructionOffsetValue


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21 package proguard.evaluation.value;
22
23 import proguard.classfile.ClassConstants;
24
25 /**
26  * This class represents a partially evaluated instruction offset. It can
27  * contain 0 or more specific instruction offsets.
28  *
29  * @author Eric Lafortune
30  */

31 public class InstructionOffsetValue extends Category1Value
32 {
33     public static final InstructionOffsetValue EMPTY_VALUE = new InstructionOffsetValue();
34
35
36     private int[] values;
37
38
39     private InstructionOffsetValue()
40     {
41     }
42
43
44     public InstructionOffsetValue(int value)
45     {
46         this.values = new int[] { value };
47     }
48
49
50     public InstructionOffsetValue(int[] values)
51     {
52         this.values = values;
53     }
54
55
56     public int instructionOffsetCount()
57     {
58         return values == null ? 0 : values.length;
59     }
60
61
62     public int instructionOffset(int index)
63     {
64         return values[index];
65     }
66
67
68     /**
69      * Returns whether the given value is present in this list of instruction
70      * offsets.
71      */

72     public boolean contains(int value)
73     {
74         if (values != null)
75         {
76             for (int index = 0; index < values.length; index++)
77             {
78                 if (values[index] == value)
79                 {
80                     return true;
81                 }
82             }
83         }
84
85         return false;
86     }
87
88
89     /**
90      * Returns the minimum value from this list of instruction offsets.
91      * Returns <code>Integer.MAX_VALUE</code> if the list is empty.
92      */

93     public int minimumValue()
94     {
95         int minimumValue = Integer.MAX_VALUE;
96
97         if (values != null)
98         {
99             for (int index = 0; index < values.length; index++)
100             {
101                 int value = values[index];
102
103                 if (minimumValue > value)
104                 {
105                     minimumValue = value;
106                 }
107             }
108         }
109
110         return minimumValue;
111     }
112
113
114     /**
115      * Returns the maximum value from this list of instruction offsets.
116      * Returns <code>Integer.MIN_VALUE</code> if the list is empty.
117      */

118     public int maximumValue()
119     {
120         int maximumValue = Integer.MIN_VALUE;
121
122         if (values != null)
123         {
124             for (int index = 0; index < values.length; index++)
125             {
126                 int value = values[index];
127
128                 if (maximumValue < value)
129                 {
130                     maximumValue = value;
131                 }
132             }
133         }
134
135         return maximumValue;
136     }
137
138
139     /**
140      * Returns the generalization of this InstructionOffsetValue and the given
141      * other InstructionOffsetValue. The values of the other InstructionOffsetValue
142      * are guaranteed to remain at the end of the list, in the same order.
143      */

144     public final Value generalize(InstructionOffsetValue other)
145     {
146         // If the values array of either is null, return the other one.
147
if (this.values == null)
148         {
149             return other;
150         }
151
152         if (other.values == null)
153         {
154             return this;
155         }
156
157         // Compute the length of the union of the arrays.
158
int newLength = this.values.length;
159         for (int index = 0; index < other.values.length; index++)
160         {
161             if (!this.contains(other.values[index]))
162             {
163                 newLength++;
164             }
165         }
166
167         // If the length of the union array is equal to the length of the values
168
// array of either, return it.
169
if (newLength == other.values.length)
170         {
171             return other;
172         }
173
174         // The ordering of the this array may not be right, so we can't just
175
// use it.
176
//if (newLength == this.values.length)
177
//{
178
// return this;
179
//}
180

181         // Create the union array.
182
int[] newValues = new int[newLength];
183
184         int newIndex = 0;
185
186         // Copy the values that are different from the other array.
187
for (int index = 0; index < this.values.length; index++)
188         {
189             if (!other.contains(this.values[index]))
190             {
191                 newValues[newIndex++] = this.values[index];
192             }
193         }
194
195         // Copy the values from the other array.
196
for (int index = 0; index < other.values.length; index++)
197         {
198             newValues[newIndex++] = other.values[index];
199         }
200
201         return new InstructionOffsetValue(newValues);
202     }
203
204
205     // Implementations for Value.
206

207     public final InstructionOffsetValue instructionOffsetValue()
208     {
209         return this;
210     }
211
212     public final Value generalize(Value other)
213     {
214         return this.generalize(other.instructionOffsetValue());
215     }
216
217     public final int computationalType()
218     {
219         return TYPE_INSTRUCTION_OFFSET;
220     }
221
222     public final String JavaDoc internalType()
223     {
224         return "" + ClassConstants.INTERNAL_TYPE_INT;
225     }
226
227
228     // Implementations for Object.
229

230     public boolean equals(Object JavaDoc object)
231     {
232         if (object == null ||
233             this.getClass() != object.getClass())
234         {
235             return false;
236         }
237
238         InstructionOffsetValue other = (InstructionOffsetValue)object;
239         if (this.values == other.values)
240         {
241             return true;
242         }
243
244         if (this.values == null ||
245             other.values == null ||
246             this.values.length != other.values.length)
247         {
248             return false;
249         }
250
251         for (int index = 0; index < other.values.length; index++)
252         {
253             if (!this.contains(other.values[index]))
254             {
255                 return false;
256             }
257         }
258
259         return true;
260     }
261
262
263     public int hashCode()
264     {
265         int hashCode = this.getClass().hashCode();
266
267         if (values != null)
268         {
269             for (int index = 0; index < values.length; index++)
270             {
271                 hashCode ^= values[index];
272             }
273         }
274
275         return hashCode;
276     }
277
278
279     public String JavaDoc toString()
280     {
281         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("o:");
282
283         if (values != null)
284         {
285             for (int index = 0; index < values.length; index++)
286             {
287                 if (index > 0)
288                 {
289                     buffer.append(',');
290                 }
291                 buffer.append(values[index]);
292             }
293         }
294
295         return buffer.toString();
296     }
297 }
298
Popular Tags