1 /* 2 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 package sun.nio.cs; 28 29 import java.nio.*; 30 import java.nio.charset.*; 31 32 33 /** 34 * Utility class for caching per-thread decoders and encoders. 35 */ 36 37 public class ThreadLocalCoders { 38 39 private static final int CACHE_SIZE = 3; 40 41 private static abstract class Cache { 42 43 // Thread-local reference to array of cached objects, in LRU order 44 private ThreadLocal cache = new ThreadLocal(); 45 private final int size; 46 Cache(int size)47 Cache(int size) { 48 this.size = size; 49 } 50 create(Object name)51 abstract Object create(Object name); 52 moveToFront(Object[] oa, int i)53 private void moveToFront(Object[] oa, int i) { 54 Object ob = oa[i]; 55 for (int j = i; j > 0; j--) 56 oa[j] = oa[j - 1]; 57 oa[0] = ob; 58 } 59 hasName(Object ob, Object name)60 abstract boolean hasName(Object ob, Object name); 61 forName(Object name)62 Object forName(Object name) { 63 Object[] oa = (Object[])cache.get(); 64 if (oa == null) { 65 oa = new Object[size]; 66 cache.set(oa); 67 } else { 68 for (int i = 0; i < oa.length; i++) { 69 Object ob = oa[i]; 70 if (ob == null) 71 continue; 72 if (hasName(ob, name)) { 73 if (i > 0) 74 moveToFront(oa, i); 75 return ob; 76 } 77 } 78 } 79 80 // Create a new object 81 Object ob = create(name); 82 oa[oa.length - 1] = ob; 83 moveToFront(oa, oa.length - 1); 84 return ob; 85 } 86 87 } 88 89 private static Cache decoderCache = new Cache(CACHE_SIZE) { 90 boolean hasName(Object ob, Object name) { 91 if (name instanceof String) 92 return (((CharsetDecoder)ob).charset().name().equals(name)); 93 if (name instanceof Charset) 94 return ((CharsetDecoder)ob).charset().equals(name); 95 return false; 96 } 97 Object create(Object name) { 98 if (name instanceof String) 99 return Charset.forName((String)name).newDecoder(); 100 if (name instanceof Charset) 101 return ((Charset)name).newDecoder(); 102 assert false; 103 return null; 104 } 105 }; 106 decoderFor(Object name)107 public static CharsetDecoder decoderFor(Object name) { 108 CharsetDecoder cd = (CharsetDecoder)decoderCache.forName(name); 109 cd.reset(); 110 return cd; 111 } 112 113 private static Cache encoderCache = new Cache(CACHE_SIZE) { 114 boolean hasName(Object ob, Object name) { 115 if (name instanceof String) 116 return (((CharsetEncoder)ob).charset().name().equals(name)); 117 if (name instanceof Charset) 118 return ((CharsetEncoder)ob).charset().equals(name); 119 return false; 120 } 121 Object create(Object name) { 122 if (name instanceof String) 123 return Charset.forName((String)name).newEncoder(); 124 if (name instanceof Charset) 125 return ((Charset)name).newEncoder(); 126 assert false; 127 return null; 128 } 129 }; 130 encoderFor(Object name)131 public static CharsetEncoder encoderFor(Object name) { 132 CharsetEncoder ce = (CharsetEncoder)encoderCache.forName(name); 133 ce.reset(); 134 return ce; 135 } 136 137 } 138