1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 2004-2014, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 * 10 * Created on Feb 4, 2004 11 * 12 */ 13 package android.icu.impl; 14 15 import java.io.IOException; 16 import java.io.InputStream; 17 import java.net.URL; 18 import java.security.AccessController; 19 import java.security.PrivilegedAction; 20 import java.util.MissingResourceException; 21 import java.util.logging.Logger; 22 23 import android.icu.util.VersionInfo; 24 25 /** 26 * Provides access to ICU data files as InputStreams. Implements security checking. 27 * @hide Only a subset of ICU is exposed in Android 28 */ 29 @libcore.api.IntraCoreApi 30 public final class ICUData { 31 /** 32 * The data path to be used with getBundleInstance API 33 */ 34 static final String ICU_DATA_PATH = "android/icu/impl/"; 35 /** 36 * The ICU data package name. 37 * This is normally the name of the .dat package, and the prefix (plus '/') 38 * of the package entry names. 39 */ 40 static final String PACKAGE_NAME = "icudt" + VersionInfo.ICU_DATA_VERSION_PATH; 41 /** 42 * The data path to be used with Class.getResourceAsStream(). 43 */ 44 public static final String ICU_BUNDLE = "data/" + PACKAGE_NAME; 45 46 /** 47 * The base name of ICU data to be used with ClassLoader.getResourceAsStream(), 48 * ICUResourceBundle.getBundleInstance() etc. 49 */ 50 @libcore.api.IntraCoreApi 51 public static final String ICU_BASE_NAME = ICU_DATA_PATH + ICU_BUNDLE; 52 53 /** 54 * The base name of collation data to be used with getBundleInstance API 55 */ 56 public static final String ICU_COLLATION_BASE_NAME = ICU_BASE_NAME + "/coll"; 57 58 /** 59 * The base name of rbbi data to be used with getData API 60 */ 61 public static final String ICU_BRKITR_NAME = "brkitr"; 62 63 /** 64 * The base name of rbbi data to be used with getBundleInstance API 65 */ 66 public static final String ICU_BRKITR_BASE_NAME = ICU_BASE_NAME + '/' + ICU_BRKITR_NAME; 67 68 /** 69 * The base name of rbnf data to be used with getBundleInstance API 70 */ 71 public static final String ICU_RBNF_BASE_NAME = ICU_BASE_NAME + "/rbnf"; 72 73 /** 74 * The base name of transliterator data to be used with getBundleInstance API 75 */ 76 public static final String ICU_TRANSLIT_BASE_NAME = ICU_BASE_NAME + "/translit"; 77 78 public static final String ICU_LANG_BASE_NAME = ICU_BASE_NAME + "/lang"; 79 public static final String ICU_CURR_BASE_NAME = ICU_BASE_NAME + "/curr"; 80 public static final String ICU_REGION_BASE_NAME = ICU_BASE_NAME + "/region"; 81 public static final String ICU_ZONE_BASE_NAME = ICU_BASE_NAME + "/zone"; 82 public static final String ICU_UNIT_BASE_NAME = ICU_BASE_NAME + "/unit"; 83 84 /** 85 * For testing (otherwise false): When reading an InputStream from a Class or ClassLoader 86 * (that is, not from a file), log when the stream contains ICU binary data. 87 * 88 * This cannot be ICUConfig'ured because ICUConfig calls ICUData.getStream() 89 * to read the properties file, so we would get a circular dependency 90 * in the class initialization. 91 */ 92 private static final boolean logBinaryDataFromInputStream = false; 93 private static final Logger logger = logBinaryDataFromInputStream ? 94 Logger.getLogger(ICUData.class.getName()) : null; 95 exists(final String resourceName)96 public static boolean exists(final String resourceName) { 97 URL i = null; 98 if (System.getSecurityManager() != null) { 99 i = AccessController.doPrivileged(new PrivilegedAction<URL>() { 100 @Override 101 public URL run() { 102 return ICUData.class.getResource(resourceName); 103 } 104 }); 105 } else { 106 i = ICUData.class.getResource(resourceName); 107 } 108 return i != null; 109 } 110 getStream(final Class<?> root, final String resourceName, boolean required)111 private static InputStream getStream(final Class<?> root, final String resourceName, boolean required) { 112 InputStream i = null; 113 if (System.getSecurityManager() != null) { 114 i = AccessController.doPrivileged(new PrivilegedAction<InputStream>() { 115 @Override 116 public InputStream run() { 117 return root.getResourceAsStream(resourceName); 118 } 119 }); 120 } else { 121 i = root.getResourceAsStream(resourceName); 122 } 123 124 if (i == null && required) { 125 throw new MissingResourceException("could not locate data " +resourceName, root.getPackage().getName(), resourceName); 126 } 127 checkStreamForBinaryData(i, resourceName); 128 return i; 129 } 130 131 /** 132 * Should be called only from ICUBinary.getData() or from convenience overloads here. 133 */ getStream(final ClassLoader loader, final String resourceName, boolean required)134 static InputStream getStream(final ClassLoader loader, final String resourceName, boolean required) { 135 InputStream i = null; 136 if (System.getSecurityManager() != null) { 137 i = AccessController.doPrivileged(new PrivilegedAction<InputStream>() { 138 @Override 139 public InputStream run() { 140 return loader.getResourceAsStream(resourceName); 141 } 142 }); 143 } else { 144 i = loader.getResourceAsStream(resourceName); 145 } 146 if (i == null && required) { 147 throw new MissingResourceException("could not locate data", loader.toString(), resourceName); 148 } 149 checkStreamForBinaryData(i, resourceName); 150 return i; 151 } 152 153 @SuppressWarnings("unused") // used if logBinaryDataFromInputStream == true checkStreamForBinaryData(InputStream is, String resourceName)154 private static void checkStreamForBinaryData(InputStream is, String resourceName) { 155 if (logBinaryDataFromInputStream && is != null && resourceName.indexOf(PACKAGE_NAME) >= 0) { 156 try { 157 is.mark(32); 158 byte[] b = new byte[32]; 159 int len = is.read(b); 160 if (len == 32 && b[2] == (byte)0xda && b[3] == 0x27) { 161 String msg = String.format( 162 "ICU binary data file loaded from Class/ClassLoader as InputStream " + 163 "from %s: MappedData %02x%02x%02x%02x dataFormat %02x%02x%02x%02x", 164 resourceName, 165 b[0], b[1], b[2], b[3], 166 b[12], b[13], b[14], b[15]); 167 logger.info(msg); 168 } 169 is.reset(); 170 } catch (IOException ignored) { 171 } 172 } 173 } 174 getStream(ClassLoader loader, String resourceName)175 public static InputStream getStream(ClassLoader loader, String resourceName){ 176 return getStream(loader,resourceName, false); 177 } 178 getRequiredStream(ClassLoader loader, String resourceName)179 public static InputStream getRequiredStream(ClassLoader loader, String resourceName){ 180 return getStream(loader, resourceName, true); 181 } 182 183 /** 184 * Convenience override that calls getStream(ICUData.class, resourceName, false); 185 * Returns null if the resource could not be found. 186 */ getStream(String resourceName)187 public static InputStream getStream(String resourceName) { 188 return getStream(ICUData.class, resourceName, false); 189 } 190 191 /** 192 * Convenience method that calls getStream(ICUData.class, resourceName, true). 193 * @throws MissingResourceException if the resource could not be found 194 */ getRequiredStream(String resourceName)195 public static InputStream getRequiredStream(String resourceName) { 196 return getStream(ICUData.class, resourceName, true); 197 } 198 199 /** 200 * Convenience override that calls getStream(root, resourceName, false); 201 * Returns null if the resource could not be found. 202 */ getStream(Class<?> root, String resourceName)203 public static InputStream getStream(Class<?> root, String resourceName) { 204 return getStream(root, resourceName, false); 205 } 206 207 /** 208 * Convenience method that calls getStream(root, resourceName, true). 209 * @throws MissingResourceException if the resource could not be found 210 */ getRequiredStream(Class<?> root, String resourceName)211 public static InputStream getRequiredStream(Class<?> root, String resourceName) { 212 return getStream(root, resourceName, true); 213 } 214 } 215