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 30 package sun.nio.cs; 31 32 import java.nio.charset.Charset; 33 import java.nio.charset.spi.CharsetProvider; 34 import java.util.Iterator; 35 import java.util.Map; 36 import java.util.Set; 37 import jdk.internal.vm.annotation.Stable; 38 import sun.security.action.GetPropertyAction; 39 40 public 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 map.put("utf-16", UTF_16.INSTANCE); 90 map.put("utf-16be", UTF_16BE.INSTANCE); 91 map.put("utf-16le", UTF_16LE.INSTANCE); 92 cache = map; 93 } 94 return map; 95 } 96 97 // Private ASCII-only version, optimized for interpretation during startup 98 // 99 private static String toLower(String s) { 100 int n = s.length(); 101 boolean allLower = true; 102 for (int i = 0; i < n; i++) { 103 int c = s.charAt(i); 104 if (((c - 'A') | ('Z' - c)) >= 0) { 105 allLower = false; 106 break; 107 } 108 } 109 if (allLower) 110 return s; 111 StringBuilder sb = new StringBuilder(n); 112 for (int i = 0; i < n; i++) { 113 int c = s.charAt(i); 114 if (((c - 'A') | ('Z' - c)) >= 0) 115 sb.append((char)(c + 0x20)); 116 else 117 sb.append((char)c); 118 } 119 return sb.toString(); 120 } 121 122 private Charset lookup(String charsetName) { 123 init(); 124 125 // By checking these built-ins we can avoid initializing Aliases, 126 // Classes and Cache eagerly during bootstrap. 127 // 128 // Initialization of java.nio.charset.StandardCharsets should be 129 // avoided here to minimize time spent in System.initPhase1, as it 130 // may delay initialization of performance critical VM subsystems. 131 String csn; 132 if (charsetName.equals("UTF-8")) { 133 return UTF_8.INSTANCE; 134 } else if (charsetName.equals("US-ASCII")) { 135 return US_ASCII.INSTANCE; 136 } else if (charsetName.equals("ISO-8859-1")) { 137 return ISO_8859_1.INSTANCE; 138 } else { 139 csn = canonicalize(toLower(charsetName)); 140 } 141 142 // Check cache first 143 Charset cs = cache().get(csn); 144 if (cs != null) 145 return cs; 146 147 // Do we even support this charset? 148 String cln = classMap().get(csn); 149 if (cln == null) 150 return null; 151 152 // Instantiate the charset and cache it 153 try { 154 @SuppressWarnings("deprecation") 155 Object o = Class.forName(packagePrefix + cln, 156 true, 157 this.getClass().getClassLoader()).newInstance(); 158 return cache(csn, (Charset)o); 159 } catch (ClassNotFoundException | 160 IllegalAccessException | 161 InstantiationException x) { 162 return null; 163 } 164 } 165 166 private Charset cache(String csn, Charset cs) { 167 cache().put(csn, cs); 168 return cs; 169 } 170 171 public final Charset charsetForName(String charsetName) { 172 synchronized (this) { 173 return lookup(charsetName); 174 } 175 } 176 177 public final Iterator<Charset> charsets() { 178 Set<String> charsetNames; 179 synchronized (this) { 180 init(); 181 // Ensure initialized in synchronized block 182 charsetNames = classMap().keySet(); 183 aliasMap(); 184 cache(); 185 } 186 return new Iterator<Charset>() { 187 188 Iterator<String> i = charsetNames.iterator(); 189 190 public boolean hasNext() { 191 return i.hasNext(); 192 } 193 194 public Charset next() { 195 String csn = i.next(); 196 return lookup(csn); 197 } 198 199 public void remove() { 200 throw new UnsupportedOperationException(); 201 } 202 203 }; 204 } 205 206 private boolean initialized = false; 207 208 /* provider the sun.nio.cs.map property fir sjis/ms932 mapping hack 209 */ 210 private void init() { 211 if (initialized) 212 return; 213 if (!jdk.internal.misc.VM.isBooted()) 214 return; 215 initialized = true; 216 217 String map = GetPropertyAction.privilegedGetProperty("sun.nio.cs.map"); 218 if (map != null) { 219 Map<String,String> aliasMap = aliasMap(); 220 Map<String,String> classMap = classMap(); 221 String[] maps = map.split(","); 222 for (int i = 0; i < maps.length; i++) { 223 if (maps[i].equalsIgnoreCase("Windows-31J/Shift_JIS")) { 224 // if we dont have both sjis and ms932, do nothing 225 if (classMap.get("shift_jis") == null || 226 classMap.get("windows-31j") == null) { 227 break; 228 } 229 aliases_MS932 = new String[] { 230 "MS932", // JDK historical 231 "windows-932", 232 "csWindows31J", 233 "shift-jis", 234 "ms_kanji", 235 "x-sjis", 236 "csShiftJIS", 237 // This alias takes precedence over the actual 238 // Shift_JIS charset itself since aliases are always 239 // resolved first, before looking up canonical names. 240 "shift_jis" 241 }; 242 aliases_SJIS = new String[] { "sjis" }; 243 244 for (String alias : aliases_MS932) { 245 aliasMap.put(toLower(alias), "windows-31j"); 246 } 247 cache().put("shift_jis", null); 248 break; 249 } 250 } 251 } 252 } 253 254 }