001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 */
018 package org.apache.bcel.classfile;
019
020 import java.io.DataInputStream;
021 import java.io.DataOutputStream;
022 import java.io.IOException;
023 import org.apache.bcel.Constants;
024
025 /**
026 * This class is derived from <em>Attribute</em> and declares this class as
027 * `synthetic', i.e., it needs special handling. The JVM specification
028 * states "A class member that does not appear in the source code must be
029 * marked using a Synthetic attribute." It may appear in the ClassFile
030 * attribute table, a field_info table or a method_info table. This class
031 * is intended to be instantiated from the
032 * <em>Attribute.readAttribute()</em> method.
033 *
034 * @version $Id: Synthetic.java 1152077 2011-07-29 02:29:42Z dbrosius $
035 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
036 * @see Attribute
037 */
038 public final class Synthetic extends Attribute {
039
040 private static final long serialVersionUID = -123334426995458366L;
041 private byte[] bytes;
042
043
044 /**
045 * Initialize from another object. Note that both objects use the same
046 * references (shallow copy). Use copy() for a physical copy.
047 */
048 public Synthetic(Synthetic c) {
049 this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
050 }
051
052
053 /**
054 * @param name_index Index in constant pool to CONSTANT_Utf8, which
055 * should represent the string "Synthetic".
056 * @param length Content length in bytes - should be zero.
057 * @param bytes Attribute contents
058 * @param constant_pool The constant pool this attribute is associated
059 * with.
060 */
061 public Synthetic(int name_index, int length, byte[] bytes, ConstantPool constant_pool) {
062 super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool);
063 this.bytes = bytes;
064 }
065
066
067 /**
068 * Construct object from file stream.
069 * @param name_index Index in constant pool to CONSTANT_Utf8
070 * @param length Content length in bytes
071 * @param file Input stream
072 * @param constant_pool Array of constants
073 * @throws IOException
074 */
075 Synthetic(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
076 throws IOException {
077 this(name_index, length, (byte[]) null, constant_pool);
078 if (length > 0) {
079 bytes = new byte[length];
080 file.readFully(bytes);
081 System.err.println("Synthetic attribute with length > 0");
082 }
083 }
084
085
086 /**
087 * Called by objects that are traversing the nodes of the tree implicitely
088 * defined by the contents of a Java class. I.e., the hierarchy of methods,
089 * fields, attributes, etc. spawns a tree of objects.
090 *
091 * @param v Visitor object
092 */
093 @Override
094 public void accept( Visitor v ) {
095 v.visitSynthetic(this);
096 }
097
098
099 /**
100 * Dump source file attribute to file stream in binary format.
101 *
102 * @param file Output file stream
103 * @throws IOException
104 */
105 @Override
106 public final void dump( DataOutputStream file ) throws IOException {
107 super.dump(file);
108 if (length > 0) {
109 file.write(bytes, 0, length);
110 }
111 }
112
113
114 /**
115 * @return data bytes.
116 */
117 public final byte[] getBytes() {
118 return bytes;
119 }
120
121
122 /**
123 * @param bytes
124 */
125 public final void setBytes( byte[] bytes ) {
126 this.bytes = bytes;
127 }
128
129
130 /**
131 * @return String representation.
132 */
133 @Override
134 public final String toString() {
135 StringBuilder buf = new StringBuilder("Synthetic");
136 if (length > 0) {
137 buf.append(" ").append(Utility.toHexString(bytes));
138 }
139 return buf.toString();
140 }
141
142
143 /**
144 * @return deep copy of this attribute
145 */
146 @Override
147 public Attribute copy( ConstantPool _constant_pool ) {
148 Synthetic c = (Synthetic) clone();
149 if (bytes != null) {
150 c.bytes = new byte[bytes.length];
151 System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
152 }
153 c.constant_pool = _constant_pool;
154 return c;
155 }
156 }