1/*
2 * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
3 *
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.  Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 *
26 */
27
28// -- This file was mechanically generated: Do not edit! -- //
29
30package sun.nio.cs;
31
32import java.nio.charset.Charset;
33import java.nio.charset.spi.CharsetProvider;
34import java.util.Iterator;
35import java.util.Map;
36import java.util.Set;
37import jdk.internal.vm.annotation.Stable;
38import sun.security.action.GetPropertyAction;
39
40public class StandardCharsets extends CharsetProvider {
41
42    _INCLUDE_ALIASES_TABLES_
43    _INCLUDE_ALIASES_MAP_
44    _INCLUDE_CLASSES_MAP_
45    _INCLUDE_CACHE_MAP_
46
47    // Maps canonical names to class names
48    private @Stable Map<String,String> classMap;
49
50    // Maps alias names to canonical names
51    private @Stable Map<String,String> aliasMap;
52
53    // Maps canonical names to cached instances
54    private @Stable Map<String,Charset> cache;
55
56    private static final String packagePrefix = "sun.nio.cs.";
57
58    public StandardCharsets() {
59    }
60
61    private String canonicalize(String csn) {
62        String acn = aliasMap().get(csn);
63        return (acn != null) ? acn : csn;
64    }
65
66    private Map<String,String> aliasMap() {
67        Map<String,String> map = aliasMap;
68        if (map == null) {
69            aliasMap = map = new Aliases();
70        }
71        return map;
72    }
73
74    private Map<String,String> classMap() {
75        Map<String,String> map = classMap;
76        if (map == null) {
77            classMap = map = new Classes();
78        }
79        return map;
80    }
81
82    private Map<String,Charset> cache() {
83        Map<String,Charset> map = cache;
84        if (map == null) {
85            map = new Cache();
86            map.put("utf-8", UTF_8.INSTANCE);
87            map.put("iso-8859-1", ISO_8859_1.INSTANCE);
88            map.put("us-ascii", US_ASCII.INSTANCE);
89            cache = map;
90        }
91        return map;
92    }
93
94    // Private ASCII-only version, optimized for interpretation during startup
95    //
96    private static String toLower(String s) {
97        int n = s.length();
98        boolean allLower = true;
99        for (int i = 0; i < n; i++) {
100            int c = s.charAt(i);
101            if (((c - 'A') | ('Z' - c)) >= 0) {
102                allLower = false;
103                break;
104            }
105        }
106        if (allLower)
107            return s;
108        StringBuilder sb = new StringBuilder(n);
109        for (int i = 0; i < n; i++) {
110            int c = s.charAt(i);
111            if (((c - 'A') | ('Z' - c)) >= 0)
112                sb.append((char)(c + 0x20));
113            else
114                sb.append((char)c);
115        }
116        return sb.toString();
117    }
118
119    private Charset lookup(String charsetName) {
120        init();
121
122        // By checking these built-ins we can avoid initializing Aliases and
123        // Classes eagerly during bootstrap
124        String csn;
125        if (charsetName.equals("UTF-8")) {
126            return UTF_8.INSTANCE;
127        } else if (charsetName.equals("US-ASCII")) {
128            return US_ASCII.INSTANCE;
129        } else if (charsetName.equals("ISO-8859-1")) {
130            return ISO_8859_1.INSTANCE;
131        } else {
132            csn = canonicalize(toLower(charsetName));
133        }
134
135        // Check cache first
136        Charset cs = cache().get(csn);
137        if (cs != null)
138            return cs;
139
140        // Do we even support this charset?
141        String cln = classMap().get(csn);
142        if (cln == null)
143            return null;
144
145        // Instantiate the charset and cache it
146        try {
147            @SuppressWarnings("deprecation")
148            Object o = Class.forName(packagePrefix + cln,
149                                     true,
150                                     this.getClass().getClassLoader()).newInstance();
151            return cache(csn, (Charset)o);
152        } catch (ClassNotFoundException |
153                 IllegalAccessException |
154                 InstantiationException x) {
155            return null;
156        }
157    }
158
159    private Charset cache(String csn, Charset cs) {
160        cache().put(csn, cs);
161        return cs;
162    }
163
164    public final Charset charsetForName(String charsetName) {
165        synchronized (this) {
166            return lookup(charsetName);
167        }
168    }
169
170    public final Iterator<Charset> charsets() {
171        Set<String> charsetNames;
172        synchronized (this) {
173            init();
174            // Ensure initialized in synchronized block
175            charsetNames = classMap().keySet();
176            aliasMap();
177            cache();
178        }
179        return new Iterator<Charset>() {
180
181                Iterator<String> i = charsetNames.iterator();
182
183                public boolean hasNext() {
184                    return i.hasNext();
185                }
186
187                public Charset next() {
188                    String csn = i.next();
189                    return lookup(csn);
190                }
191
192                public void remove() {
193                    throw new UnsupportedOperationException();
194                }
195
196            };
197    }
198
199    private boolean initialized = false;
200
201    /*   provider the sun.nio.cs.map property fir sjis/ms932 mapping hack
202     */
203    private void init() {
204        if (initialized)
205            return;
206        if (!jdk.internal.misc.VM.isBooted())
207            return;
208        initialized = true;
209
210        String map = GetPropertyAction.privilegedGetProperty("sun.nio.cs.map");
211        if (map != null) {
212            Map<String,String> aliasMap = aliasMap();
213            Map<String,String> classMap = classMap();
214            String[] maps = map.split(",");
215            for (int i = 0; i < maps.length; i++) {
216                if (maps[i].equalsIgnoreCase("Windows-31J/Shift_JIS")) {
217                    // if we dont have both sjis and ms932, do nothing
218                    if (classMap.get("shift_jis") == null ||
219                        classMap.get("windows-31j") == null) {
220                        break;
221                    }
222                    aliases_MS932 = new String[] {
223                        "MS932",        // JDK historical
224                        "windows-932",
225                        "csWindows31J",
226                        "shift-jis",
227                        "ms_kanji",
228                        "x-sjis",
229                        "csShiftJIS",
230                        // This alias takes precedence over the actual
231                        // Shift_JIS charset itself since aliases are always
232                        // resolved first, before looking up canonical names.
233                        "shift_jis"
234                    };
235                    aliases_SJIS = new String[] { "sjis" };
236
237                    for (String alias : aliases_MS932) {
238                        aliasMap.put(toLower(alias), "windows-31j");
239                    }
240                    cache().put("shift_jis", null);
241                    break;
242                }
243            }
244        }
245    }
246
247}
248