1/* GENERATED SOURCE. DO NOT MODIFY. */ 2/* 3 ******************************************************************************* 4 * Copyright (C) 2015, International Business Machines Corporation and 5 * others. All Rights Reserved. 6 ******************************************************************************* 7 */ 8package android.icu.impl; 9 10import java.nio.ByteBuffer; 11 12import android.icu.util.UResourceBundle; 13import android.icu.util.UResourceTypeMismatchException; 14 15// Class UResource is named consistently with the public class UResourceBundle, 16// in case we want to make it public at some point. 17 18/** 19 * ICU resource bundle key and value types. 20 * @hide Only a subset of ICU is exposed in Android 21 */ 22public final class UResource { 23 /** 24 * Represents a resource bundle item's key string. 25 * Avoids object creations as much as possible. 26 * Mutable, not thread-safe. 27 * For permanent storage, use clone() or toString(). 28 */ 29 public static final class Key implements CharSequence, Cloneable, Comparable<Key> { 30 // Stores a reference to the resource bundle key string bytes array, 31 // with an offset of the key, to avoid creating a String object 32 // until one is really needed. 33 // Alternatively, we could try to always just get the key String object, 34 // and cache it in the reader, and see if that performs better or worse. 35 private byte[] bytes; 36 private int offset; 37 private int length; 38 private String s; 39 40 /** 41 * Constructs an empty resource key string object. 42 */ 43 public Key() {} 44 45 private Key(byte[] keyBytes, int keyOffset, int keyLength) { 46 bytes = keyBytes; 47 offset = keyOffset; 48 length = keyLength; 49 } 50 51 /** 52 * Mutates this key for a new NUL-terminated resource key string. 53 * The corresponding ASCII-character bytes are not copied and 54 * must not be changed during the lifetime of this key 55 * (or until the next setBytes() call) 56 * and lifetimes of subSequences created from this key. 57 * 58 * @param keyBytes new key string byte array 59 * @param keyOffset new key string offset 60 */ 61 public void setBytes(byte[] keyBytes, int keyOffset) { 62 bytes = keyBytes; 63 offset = keyOffset; 64 for (length = 0; keyBytes[keyOffset + length] != 0; ++length) {} 65 s = null; 66 } 67 68 /** 69 * Mutates this key to an empty resource key string. 70 */ 71 public void setToEmpty() { 72 bytes = null; 73 offset = length = 0; 74 s = null; 75 } 76 77 /** 78 * {@inheritDoc} 79 * Does not clone the byte array. 80 */ 81 @Override 82 public Key clone() { 83 try { 84 return (Key)super.clone(); 85 } catch (CloneNotSupportedException cannotOccur) { 86 return null; 87 } 88 } 89 90 // TODO: Java 6: @Override 91 public char charAt(int i) { 92 assert(0 <= i && i < length); 93 return (char)bytes[offset + i]; 94 } 95 96 // TODO: Java 6: @Override 97 public int length() { 98 return length; 99 } 100 101 // TODO: Java 6: @Override 102 public Key subSequence(int start, int end) { 103 assert(0 <= start && start < length); 104 assert(start <= end && end <= length); 105 return new Key(bytes, offset + start, end - start); 106 } 107 108 /** 109 * Creates/caches/returns this resource key string as a Java String. 110 */ 111 public String toString() { 112 if (s == null) { 113 s = internalSubString(0, length); 114 } 115 return s; 116 } 117 118 private String internalSubString(int start, int end) { 119 StringBuilder sb = new StringBuilder(end - start); 120 for (int i = start; i < end; ++i) { 121 sb.append((char)bytes[offset + i]); 122 } 123 return sb.toString(); 124 } 125 126 /** 127 * Creates a new Java String for a sub-sequence of this resource key string. 128 */ 129 public String substring(int start) { 130 assert(0 <= start && start < length); 131 return internalSubString(start, length); 132 } 133 134 /** 135 * Creates a new Java String for a sub-sequence of this resource key string. 136 */ 137 public String substring(int start, int end) { 138 assert(0 <= start && start < length); 139 assert(start <= end && end <= length); 140 return internalSubString(start, end); 141 } 142 143 private boolean regionMatches(byte[] otherBytes, int otherOffset, int n) { 144 for (int i = 0; i < n; ++i) { 145 if (bytes[offset + i] != otherBytes[otherOffset + i]) { 146 return false; 147 } 148 } 149 return true; 150 } 151 152 private boolean regionMatches(int start, CharSequence cs, int n) { 153 for (int i = 0; i < n; ++i) { 154 if (bytes[offset + start + i] != cs.charAt(i)) { 155 return false; 156 } 157 } 158 return true; 159 } 160 161 @Override 162 public boolean equals(Object other) { 163 if (other == null) { 164 return false; 165 } else if (this == other) { 166 return true; 167 } else if (other instanceof Key) { 168 Key otherKey = (Key)other; 169 return length == otherKey.length && 170 regionMatches(otherKey.bytes, otherKey.offset, length); 171 } else { 172 return false; 173 } 174 } 175 176 public boolean contentEquals(CharSequence cs) { 177 if (cs == null) { 178 return false; 179 } 180 return this == cs || (cs.length() == length && regionMatches(0, cs, length)); 181 } 182 183 public boolean startsWith(CharSequence cs) { 184 int csLength = cs.length(); 185 return csLength <= length && regionMatches(0, cs, csLength); 186 } 187 188 public boolean endsWith(CharSequence cs) { 189 int csLength = cs.length(); 190 return csLength <= length && regionMatches(length - csLength, cs, csLength); 191 } 192 193 /** 194 * @return true if the substring of this key starting from the offset 195 * contains the same characters as the other sequence. 196 */ 197 public boolean regionMatches(int start, CharSequence cs) { 198 int csLength = cs.length(); 199 return csLength == (length - start) && regionMatches(start, cs, csLength); 200 } 201 202 @Override 203 public int hashCode() { 204 // Never return s.hashCode(), so that 205 // Key.hashCode() is the same whether we have cached s or not. 206 if (length == 0) { 207 return 0; 208 } 209 210 int h = bytes[offset]; 211 for (int i = 1; i < length; ++i) { 212 h = 37 * h + bytes[offset]; 213 } 214 return h; 215 } 216 217 // TODO: Java 6: @Override 218 public int compareTo(Key other) { 219 return compareTo((CharSequence)other); 220 } 221 222 public int compareTo(CharSequence cs) { 223 int csLength = cs.length(); 224 int minLength = length <= csLength ? length : csLength; 225 for (int i = 0; i < minLength; ++i) { 226 int diff = (int)charAt(i) - (int)cs.charAt(i); 227 if (diff != 0) { 228 return diff; 229 } 230 } 231 return length - csLength; 232 } 233 } 234 235 /** 236 * Represents a resource bundle item's value. 237 * Avoids object creations as much as possible. 238 * Mutable, not thread-safe. 239 */ 240 public static abstract class Value { 241 protected Value() {} 242 243 /** 244 * @return ICU resource type like {@link UResourceBundle#getType()}, 245 * for example, {@link UResourceBundle#STRING} 246 */ 247 public abstract int getType(); 248 249 /** 250 * @see UResourceBundle#getString() 251 * @throws UResourceTypeMismatchException if this is not a string resource 252 */ 253 public abstract String getString(); 254 255 /** 256 * @throws UResourceTypeMismatchException if this is not an alias resource 257 */ 258 public abstract String getAliasString(); 259 260 /** 261 * @see UResourceBundle#getInt() 262 * @throws UResourceTypeMismatchException if this is not an integer resource 263 */ 264 public abstract int getInt(); 265 266 /** 267 * @see UResourceBundle#getUInt() 268 * @throws UResourceTypeMismatchException if this is not an integer resource 269 */ 270 public abstract int getUInt(); 271 272 /** 273 * @see UResourceBundle#getIntVector() 274 * @throws UResourceTypeMismatchException if this is not an intvector resource 275 */ 276 public abstract int[] getIntVector(); 277 278 /** 279 * @see UResourceBundle#getBinary() 280 * @throws UResourceTypeMismatchException if this is not a binary-blob resource 281 */ 282 public abstract ByteBuffer getBinary(); 283 284 /** 285 * Only for debugging. 286 */ 287 @Override 288 public String toString() { 289 switch(getType()) { 290 case UResourceBundle.STRING: 291 return getString(); 292 case UResourceBundle.INT: 293 return Integer.toString(getInt()); 294 case UResourceBundle.INT_VECTOR: 295 int[] iv = getIntVector(); 296 StringBuilder sb = new StringBuilder("["); 297 sb.append(iv.length).append("]{"); 298 if (iv.length != 0) { 299 sb.append(iv[0]); 300 for (int i = 1; i < iv.length; ++i) { 301 sb.append(", ").append(iv[i]); 302 } 303 } 304 return sb.append('}').toString(); 305 case UResourceBundle.BINARY: 306 return "(binary blob)"; 307 case UResourceBundle.ARRAY: // should not occur 308 return "(array)"; 309 case UResourceBundle.TABLE: // should not occur 310 return "(table)"; 311 default: // should not occur 312 return "???"; 313 } 314 } 315 } 316 317 /** 318 * Sink for ICU resource array contents. 319 * The base class does nothing. 320 * 321 * <p>Nested arrays and tables are stored as nested sinks, 322 * never put() as {@link Value} items. 323 */ 324 public static class ArraySink { 325 /** 326 * Adds a value from a resource array. 327 * 328 * @param index of the resource array item 329 * @param value resource value 330 */ 331 public void put(int index, Value value) {} 332 333 /** 334 * Returns a nested resource array at the array index as another sink. 335 * Creates the sink if none exists for the key. 336 * Returns null if nested arrays are not supported. 337 * The default implementation always returns null. 338 * 339 * @param index of the resource array item 340 * @param size number of array items 341 * @return nested-array sink, or null 342 */ 343 public ArraySink getOrCreateArraySink(int index, int size) { 344 return null; 345 } 346 347 /** 348 * Returns a nested resource table at the array index as another sink. 349 * Creates the sink if none exists for the key. 350 * Returns null if nested tables are not supported. 351 * The default implementation always returns null. 352 * 353 * @param index of the resource array item 354 * @param initialSize size hint for creating the sink if necessary 355 * @return nested-table sink, or null 356 */ 357 public TableSink getOrCreateTableSink(int index, int initialSize) { 358 return null; 359 } 360 361 /** 362 * "Leaves" the array. 363 * Indicates that all of the resources and sub-resources of the current array 364 * have been enumerated. 365 */ 366 public void leave() {} 367 } 368 369 /** 370 * Sink for ICU resource table contents. 371 * The base class does nothing. 372 * 373 * <p>Nested arrays and tables are stored as nested sinks, 374 * never put() as {@link Value} items. 375 */ 376 public static class TableSink { 377 /** 378 * Adds a key-value pair from a resource table. 379 * 380 * @param key resource key string 381 * @param value resource value 382 */ 383 public void put(Key key, Value value) {} 384 385 /** 386 * Adds a no-fallback/no-inheritance marker for this key. 387 * Used for CLDR no-fallback data values of "∅∅∅" 388 * when enumerating tables with fallback from the specific resource bundle to root. 389 * 390 * <p>The default implementation does nothing. 391 * 392 * @param key to be removed 393 */ 394 public void putNoFallback(Key key) {} 395 396 /** 397 * Returns a nested resource array for the key as another sink. 398 * Creates the sink if none exists for the key. 399 * Returns null if nested arrays are not supported. 400 * The default implementation always returns null. 401 * 402 * @param key resource key string 403 * @param size number of array items 404 * @return nested-array sink, or null 405 */ 406 public ArraySink getOrCreateArraySink(Key key, int size) { 407 return null; 408 } 409 410 /** 411 * Returns a nested resource table for the key as another sink. 412 * Creates the sink if none exists for the key. 413 * Returns null if nested tables are not supported. 414 * The default implementation always returns null. 415 * 416 * @param key resource key string 417 * @param initialSize size hint for creating the sink if necessary 418 * @return nested-table sink, or null 419 */ 420 public TableSink getOrCreateTableSink(Key key, int initialSize) { 421 return null; 422 } 423 424 /** 425 * "Leaves" the table. 426 * Indicates that all of the resources and sub-resources of the current table 427 * have been enumerated. 428 */ 429 public void leave() {} 430 } 431} 432