0N/A/*
2362N/A * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.nio.cs;
0N/A
0N/Aimport java.lang.ref.SoftReference;
0N/Aimport java.nio.charset.Charset;
0N/Aimport java.nio.charset.spi.CharsetProvider;
0N/Aimport java.util.Iterator;
0N/Aimport java.util.Map;
0N/A
0N/A
0N/A/**
0N/A * Abstract base class for fast charset providers.
0N/A *
0N/A * @author Mark Reinhold
0N/A */
0N/A
0N/Apublic class FastCharsetProvider
0N/A extends CharsetProvider
0N/A{
0N/A
0N/A // Maps canonical names to class names
0N/A private Map<String,String> classMap;
0N/A
0N/A // Maps alias names to canonical names
0N/A private Map<String,String> aliasMap;
0N/A
0N/A // Maps canonical names to cached instances
0N/A private Map<String,Charset> cache;
0N/A
0N/A private String packagePrefix;
0N/A
0N/A protected FastCharsetProvider(String pp,
0N/A Map<String,String> am,
0N/A Map<String,String> cm,
0N/A Map<String,Charset> c)
0N/A {
0N/A packagePrefix = pp;
0N/A aliasMap = am;
0N/A classMap = cm;
0N/A cache = c;
0N/A }
0N/A
0N/A private String canonicalize(String csn) {
0N/A String acn = aliasMap.get(csn);
0N/A return (acn != null) ? acn : csn;
0N/A }
0N/A
0N/A // Private ASCII-only version, optimized for interpretation during startup
0N/A //
0N/A private static String toLower(String s) {
0N/A int n = s.length();
0N/A boolean allLower = true;
0N/A for (int i = 0; i < n; i++) {
0N/A int c = s.charAt(i);
0N/A if (((c - 'A') | ('Z' - c)) >= 0) {
0N/A allLower = false;
0N/A break;
0N/A }
0N/A }
0N/A if (allLower)
0N/A return s;
0N/A char[] ca = new char[n];
0N/A for (int i = 0; i < n; i++) {
0N/A int c = s.charAt(i);
0N/A if (((c - 'A') | ('Z' - c)) >= 0)
0N/A ca[i] = (char)(c + 0x20);
0N/A else
0N/A ca[i] = (char)c;
0N/A }
0N/A return new String(ca);
0N/A }
0N/A
0N/A private Charset lookup(String charsetName) {
0N/A
0N/A String csn = canonicalize(toLower(charsetName));
0N/A
0N/A // Check cache first
0N/A Charset cs = cache.get(csn);
0N/A if (cs != null)
0N/A return cs;
0N/A
0N/A // Do we even support this charset?
0N/A String cln = classMap.get(csn);
0N/A if (cln == null)
0N/A return null;
0N/A
0N/A if (cln.equals("US_ASCII")) {
0N/A cs = new US_ASCII();
0N/A cache.put(csn, cs);
0N/A return cs;
0N/A }
0N/A
0N/A // Instantiate the charset and cache it
0N/A try {
0N/A Class c = Class.forName(packagePrefix + "." + cln,
0N/A true,
0N/A this.getClass().getClassLoader());
0N/A cs = (Charset)c.newInstance();
0N/A cache.put(csn, cs);
0N/A return cs;
0N/A } catch (ClassNotFoundException x) {
0N/A return null;
0N/A } catch (IllegalAccessException x) {
0N/A return null;
0N/A } catch (InstantiationException x) {
0N/A return null;
0N/A }
0N/A }
0N/A
0N/A public final Charset charsetForName(String charsetName) {
0N/A synchronized (this) {
0N/A return lookup(canonicalize(charsetName));
0N/A }
0N/A }
0N/A
0N/A public final Iterator<Charset> charsets() {
0N/A
0N/A return new Iterator<Charset>() {
0N/A
0N/A Iterator<String> i = classMap.keySet().iterator();
0N/A
0N/A public boolean hasNext() {
0N/A return i.hasNext();
0N/A }
0N/A
0N/A public Charset next() {
0N/A String csn = i.next();
0N/A return lookup(csn);
0N/A }
0N/A
0N/A public void remove() {
0N/A throw new UnsupportedOperationException();
0N/A }
0N/A
0N/A };
0N/A
0N/A }
0N/A
0N/A}