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