1 /*
  2  * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 package org.openjdk.asmtools.jdis;
 24 
 25 import org.openjdk.asmtools.jasm.JasmTokens;
 26 import org.openjdk.asmtools.jasm.Modifiers;
 27 
 28 import java.io.DataInputStream;
 29 import java.io.IOException;
 30 
 31 import static java.lang.String.format;
 32 import static org.openjdk.asmtools.jasm.Tables.AttrTag;
 33 import static org.openjdk.asmtools.jasm.Tables.CF_Context;
 34 import static org.openjdk.asmtools.jdis.TraceUtils.traceln;
 35 
 36 /**
 37  * Field data for field members in a class of the Java Disassembler
 38  */
 39 public class FieldData extends MemberData {
 40 
 41     // CP index to the field name
 42     protected int name_cpx;
 43     // CP index to the field type
 44     protected int type_cpx;
 45     // CP index to the field value
 46     protected int value_cpx = 0;
 47 
 48     public FieldData(ClassData cls) {
 49         super(cls);
 50         memberType = "FieldData";
 51     }
 52 
 53     @Override
 54     protected boolean handleAttributes(DataInputStream in, AttrTag attrtag, int attrlen) throws IOException {
 55         // Read the Attributes
 56         boolean handled = true;
 57         switch (attrtag) {
 58             case ATT_Signature:
 59                 if( signature != null ) {
 60                     traceln("Record attribute:  more than one attribute Signature are in component.attribute_info_attributes[attribute_count]");
 61                     traceln("Last one will be used.");
 62                 }
 63                 signature = new SignatureData(cls).read(in, attrlen);
 64                 break;
 65             case ATT_ConstantValue:
 66                 if (attrlen != 2) {
 67                     throw new ClassFormatError(format("%s: Invalid attribute length #%d", AttrTag.ATT_ConstantValue.printval(), attrlen));
 68                 }
 69                 value_cpx = in.readUnsignedShort();
 70                 break;
 71             default:
 72                 handled = false;
 73                 break;
 74         }
 75         return handled;
 76     }
 77 
 78     /**
 79      * Read and resolve the field data called from ClassData.
 80      * Precondition: NumFields has already been read from the stream.
 81      */
 82     public void read(DataInputStream in) throws IOException {
 83         // read the Fields CP indexes
 84         access = in.readUnsignedShort();
 85         name_cpx = in.readUnsignedShort();
 86         type_cpx = in.readUnsignedShort();
 87         // Read the attributes
 88         readAttributes(in);
 89         //
 90         TraceUtils.traceln(2,
 91                 format("FieldData: name[%d]=%s type[%d]=%s%s",
 92                         name_cpx, cls.pool.getString(name_cpx),
 93                         type_cpx, cls.pool.getString(type_cpx),
 94                         signature != null ? signature : ""));
 95     }
 96 
 97 
 98     /**
 99      * Prints the field data to the current output stream. called from ClassData.
100      */
101     @Override
102     public void print() throws IOException {
103         // Print annotations first
104         super.printAnnotations(getIndentString());
105 
106         StringBuilder bodyPrefix = new StringBuilder(getIndentString()).append(Modifiers.accessString(access, CF_Context.CTX_FIELD));
107         StringBuilder tailPrefix = new StringBuilder();
108 
109         if (isSynthetic) {
110             bodyPrefix.append(JasmTokens.Token.SYNTHETIC.parseKey()).append(' ');
111         }
112         if (isDeprecated) {
113             bodyPrefix.append(JasmTokens.Token.DEPRECATED.parseKey()).append(' ');
114         }
115 
116         // field
117         bodyPrefix.append(JasmTokens.Token.FIELDREF.parseKey()).append(' ');
118 
119         if (value_cpx != 0) {
120             tailPrefix.append("\t= ").append(cls.pool.ConstantStrValue(value_cpx));
121         }
122 
123         printVar(bodyPrefix, tailPrefix,name_cpx, type_cpx);
124     }
125 } // end FieldData
126