1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.bcel.internal.classfile; 23 24 25 import com.sun.org.apache.bcel.internal.Constants; 26 import java.io.*; 27 import java.util.*; 28 29 /** 30 * This class represents a reference to an unknown (i.e., 31 * application-specific) attribute of a class. It is instantiated from the 32 * <em>Attribute.readAttribute()</em> method. Applications that need to 33 * read in application-specific attributes should create an <a 34 * href="./AttributeReader.html">AttributeReader</a> implementation and 35 * attach it via <a 36 * href="./Attribute.html#addAttributeReader(java.lang.String, 37 * com.sun.org.apache.bcel.internal.classfile.AttributeReader)">Attribute.addAttributeReader</a>. 38 39 * 40 * @see com.sun.org.apache.bcel.internal.classfile.Attribute 41 * @see com.sun.org.apache.bcel.internal.classfile.AttributeReader 42 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 43 */ 44 public final class Unknown extends Attribute { 45 private byte[] bytes; 46 private String name; 47 48 private static HashMap unknown_attributes = new HashMap(); 49 50 /** @return array of unknown attributes, but just one for each kind. 51 */ 52 static Unknown[] getUnknownAttributes() { 53 Unknown[] unknowns = new Unknown[unknown_attributes.size()]; 54 Iterator entries = unknown_attributes.values().iterator(); 55 56 for(int i=0; entries.hasNext(); i++) 57 unknowns[i] = (Unknown)entries.next(); 58 59 unknown_attributes.clear(); 60 return unknowns; 61 } 62 63 /** 64 * Initialize from another object. Note that both objects use the same 65 * references (shallow copy). Use clone() for a physical copy. 66 */ 67 public Unknown(Unknown c) { 68 this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); 69 } 70 71 /** 72 * Create a non-standard attribute. 73 * 74 * @param name_index Index in constant pool 75 * @param length Content length in bytes 76 * @param bytes Attribute contents 77 * @param constant_pool Array of constants 78 */ 79 public Unknown(int name_index, int length, byte[] bytes, 80 ConstantPool constant_pool) 81 { 82 super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool); 83 this.bytes = bytes; 84 85 name = ((ConstantUtf8)constant_pool.getConstant(name_index, 86 Constants.CONSTANT_Utf8)).getBytes(); 87 unknown_attributes.put(name, this); 88 } 89 90 /** 91 * Construct object from file stream. 92 * @param name_index Index in constant pool 93 * @param length Content length in bytes 94 * @param file Input stream 95 * @param constant_pool Array of constants 96 * @throws IOException 97 */ 98 Unknown(int name_index, int length, DataInputStream file, 99 ConstantPool constant_pool) 100 throws IOException 101 { 102 this(name_index, length, (byte [])null, constant_pool); 103 104 if(length > 0) { 105 bytes = new byte[length]; 106 file.readFully(bytes); 107 } 108 } 109 110 /** 111 * Called by objects that are traversing the nodes of the tree implicitely 112 * defined by the contents of a Java class. I.e., the hierarchy of methods, 113 * fields, attributes, etc. spawns a tree of objects. 114 * 115 * @param v Visitor object 116 */ 117 public void accept(Visitor v) { 118 v.visitUnknown(this); 119 } 120 /** 121 * Dump unknown bytes to file stream. 122 * 123 * @param file Output file stream 124 * @throws IOException 125 */ 126 public final void dump(DataOutputStream file) throws IOException 127 { 128 super.dump(file); 129 if(length > 0) 130 file.write(bytes, 0, length); 131 } 132 /** 133 * @return data bytes. 134 */ 135 public final byte[] getBytes() { return bytes; } 136 137 /** 138 * @return name of attribute. 139 */ 140 public final String getName() { return name; } 141 142 /** 143 * @param bytes. 144 */ 145 public final void setBytes(byte[] bytes) { 146 this.bytes = bytes; 147 } 148 149 /** 150 * @return String representation. 151 */ 152 public final String toString() { 153 if(length == 0 || bytes == null) 154 return "(Unknown attribute " + name + ")"; 155 156 String hex; 157 if(length > 10) { 158 byte[] tmp = new byte[10]; 159 System.arraycopy(bytes, 0, tmp, 0, 10); 160 hex = Utility.toHexString(tmp) + "... (truncated)"; 161 } 162 else 163 hex = Utility.toHexString(bytes); 164 165 return "(Unknown attribute " + name + ": " + hex + ")"; 166 } 167 168 /** 169 * @return deep copy of this attribute 170 */ 171 public Attribute copy(ConstantPool constant_pool) { 172 Unknown c = (Unknown)clone(); 173 174 if(bytes != null) 175 c.bytes = (byte[])bytes.clone(); 176 177 c.constant_pool = constant_pool; 178 return c; 179 } 180 }