1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 package org.apache.bcel.classfile; 19 20 import java.io.DataInput; 21 import java.io.DataOutputStream; 22 import java.io.IOException; 23 24 import org.apache.bcel.Const; 25 26 /** 27 * This class is derived from <em>Attribute</em> and declares this class as 28 * `synthetic', i.e., it needs special handling. The JVM specification 29 * states "A class member that does not appear in the source code must be 30 * marked using a Synthetic attribute." It may appear in the ClassFile 31 * attribute table, a field_info table or a method_info table. This class 32 * is intended to be instantiated from the 33 * <em>Attribute.readAttribute()</em> method. 34 * 35 * @version $Id$ 36 * @see Attribute 37 */ 38 public final class Synthetic extends Attribute { 39 40 private byte[] bytes; 41 42 43 /** 44 * Initialize from another object. Note that both objects use the same 45 * references (shallow copy). Use copy() for a physical copy. 46 */ Synthetic(final Synthetic c)47 public Synthetic(final Synthetic c) { 48 this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); 49 } 50 51 52 /** 53 * @param name_index Index in constant pool to CONSTANT_Utf8, which 54 * should represent the string "Synthetic". 55 * @param length Content length in bytes - should be zero. 56 * @param bytes Attribute contents 57 * @param constant_pool The constant pool this attribute is associated 58 * with. 59 */ Synthetic(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool)60 public Synthetic(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool) { 61 super(Const.ATTR_SYNTHETIC, name_index, length, constant_pool); 62 this.bytes = bytes; 63 } 64 65 66 /** 67 * Construct object from input stream. 68 * 69 * @param name_index Index in constant pool to CONSTANT_Utf8 70 * @param length Content length in bytes 71 * @param input Input stream 72 * @param constant_pool Array of constants 73 * @throws IOException 74 */ Synthetic(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool)75 Synthetic(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) 76 throws IOException { 77 this(name_index, length, (byte[]) null, constant_pool); 78 if (length > 0) { 79 bytes = new byte[length]; 80 input.readFully(bytes); 81 System.err.println("Synthetic attribute with length > 0"); 82 } 83 } 84 85 86 /** 87 * Called by objects that are traversing the nodes of the tree implicitely 88 * defined by the contents of a Java class. I.e., the hierarchy of methods, 89 * fields, attributes, etc. spawns a tree of objects. 90 * 91 * @param v Visitor object 92 */ 93 @Override accept( final Visitor v )94 public void accept( final Visitor v ) { 95 v.visitSynthetic(this); 96 } 97 98 99 /** 100 * Dump source file attribute to file stream in binary format. 101 * 102 * @param file Output file stream 103 * @throws IOException 104 */ 105 @Override dump( final DataOutputStream file )106 public final void dump( final DataOutputStream file ) throws IOException { 107 super.dump(file); 108 if (super.getLength() > 0) { 109 file.write(bytes, 0, super.getLength()); 110 } 111 } 112 113 114 /** 115 * @return data bytes. 116 */ getBytes()117 public final byte[] getBytes() { 118 return bytes; 119 } 120 121 122 /** 123 * @param bytes 124 */ setBytes( final byte[] bytes )125 public final void setBytes( final byte[] bytes ) { 126 this.bytes = bytes; 127 } 128 129 130 /** 131 * @return String representation. 132 */ 133 @Override toString()134 public final String toString() { 135 final StringBuilder buf = new StringBuilder("Synthetic"); 136 if (super.getLength() > 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 copy( final ConstantPool _constant_pool )147 public Attribute copy( final ConstantPool _constant_pool ) { 148 final 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.setConstantPool(_constant_pool); 154 return c; 155 } 156 } 157