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