< prev index next >
src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template
Print this page
rev 17642 : 8186517: sun.nio.cs.StandardCharsets$Aliases and Classes can be lazily loaded
Reviewed-by: sherman, martin, plevart
*** 31,75 ****
import java.nio.charset.Charset;
import java.nio.charset.spi.CharsetProvider;
import java.util.Iterator;
import java.util.Map;
import sun.security.action.GetPropertyAction;
public class StandardCharsets extends CharsetProvider {
_INCLUDE_ALIASES_TABLES_
_INCLUDE_ALIASES_MAP_
_INCLUDE_CLASSES_MAP_
_INCLUDE_CACHE_MAP_
// Maps canonical names to class names
! private final Map<String,String> classMap;
! // Maps alias names to canonical names
! private final Map<String,String> aliasMap;
! // Maps canonical names to cached instances
! private final Map<String,Charset> cache;
!
! private static final String packagePrefix = "sun.nio.cs";
! public static final String US_ASCII = "US-ASCII";
! public static final String ISO_8859_1 = "ISO-8859-1";
! public static final String UTF_8 = "UTF-8";
public StandardCharsets() {
- this.aliasMap = new Aliases();
- this.classMap = new Classes();
- this.cache = new Cache();
}
private String canonicalize(String csn) {
! String acn = aliasMap.get(csn);
return (acn != null) ? acn : csn;
}
// Private ASCII-only version, optimized for interpretation during startup
//
private static String toLower(String s) {
int n = s.length();
boolean allLower = true;
--- 31,98 ----
import java.nio.charset.Charset;
import java.nio.charset.spi.CharsetProvider;
import java.util.Iterator;
import java.util.Map;
+ import java.util.Set;
+ import jdk.internal.vm.annotation.Stable;
import sun.security.action.GetPropertyAction;
public class StandardCharsets extends CharsetProvider {
_INCLUDE_ALIASES_TABLES_
_INCLUDE_ALIASES_MAP_
_INCLUDE_CLASSES_MAP_
_INCLUDE_CACHE_MAP_
// Maps canonical names to class names
! private @Stable Map<String,String> classMap;
! // Maps alias names to canonical names
! private @Stable Map<String,String> aliasMap;
! // Maps canonical names to cached instances
! private @Stable Map<String,Charset> cache;
! private static final String packagePrefix = "sun.nio.cs.";
public StandardCharsets() {
}
private String canonicalize(String csn) {
! String acn = aliasMap().get(csn);
return (acn != null) ? acn : csn;
}
+ private Map<String,String> aliasMap() {
+ Map<String,String> map = aliasMap;
+ if (map == null) {
+ aliasMap = map = new Aliases();
+ }
+ return map;
+ }
+
+ private Map<String,String> classMap() {
+ Map<String,String> map = classMap;
+ if (map == null) {
+ classMap = map = new Classes();
+ }
+ return map;
+ }
+
+ private Map<String,Charset> cache() {
+ Map<String,Charset> map = cache;
+ if (map == null) {
+ map = new Cache();
+ map.put("utf-8", UTF_8.INSTANCE);
+ map.put("iso-8859-1", ISO_8859_1.INSTANCE);
+ map.put("us-ascii", US_ASCII.INSTANCE);
+ cache = map;
+ }
+ return map;
+ }
+
// Private ASCII-only version, optimized for interpretation during startup
//
private static String toLower(String s) {
int n = s.length();
boolean allLower = true;
*** 80,130 ****
break;
}
}
if (allLower)
return s;
! char[] ca = new char[n];
for (int i = 0; i < n; i++) {
int c = s.charAt(i);
if (((c - 'A') | ('Z' - c)) >= 0)
! ca[i] = (char)(c + 0x20);
else
! ca[i] = (char)c;
}
! return new String(ca);
}
private Charset lookup(String charsetName) {
init();
! String csn = canonicalize(toLower(charsetName));
// Check cache first
! Charset cs = cache.get(csn);
if (cs != null)
return cs;
// Do we even support this charset?
! String cln = classMap.get(csn);
if (cln == null)
return null;
- // As all charset class names added to classMap are string literals we
- // can check identity here as an optimization
- if (cln == US_ASCII) {
- return cache(csn, new US_ASCII());
- }
- if (cln == ISO_8859_1) {
- return cache(csn, new ISO_8859_1());
- }
- if (cln == UTF_8) {
- return cache(csn, new UTF_8());
- }
-
// Instantiate the charset and cache it
try {
@SuppressWarnings("deprecation")
! Object o = Class.forName(packagePrefix + "." + cln,
true,
this.getClass().getClassLoader()).newInstance();
return cache(csn, (Charset)o);
} catch (ClassNotFoundException |
IllegalAccessException |
--- 103,153 ----
break;
}
}
if (allLower)
return s;
! StringBuilder sb = new StringBuilder(n);
for (int i = 0; i < n; i++) {
int c = s.charAt(i);
if (((c - 'A') | ('Z' - c)) >= 0)
! sb.append((char)(c + 0x20));
else
! sb.append((char)c);
}
! return sb.toString();
}
private Charset lookup(String charsetName) {
init();
!
! // By checking these built-ins we can avoid initializing Aliases and
! // Classes eagerly during bootstrap
! String csn;
! if (charsetName.equals("UTF-8")) {
! return UTF_8.INSTANCE;
! } else if (charsetName.equals("US-ASCII")) {
! return US_ASCII.INSTANCE;
! } else if (charsetName.equals("ISO-8859-1")) {
! return ISO_8859_1.INSTANCE;
! } else {
! csn = canonicalize(toLower(charsetName));
! }
// Check cache first
! Charset cs = cache().get(csn);
if (cs != null)
return cs;
// Do we even support this charset?
! String cln = classMap().get(csn);
if (cln == null)
return null;
// Instantiate the charset and cache it
try {
@SuppressWarnings("deprecation")
! Object o = Class.forName(packagePrefix + cln,
true,
this.getClass().getClassLoader()).newInstance();
return cache(csn, (Charset)o);
} catch (ClassNotFoundException |
IllegalAccessException |
*** 132,158 ****
return null;
}
}
private Charset cache(String csn, Charset cs) {
! cache.put(csn, cs);
return cs;
}
public final Charset charsetForName(String charsetName) {
synchronized (this) {
! return lookup(canonicalize(charsetName));
}
}
public final Iterator<Charset> charsets() {
synchronized (this) {
init();
}
return new Iterator<Charset>() {
! Iterator<String> i = classMap.keySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
--- 155,186 ----
return null;
}
}
private Charset cache(String csn, Charset cs) {
! cache().put(csn, cs);
return cs;
}
public final Charset charsetForName(String charsetName) {
synchronized (this) {
! return lookup(charsetName);
}
}
public final Iterator<Charset> charsets() {
+ Set<String> charsetNames;
synchronized (this) {
init();
+ // Ensure initialized in synchronized block
+ charsetNames = classMap().keySet();
+ aliasMap();
+ cache();
}
return new Iterator<Charset>() {
! Iterator<String> i = charsetNames.iterator();
public boolean hasNext() {
return i.hasNext();
}
*** 179,188 ****
--- 207,218 ----
return;
initialized = true;
String map = GetPropertyAction.privilegedGetProperty("sun.nio.cs.map");
if (map != null) {
+ Map<String,String> aliasMap = aliasMap();
+ Map<String,String> classMap = classMap();
String[] maps = map.split(",");
for (int i = 0; i < maps.length; i++) {
if (maps[i].equalsIgnoreCase("Windows-31J/Shift_JIS")) {
// if we dont have both sjis and ms932, do nothing
if (classMap.get("shift_jis") == null ||
*** 205,215 ****
aliases_SJIS = new String[] { "sjis" };
for (String alias : aliases_MS932) {
aliasMap.put(toLower(alias), "windows-31j");
}
! cache.put("shift_jis", null);
break;
}
}
}
}
--- 235,245 ----
aliases_SJIS = new String[] { "sjis" };
for (String alias : aliases_MS932) {
aliasMap.put(toLower(alias), "windows-31j");
}
! cache().put("shift_jis", null);
break;
}
}
}
}
< prev index next >