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 } | 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 import java.io.DataInput; 25 import java.io.DataOutputStream; 26 import java.io.IOException; 27 import java.util.HashMap; 28 import java.util.Map; 29 30 import com.sun.org.apache.bcel.internal.Const; 31 32 /** 33 * This class represents a reference to an unknown (i.e., 34 * application-specific) attribute of a class. It is instantiated from the 35 * {@link Attribute#readAttribute(java.io.DataInput, ConstantPool)} method. 36 * Applications that need to read in application-specific attributes should create an 37 * {@link UnknownAttributeReader} implementation and attach it via 38 * {@link Attribute#addAttributeReader(String, UnknownAttributeReader)}. 39 40 * 41 * @version $Id: Unknown.java 1749603 2016-06-21 20:50:19Z ggregory $ 42 * @see Attribute 43 * @see UnknownAttributeReader 44 */ 45 public final class Unknown extends Attribute { 46 47 private byte[] bytes; 48 private final String name; 49 private static final Map<String, Unknown> unknown_attributes = new HashMap<>(); 50 51 52 /** @return array of unknown attributes, but just one for each kind. 53 */ 54 static Unknown[] getUnknownAttributes() { 55 final Unknown[] unknowns = new Unknown[unknown_attributes.size()]; 56 unknown_attributes.values().toArray(unknowns); 57 unknown_attributes.clear(); 58 return unknowns; 59 } 60 61 62 /** 63 * Initialize from another object. Note that both objects use the same 64 * references (shallow copy). Use clone() for a physical copy. 65 */ 66 public Unknown(final Unknown c) { 67 this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); 68 } 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(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool) { 80 super(Const.ATTR_UNKNOWN, name_index, length, constant_pool); 81 this.bytes = bytes; 82 name = ((ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8)) 83 .getBytes(); 84 unknown_attributes.put(name, this); 85 } 86 87 88 /** 89 * Construct object from input stream. 90 * 91 * @param name_index Index in constant pool 92 * @param length Content length in bytes 93 * @param input Input stream 94 * @param constant_pool Array of constants 95 * @throws IOException 96 */ 97 Unknown(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) 98 throws IOException { 99 this(name_index, length, (byte[]) null, constant_pool); 100 if (length > 0) { 101 bytes = new byte[length]; 102 input.readFully(bytes); 103 } 104 } 105 106 107 /** 108 * Called by objects that are traversing the nodes of the tree implicitely 109 * defined by the contents of a Java class. I.e., the hierarchy of methods, 110 * fields, attributes, etc. spawns a tree of objects. 111 * 112 * @param v Visitor object 113 */ 114 @Override 115 public void accept( final Visitor v ) { 116 v.visitUnknown(this); 117 } 118 119 120 /** 121 * Dump unknown bytes to file stream. 122 * 123 * @param file Output file stream 124 * @throws IOException 125 */ 126 @Override 127 public final void dump( final DataOutputStream file ) throws IOException { 128 super.dump(file); 129 if (super.getLength() > 0) { 130 file.write(bytes, 0, super.getLength()); 131 } 132 } 133 134 135 /** 136 * @return data bytes. 137 */ 138 public final byte[] getBytes() { 139 return bytes; 140 } 141 142 143 /** 144 * @return name of attribute. 145 */ 146 @Override 147 public final String getName() { 148 return name; 149 } 150 151 152 /** 153 * @param bytes the bytes to set 154 */ 155 public final void setBytes( final byte[] bytes ) { 156 this.bytes = bytes; 157 } 158 159 160 /** 161 * @return String representation. 162 */ 163 @Override 164 public final String toString() { 165 if (super.getLength() == 0 || bytes == null) { 166 return "(Unknown attribute " + name + ")"; 167 } 168 String hex; 169 if (super.getLength() > 10) { 170 final byte[] tmp = new byte[10]; 171 System.arraycopy(bytes, 0, tmp, 0, 10); 172 hex = Utility.toHexString(tmp) + "... (truncated)"; 173 } else { 174 hex = Utility.toHexString(bytes); 175 } 176 return "(Unknown attribute " + name + ": " + hex + ")"; 177 } 178 179 180 /** 181 * @return deep copy of this attribute 182 */ 183 @Override 184 public Attribute copy( final ConstantPool _constant_pool ) { 185 final Unknown c = (Unknown) clone(); 186 if (bytes != null) { 187 c.bytes = new byte[bytes.length]; 188 System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); 189 } 190 c.setConstantPool(_constant_pool); 191 return c; 192 } 193 } |