1/*** 2 * ASM: a very small and fast Java bytecode manipulation framework 3 * Copyright (c) 2000-2005 INRIA, France Telecom 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30package com.sleepycat.asm; 31 32/** 33 * A constant pool item. Constant pool items can be created with the 'newXXX' 34 * methods in the {@link ClassWriter} class. 35 * 36 * @author Eric Bruneton 37 */ 38final class Item { 39 40 /** 41 * Index of this item in the constant pool. 42 */ 43 int index; 44 45 /** 46 * Type of this constant pool item. A single class is used to represent all 47 * constant pool item types, in order to minimize the bytecode size of this 48 * package. The value of this field is one of {@link ClassWriter#INT}, 49 * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, 50 * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8}, 51 * {@link ClassWriter#STR}, {@link ClassWriter#CLASS}, 52 * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD}, 53 * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}. 54 */ 55 int type; 56 57 /** 58 * Value of this item, for an integer item. 59 */ 60 int intVal; 61 62 /** 63 * Value of this item, for a long item. 64 */ 65 long longVal; 66 67 /** 68 * Value of this item, for a float item. 69 */ 70 float floatVal; 71 72 /** 73 * Value of this item, for a double item. 74 */ 75 double doubleVal; 76 77 /** 78 * First part of the value of this item, for items that do not hold a 79 * primitive value. 80 */ 81 String strVal1; 82 83 /** 84 * Second part of the value of this item, for items that do not hold a 85 * primitive value. 86 */ 87 String strVal2; 88 89 /** 90 * Third part of the value of this item, for items that do not hold a 91 * primitive value. 92 */ 93 String strVal3; 94 95 /** 96 * The hash code value of this constant pool item. 97 */ 98 int hashCode; 99 100 /** 101 * Link to another constant pool item, used for collision lists in the 102 * constant pool's hash table. 103 */ 104 Item next; 105 106 /** 107 * Constructs an uninitialized {@link Item}. 108 */ 109 Item() { 110 } 111 112 Item(int index) { 113 this.index = index; 114 } 115 116 /** 117 * Constructs a copy of the given item. 118 * 119 * @param index index of the item to be constructed. 120 * @param i the item that must be copied into the item to be constructed. 121 */ 122 Item(final int index, final Item i) { 123 this.index = index; 124 type = i.type; 125 intVal = i.intVal; 126 longVal = i.longVal; 127 floatVal = i.floatVal; 128 doubleVal = i.doubleVal; 129 strVal1 = i.strVal1; 130 strVal2 = i.strVal2; 131 strVal3 = i.strVal3; 132 hashCode = i.hashCode; 133 } 134 135 /** 136 * Sets this item to an integer item. 137 * 138 * @param intVal the value of this item. 139 */ 140 void set(final int intVal) { 141 this.type = ClassWriter.INT; 142 this.intVal = intVal; 143 this.hashCode = 0x7FFFFFFF & (type + intVal); 144 } 145 146 /** 147 * Sets this item to a long item. 148 * 149 * @param longVal the value of this item. 150 */ 151 void set(final long longVal) { 152 this.type = ClassWriter.LONG; 153 this.longVal = longVal; 154 this.hashCode = 0x7FFFFFFF & (type + (int) longVal); 155 } 156 157 /** 158 * Sets this item to a float item. 159 * 160 * @param floatVal the value of this item. 161 */ 162 void set(final float floatVal) { 163 this.type = ClassWriter.FLOAT; 164 this.floatVal = floatVal; 165 this.hashCode = 0x7FFFFFFF & (type + (int) floatVal); 166 } 167 168 /** 169 * Sets this item to a double item. 170 * 171 * @param doubleVal the value of this item. 172 */ 173 void set(final double doubleVal) { 174 this.type = ClassWriter.DOUBLE; 175 this.doubleVal = doubleVal; 176 this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal); 177 } 178 179 /** 180 * Sets this item to an item that do not hold a primitive value. 181 * 182 * @param type the type of this item. 183 * @param strVal1 first part of the value of this item. 184 * @param strVal2 second part of the value of this item. 185 * @param strVal3 third part of the value of this item. 186 */ 187 void set( 188 final int type, 189 final String strVal1, 190 final String strVal2, 191 final String strVal3) 192 { 193 this.type = type; 194 this.strVal1 = strVal1; 195 this.strVal2 = strVal2; 196 this.strVal3 = strVal3; 197 switch (type) { 198 case ClassWriter.UTF8: 199 case ClassWriter.STR: 200 case ClassWriter.CLASS: 201 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); 202 return; 203 case ClassWriter.NAME_TYPE: 204 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() 205 * strVal2.hashCode()); 206 return; 207 // ClassWriter.FIELD: 208 // ClassWriter.METH: 209 // ClassWriter.IMETH: 210 default: 211 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() 212 * strVal2.hashCode() * strVal3.hashCode()); 213 } 214 } 215 216 /** 217 * Indicates if the given item is equal to this one. 218 * 219 * @param i the item to be compared to this one. 220 * @return <tt>true</tt> if the given item if equal to this one, 221 * <tt>false</tt> otherwise. 222 */ 223 boolean isEqualTo(final Item i) { 224 if (i.type == type) { 225 switch (type) { 226 case ClassWriter.INT: 227 return i.intVal == intVal; 228 case ClassWriter.LONG: 229 return i.longVal == longVal; 230 case ClassWriter.FLOAT: 231 return i.floatVal == floatVal; 232 case ClassWriter.DOUBLE: 233 return i.doubleVal == doubleVal; 234 case ClassWriter.UTF8: 235 case ClassWriter.STR: 236 case ClassWriter.CLASS: 237 return i.strVal1.equals(strVal1); 238 case ClassWriter.NAME_TYPE: 239 return i.strVal1.equals(strVal1) 240 && i.strVal2.equals(strVal2); 241 // ClassWriter.FIELD: 242 // ClassWriter.METH: 243 // ClassWriter.IMETH: 244 default: 245 return i.strVal1.equals(strVal1) 246 && i.strVal2.equals(strVal2) 247 && i.strVal3.equals(strVal3); 248 } 249 } 250 return false; 251 } 252} 253