/Users/lyon/j4p/src/javassist/bytecode/AttributeInfo.java
|
1 /*
2 * Javassist, a Java-bytecode translator toolkit.
3 * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. Alternatively, the contents of this file may be used under
8 * the terms of the GNU Lesser General Public License Version 2.1 or later.
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 */
15
16 package javassist.bytecode;
17
18 import java.io.DataInputStream;
19 import java.io.DataOutputStream;
20 import java.io.IOException;
21 import java.util.Map;
22 import java.util.LinkedList;
23 import java.util.ListIterator;
24
25 // Note: if you define a new subclass of AttributeInfo, then
26 // update AttributeInfo.read().
27
28 /**
29 * <code>attribute_info</code> structure.
30 */
31 public class AttributeInfo {
32 protected ConstPool constPool;
33 int name;
34 byte[] info;
35
36 protected AttributeInfo(ConstPool cp, int attrname, byte[] attrinfo) {
37 constPool = cp;
38 name = attrname;
39 info = attrinfo;
40 }
41
42 protected AttributeInfo(ConstPool cp, String attrname) {
43 this(cp, attrname, (byte[]) null);
44 }
45
46 /**
47 * Constructs an <code>attribute_info</code> structure.
48 *
49 * @param cp constant pool table
50 * @param attrname attribute name
51 * @param attrinfo <code>info</code> field
52 * of <code>attribute_info</code> structure.
53 */
54 public AttributeInfo(ConstPool cp, String attrname, byte[] attrinfo) {
55 this(cp, cp.addUtf8Info(attrname), attrinfo);
56 }
57
58 protected AttributeInfo(ConstPool cp, int n, DataInputStream in)
59 throws IOException {
60 constPool = cp;
61 name = n;
62 int len = in.readInt();
63 info = new byte[len];
64 if (len > 0)
65 in.readFully(info);
66 }
67
68 static AttributeInfo read(ConstPool cp, DataInputStream in)
69 throws IOException {
70 int name = in.readUnsignedShort();
71 String nameStr = cp.getUtf8Info(name);
72 if (nameStr.equals(CodeAttribute.tag))
73 return new CodeAttribute(cp, name, in);
74 else if (nameStr.equals(ExceptionsAttribute.tag))
75 return new ExceptionsAttribute(cp, name, in);
76 else if (nameStr.equals(ConstantAttribute.tag))
77 return new ConstantAttribute(cp, name, in);
78 else if (nameStr.equals(SourceFileAttribute.tag))
79 return new SourceFileAttribute(cp, name, in);
80 else if (nameStr.equals(LineNumberAttribute.tag))
81 return new LineNumberAttribute(cp, name, in);
82 else if (nameStr.equals(SyntheticAttribute.tag))
83 return new SyntheticAttribute(cp, name, in);
84 else if (nameStr.equals(InnerClassesAttribute.tag))
85 return new InnerClassesAttribute(cp, name, in);
86 else
87 return new AttributeInfo(cp, name, in);
88 }
89
90 /**
91 * Returns an attribute name.
92 */
93 public String getName() {
94 return constPool.getUtf8Info(name);
95 }
96
97 /**
98 * Returns a constant pool table.
99 */
100 public ConstPool getConstPool() {
101 return constPool;
102 }
103
104 /**
105 * Returns the length of this <code>attribute_info</code>
106 * structure.
107 * The returned value is <code>attribute_length + 6</code>.
108 */
109 public int length() {
110 return info.length + 6;
111 }
112
113 /**
114 * Returns the <code>info</code> field
115 * of this <code>attribute_info</code> structure.
116 *
117 * <p>This method is not available if the object is an instance
118 * of <code>CodeAttribute</code>.
119 */
120 public byte[] get() {
121 return info;
122 }
123
124 /**
125 * Sets the <code>info</code> field
126 * of this <code>attribute_info</code> structure.
127 *
128 * <p>This method is not available if the object is an instance
129 * of <code>CodeAttribute</code>.
130 */
131 public void set(byte[] newinfo) {
132 info = newinfo;
133 }
134
135 /**
136 * Makes a copy. Class names are replaced according to the
137 * given <code>Map</code> object.
138 *
139 * @param newCp the constant pool table used by the new copy.
140 * @param classnames pairs of replaced and substituted
141 * class names.
142 */
143 public AttributeInfo copy(ConstPool newCp, Map classnames) {
144 int s = info.length;
145 byte[] newInfo = new byte[s];
146 for (int i = 0; i < s; ++i)
147 newInfo[i] = info[i];
148
149 return new AttributeInfo(newCp, getName(), newInfo);
150 }
151
152 void write(DataOutputStream out) throws IOException {
153 out.writeShort(name);
154 out.writeInt(info.length);
155 if (info.length > 0)
156 out.write(info);
157 }
158
159 static int getLength(LinkedList list) {
160 int size = 0;
161 int n = list.size();
162 for (int i = 0; i < n; ++i) {
163 AttributeInfo attr = (AttributeInfo) list.get(i);
164 size += attr.length();
165 }
166
167 return size;
168 }
169
170 static AttributeInfo lookup(LinkedList list, String name) {
171 if (list == null)
172 return null;
173
174 ListIterator iterator = list.listIterator();
175 while (iterator.hasNext()) {
176 AttributeInfo ai = (AttributeInfo) iterator.next();
177 if (ai.getName().equals(name))
178 return ai;
179 }
180
181 return null; // no such attribute
182 }
183
184 static AttributeInfo lookup(LinkedList list, Class type) {
185 if (list == null)
186 return null;
187
188 ListIterator iterator = list.listIterator();
189 while (iterator.hasNext()) {
190 Object obj = iterator.next();
191 if (type.isInstance(obj))
192 return (AttributeInfo) obj;
193 }
194
195 return null; // no such attribute
196 }
197
198 static synchronized void remove(LinkedList list, String name) {
199 if (list == null)
200 return;
201
202 ListIterator iterator = list.listIterator();
203 while (iterator.hasNext()) {
204 AttributeInfo ai = (AttributeInfo) iterator.next();
205 if (ai.getName().equals(name))
206 iterator.remove();
207 }
208 }
209
210 static synchronized void remove(LinkedList list, Class type) {
211 if (list == null)
212 return;
213
214 ListIterator iterator = list.listIterator();
215 while (iterator.hasNext()) {
216 Object obj = iterator.next();
217 if (type.isInstance(obj))
218 iterator.remove();
219 }
220 }
221
222 static void writeAll(LinkedList list, DataOutputStream out)
223 throws IOException {
224 if (list == null)
225 return;
226
227 int n = list.size();
228 for (int i = 0; i < n; ++i) {
229 AttributeInfo attr = (AttributeInfo) list.get(i);
230 attr.write(out);
231 }
232 }
233 }
234