/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