1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved. 2 * 3 * This program and the accompanying materials are made available under 4 * the terms of the Common Public License v1.0 which accompanies this distribution, 5 * and is available at http://www.eclipse.org/legal/cpl-v10.html 6 * 7 * $Id: Field_info.java,v 1.1.1.1 2004/05/09 16:57:45 vlad_r Exp $ 8 */ 9 package com.vladium.jcd.cls; 10 11 import java.io.IOException; 12 13 import com.vladium.jcd.cls.attribute.*; 14 import com.vladium.jcd.cls.constant.CONSTANT_Utf8_info; 15 import com.vladium.jcd.lib.UDataInputStream; 16 import com.vladium.jcd.lib.UDataOutputStream; 17 18 // ---------------------------------------------------------------------------- 19 /** 20 * Each class field is described by a variable-length field_info structure. The 21 * format of this structure is 22 * <PRE> 23 * field_info { 24 * u2 access_flags; 25 * u2 name_index; 26 * u2 descriptor_index; 27 * u2 attributes_count; 28 * attribute_info attributes[attributes_count]; 29 * } 30 * </PRE> 31 * 32 * The value of the access_flags item is a mask of modifiers used to describe 33 * access permission to and properties of a field.<P> 34 * 35 * The value of the name_index item must be a valid index into the constant pool 36 * table. The constant pool entry at that index must be a {@link CONSTANT_Utf8_info} 37 * structure which must represent a valid Java field name stored as a simple (not 38 * fully qualified) name, that is, as a Java identifier.<P> 39 * 40 * The value of the descriptor_index item must be a valid index into the constant 41 * pool table. The constant pool entry at that index must be a 42 * {@link CONSTANT_Utf8_info} structure which must represent a valid Java field 43 * descriptor.<P> 44 * 45 * Each value of the attributes table must be a variable-length attribute structure. 46 * A field can have any number of attributes associated with it. The only attribute 47 * defined for the attributes table of a field_info structure at the moment 48 * is the ConstantValue attribute -- see {@link ConstantValueAttribute_info}. 49 * 50 * @author (C) 2001, Vlad Roubtsov 51 */ 52 public 53 final class Field_info implements Cloneable, IAccessFlags 54 { 55 // public: ................................................................ 56 57 58 public int m_name_index; 59 public int m_descriptor_index; 60 61 62 public Field_info (final int access_flags, 63 final int name_index, final int descriptor_index, 64 final IAttributeCollection attributes) 65 { 66 m_access_flags = access_flags; 67 68 m_name_index = name_index; 69 m_descriptor_index = descriptor_index; 70 71 m_attributes = attributes; 72 } 73 74 public Field_info (final IConstantCollection constants, 75 final UDataInputStream bytes) 76 throws IOException 77 { 78 m_access_flags = bytes.readU2 (); 79 80 m_name_index = bytes.readU2 (); 81 m_descriptor_index = bytes.readU2 (); 82 83 // TODO: put this logic into AttributeCollection 84 final int attributes_count = bytes.readU2 (); 85 m_attributes = ElementFactory.newAttributeCollection (attributes_count); 86 87 for (int i = 0; i < attributes_count; i++) 88 { 89 final Attribute_info attribute_info = Attribute_info.new_Attribute_info (constants, bytes); 90 if (DEBUG) System.out.println ("\t[" + i + "] attribute: " + attribute_info); 91 92 m_attributes.add (attribute_info); 93 } 94 } 95 96 /** 97 * Returns the field name within the context of 'cls' class definition. 98 * 99 * @param cls class that contains this field 100 * @return field name 101 */ 102 public String getName (final ClassDef cls) 103 { 104 return ((CONSTANT_Utf8_info) cls.getConstants ().get (m_name_index)).m_value; 105 } 106 107 /** 108 * Returns the descriptor string for this field within the context of 'cls' 109 * class definition. 110 * 111 * @param cls class that contains this field 112 * @return field typename descriptor 113 */ 114 public String getDescriptor (final ClassDef cls) 115 { 116 return ((CONSTANT_Utf8_info) cls.getConstants ().get (m_descriptor_index)).m_value; 117 } 118 119 public boolean isSynthetic () 120 { 121 return m_attributes.hasSynthetic (); 122 } 123 124 // IAccessFlags: 125 126 public final void setAccessFlags (final int flags) 127 { 128 m_access_flags = flags; 129 } 130 131 public final int getAccessFlags () 132 { 133 return m_access_flags; 134 } 135 136 public IAttributeCollection getAttributes () 137 { 138 return m_attributes; 139 } 140 141 142 public String toString () 143 { 144 return "field_info: [modifiers: 0x" + Integer.toHexString(m_access_flags) + ", name_index = " + m_name_index + ", descriptor_index = " + m_descriptor_index + ']'; 145 } 146 147 148 // Cloneable: 149 150 /** 151 * Performs a deep copy. 152 */ 153 public Object clone () 154 { 155 try 156 { 157 final Field_info _clone = (Field_info) super.clone (); 158 159 // do deep copy: 160 _clone.m_attributes = (IAttributeCollection) m_attributes.clone (); 161 162 return _clone; 163 } 164 catch (CloneNotSupportedException e) 165 { 166 throw new InternalError (e.toString ()); 167 } 168 } 169 170 171 // IClassFormatOutput: 172 173 public void writeInClassFormat (final UDataOutputStream out) throws IOException 174 { 175 out.writeU2 (m_access_flags); 176 177 out.writeU2 (m_name_index); 178 out.writeU2 (m_descriptor_index); 179 180 m_attributes.writeInClassFormat (out); 181 } 182 183 // protected: ............................................................. 184 185 // package: ............................................................... 186 187 // private: ............................................................... 188 189 190 private int m_access_flags; 191 private IAttributeCollection m_attributes; // never null 192 193 194 private static final boolean DEBUG = false; 195 196 } // end of class 197 // ---------------------------------------------------------------------------- 198