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 28 /** 29 * This class is derived from the abstract 30 * <A HREF="com.sun.org.apache.bcel.internal.classfile.Constant.html">Constant</A> class 31 * and represents a reference to a Utf8 encoded string. 32 * 33 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 34 * @see Constant 35 */ 36 public final class ConstantUtf8 extends Constant { 37 private String bytes; 38 39 /** 40 * Initialize from another object. 41 */ 42 public ConstantUtf8(ConstantUtf8 c) { 43 this(c.getBytes()); 44 } 45 46 /** 47 * Initialize instance from file data. 48 * 49 * @param file Input stream 50 * @throws IOException 51 */ 52 ConstantUtf8(DataInputStream file) throws IOException 53 { 54 super(Constants.CONSTANT_Utf8); 55 56 bytes = file.readUTF(); 57 } 58 59 /** 60 * @param bytes Data 61 */ 62 public ConstantUtf8(String bytes) 63 { 64 super(Constants.CONSTANT_Utf8); 65 66 if(bytes == null) 67 throw new IllegalArgumentException("bytes must not be null!"); 68 69 this.bytes = bytes; 70 } 71 72 /** 73 * Called by objects that are traversing the nodes of the tree implicitely 74 * defined by the contents of a Java class. I.e., the hierarchy of methods, 75 * fields, attributes, etc. spawns a tree of objects. 76 * 77 * @param v Visitor object 78 */ 79 public void accept(Visitor v) { 80 v.visitConstantUtf8(this); 81 } 82 83 /** 84 * Dump String in Utf8 format to file stream. 85 * 86 * @param file Output file stream 87 * @throws IOException 88 */ 89 public final void dump(DataOutputStream file) throws IOException 90 { 91 file.writeByte(tag); 92 file.writeUTF(bytes); 93 } 94 95 /** 96 * @return Data converted to string. 97 */ 98 public final String getBytes() { return bytes; } 99 100 /** 101 * @param bytes. 102 */ 103 public final void setBytes(String bytes) { 104 this.bytes = bytes; 105 } 106 107 /** 108 * @return String representation 109 */ 110 public final String toString() 111 { 112 return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + "\")"; 113 } 114 } | 1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.bcel.internal.classfile; 22 23 import com.sun.org.apache.bcel.internal.Const; 24 import java.io.DataInput; 25 import java.io.DataOutputStream; 26 import java.io.IOException; 27 import java.util.HashMap; 28 import java.util.LinkedHashMap; 29 import java.util.Map; 30 31 /** 32 * This class is derived from the abstract {@link Constant} 33 * and represents a reference to a Utf8 encoded string. 34 * 35 * @version $Id: ConstantUtf8.java 1750029 2016-06-23 22:14:38Z sebb $ 36 * @see Constant 37 */ 38 public final class ConstantUtf8 extends Constant { 39 40 private final String bytes; 41 42 // TODO these should perhaps be AtomicInt? 43 private static volatile int considered = 0; 44 private static volatile int hits = 0; 45 private static volatile int skipped = 0; 46 private static volatile int created = 0; 47 48 // Set the size to 0 or below to skip caching entirely 49 private static final int MAX_CACHED_SIZE = 200; 50 private static final boolean BCEL_STATISTICS = false; 51 52 53 private static class CACHE_HOLDER { 54 55 private static final int MAX_CACHE_ENTRIES = 20000; 56 private static final int INITIAL_CACHE_CAPACITY = (int)(MAX_CACHE_ENTRIES/0.75); 57 58 private static final HashMap<String, ConstantUtf8> CACHE = 59 new LinkedHashMap<String, ConstantUtf8>(INITIAL_CACHE_CAPACITY, 0.75f, true) { 60 private static final long serialVersionUID = -8506975356158971766L; 61 62 @Override 63 protected boolean removeEldestEntry(final Map.Entry<String, ConstantUtf8> eldest) { 64 return size() > MAX_CACHE_ENTRIES; 65 } 66 }; 67 68 } 69 70 // for accesss by test code 71 static void printStats() { 72 System.err.println("Cache hit " + hits + "/" + considered +", " + skipped + " skipped"); 73 System.err.println("Total of " + created + " ConstantUtf8 objects created"); 74 } 75 76 // for accesss by test code 77 static void clearStats() { 78 hits = considered = skipped = created = 0; 79 } 80 81 static { 82 if (BCEL_STATISTICS) { 83 Runtime.getRuntime().addShutdownHook(new Thread() { 84 @Override 85 public void run() { 86 printStats(); 87 } 88 }); 89 } 90 } 91 92 /** 93 * @since 6.0 94 */ 95 public static ConstantUtf8 getCachedInstance(final String s) { 96 if (s.length() > MAX_CACHED_SIZE) { 97 skipped++; 98 return new ConstantUtf8(s); 99 } 100 considered++; 101 synchronized (ConstantUtf8.class) { // might be better with a specific lock object 102 ConstantUtf8 result = CACHE_HOLDER.CACHE.get(s); 103 if (result != null) { 104 hits++; 105 return result; 106 } 107 result = new ConstantUtf8(s); 108 CACHE_HOLDER.CACHE.put(s, result); 109 return result; 110 } 111 } 112 113 /** 114 * @since 6.0 115 */ 116 public static ConstantUtf8 getInstance(final String s) { 117 return new ConstantUtf8(s); 118 } 119 120 /** 121 * @since 6.0 122 */ 123 public static ConstantUtf8 getInstance (final DataInput input) throws IOException { 124 return getInstance(input.readUTF()); 125 } 126 127 /** 128 * Initialize from another object. 129 */ 130 public ConstantUtf8(final ConstantUtf8 c) { 131 this(c.getBytes()); 132 } 133 134 135 /** 136 * Initialize instance from file data. 137 * 138 * @param file Input stream 139 * @throws IOException 140 */ 141 ConstantUtf8(final DataInput file) throws IOException { 142 super(Const.CONSTANT_Utf8); 143 bytes = file.readUTF(); 144 created++; 145 } 146 147 148 /** 149 * @param bytes Data 150 */ 151 public ConstantUtf8(final String bytes) { 152 super(Const.CONSTANT_Utf8); 153 if (bytes == null) { 154 throw new IllegalArgumentException("bytes must not be null!"); 155 } 156 this.bytes = bytes; 157 created++; 158 } 159 160 161 /** 162 * Called by objects that are traversing the nodes of the tree implicitely 163 * defined by the contents of a Java class. I.e., the hierarchy of methods, 164 * fields, attributes, etc. spawns a tree of objects. 165 * 166 * @param v Visitor object 167 */ 168 @Override 169 public void accept( final Visitor v ) { 170 v.visitConstantUtf8(this); 171 } 172 173 174 /** 175 * Dump String in Utf8 format to file stream. 176 * 177 * @param file Output file stream 178 * @throws IOException 179 */ 180 @Override 181 public final void dump( final DataOutputStream file ) throws IOException { 182 file.writeByte(super.getTag()); 183 file.writeUTF(bytes); 184 } 185 186 187 /** 188 * @return Data converted to string. 189 */ 190 public final String getBytes() { 191 return bytes; 192 } 193 194 195 /** 196 * @param bytes the raw bytes of this Utf-8 197 * @deprecated (since 6.0) 198 */ 199 @java.lang.Deprecated 200 public final void setBytes( final String bytes ) { 201 throw new UnsupportedOperationException(); 202 } 203 204 205 /** 206 * @return String representation 207 */ 208 @Override 209 public final String toString() { 210 return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + "\")"; 211 } 212 } |