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 4 /* 5 ******************************************************************************* 6 * Copyright (C) 1996-2016, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 */ 10 11 package android.icu.util; 12 13 import java.util.concurrent.ConcurrentHashMap; 14 15 /** 16 * Class to store version numbers of the form major.minor.milli.micro. 17 * @author synwee 18 */ 19 public final class VersionInfo implements Comparable<VersionInfo> 20 { 21 // public data members ------------------------------------------------- 22 23 /** 24 * Unicode 1.0 version 25 */ 26 public static final VersionInfo UNICODE_1_0; 27 /** 28 * Unicode 1.0.1 version 29 */ 30 public static final VersionInfo UNICODE_1_0_1; 31 /** 32 * Unicode 1.1.0 version 33 */ 34 public static final VersionInfo UNICODE_1_1_0; 35 /** 36 * Unicode 1.1.5 version 37 */ 38 public static final VersionInfo UNICODE_1_1_5; 39 /** 40 * Unicode 2.0 version 41 */ 42 public static final VersionInfo UNICODE_2_0; 43 /** 44 * Unicode 2.1.2 version 45 */ 46 public static final VersionInfo UNICODE_2_1_2; 47 /** 48 * Unicode 2.1.5 version 49 */ 50 public static final VersionInfo UNICODE_2_1_5; 51 /** 52 * Unicode 2.1.8 version 53 */ 54 public static final VersionInfo UNICODE_2_1_8; 55 /** 56 * Unicode 2.1.9 version 57 */ 58 public static final VersionInfo UNICODE_2_1_9; 59 /** 60 * Unicode 3.0 version 61 */ 62 public static final VersionInfo UNICODE_3_0; 63 /** 64 * Unicode 3.0.1 version 65 */ 66 public static final VersionInfo UNICODE_3_0_1; 67 /** 68 * Unicode 3.1.0 version 69 */ 70 public static final VersionInfo UNICODE_3_1_0; 71 /** 72 * Unicode 3.1.1 version 73 */ 74 public static final VersionInfo UNICODE_3_1_1; 75 /** 76 * Unicode 3.2 version 77 */ 78 public static final VersionInfo UNICODE_3_2; 79 80 /** 81 * Unicode 4.0 version 82 */ 83 public static final VersionInfo UNICODE_4_0; 84 85 /** 86 * Unicode 4.0.1 version 87 */ 88 public static final VersionInfo UNICODE_4_0_1; 89 90 /** 91 * Unicode 4.1 version 92 */ 93 public static final VersionInfo UNICODE_4_1; 94 95 /** 96 * Unicode 5.0 version 97 */ 98 public static final VersionInfo UNICODE_5_0; 99 100 /** 101 * Unicode 5.1 version 102 */ 103 public static final VersionInfo UNICODE_5_1; 104 105 /** 106 * Unicode 5.2 version 107 */ 108 public static final VersionInfo UNICODE_5_2; 109 110 /** 111 * Unicode 6.0 version 112 */ 113 public static final VersionInfo UNICODE_6_0; 114 115 /** 116 * Unicode 6.1 version 117 */ 118 public static final VersionInfo UNICODE_6_1; 119 120 /** 121 * Unicode 6.2 version 122 */ 123 public static final VersionInfo UNICODE_6_2; 124 125 /** 126 * Unicode 6.3 version 127 */ 128 public static final VersionInfo UNICODE_6_3; 129 130 /** 131 * Unicode 7.0 version 132 */ 133 public static final VersionInfo UNICODE_7_0; 134 135 /** 136 * Unicode 8.0 version 137 */ 138 public static final VersionInfo UNICODE_8_0; 139 140 /** 141 * Unicode 9.0 version 142 */ 143 public static final VersionInfo UNICODE_9_0; 144 145 /** 146 * Unicode 10.0 version 147 */ 148 public static final VersionInfo UNICODE_10_0; 149 150 /** 151 * Unicode 11.0 version 152 */ 153 public static final VersionInfo UNICODE_11_0; 154 155 /** 156 * Unicode 12.0 version 157 */ 158 public static final VersionInfo UNICODE_12_0; 159 160 /** 161 * Unicode 12.1 version 162 */ 163 public static final VersionInfo UNICODE_12_1; 164 165 /** 166 * Unicode 13.0 version 167 */ 168 public static final VersionInfo UNICODE_13_0; 169 170 /** 171 * Unicode 14.0 version 172 */ 173 public static final VersionInfo UNICODE_14_0; 174 175 /** 176 * Unicode 15.0 version 177 */ 178 public static final VersionInfo UNICODE_15_0; 179 180 /** 181 * Unicode 15.1 version 182 */ 183 @android.annotation.FlaggedApi(com.android.icu.Flags.FLAG_ICU_V_API) 184 public static final VersionInfo UNICODE_15_1; 185 186 /** 187 * ICU4J current release version 188 */ 189 public static final VersionInfo ICU_VERSION; 190 191 /** 192 * Data version string for ICU's internal data. 193 * Used for appending to data path (e.g. icudt43b) 194 * @deprecated This API is ICU internal only. 195 * @hide original deprecated declaration 196 * @hide draft / provisional / internal are hidden on Android 197 */ 198 @Deprecated 199 public static final String ICU_DATA_VERSION_PATH = "75b"; 200 201 /** 202 * Data version in ICU4J. 203 * @deprecated This API is ICU internal only. 204 * @hide original deprecated declaration 205 * @hide draft / provisional / internal are hidden on Android 206 */ 207 @Deprecated 208 public static final VersionInfo ICU_DATA_VERSION; 209 210 /** 211 * Collation runtime version (sort key generator, string comparisons). 212 * If the version is different, sort keys for the same string could be different. 213 * This value may change in subsequent releases of ICU. 214 */ 215 public static final VersionInfo UCOL_RUNTIME_VERSION; 216 217 /** 218 * Collation builder code version. 219 * When this is different, the same tailoring might result 220 * in assigning different collation elements to code points. 221 * This value may change in subsequent releases of ICU. 222 */ 223 public static final VersionInfo UCOL_BUILDER_VERSION; 224 225 /** 226 * Constant version 1. 227 * This was intended to be the version of collation tailorings, 228 * but instead the tailoring data carries a version number. 229 * @deprecated ICU 54 230 * @hide original deprecated declaration 231 */ 232 @Deprecated 233 public static final VersionInfo UCOL_TAILORINGS_VERSION; 234 235 236 // public methods ------------------------------------------------------ 237 238 /** 239 * Returns an instance of VersionInfo with the argument version. 240 * @param version version String in the format of "major.minor.milli.micro" 241 * or "major.minor.milli" or "major.minor" or "major", 242 * where major, minor, milli, micro are non-negative numbers 243 * <= 255. If the trailing version numbers are 244 * not specified they are taken as 0s. E.g. Version "3.1" is 245 * equivalent to "3.1.0.0". 246 * @return an instance of VersionInfo with the argument version. 247 * @exception IllegalArgumentException when the argument version 248 * is not in the right format 249 */ getInstance(String version)250 public static VersionInfo getInstance(String version) 251 { 252 int length = version.length(); 253 int array[] = {0, 0, 0, 0}; 254 int count = 0; 255 int index = 0; 256 257 while (count < 4 && index < length) { 258 char c = version.charAt(index); 259 if (c == '.') { 260 count ++; 261 } 262 else { 263 c -= '0'; 264 if (c < 0 || c > 9) { 265 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); 266 } 267 array[count] *= 10; 268 array[count] += c; 269 } 270 index ++; 271 } 272 if (index != length) { 273 throw new IllegalArgumentException( 274 "Invalid version number: String '" + version + "' exceeds version format"); 275 } 276 for (int i = 0; i < 4; i ++) { 277 if (array[i] < 0 || array[i] > 255) { 278 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); 279 } 280 } 281 282 return getInstance(array[0], array[1], array[2], array[3]); 283 } 284 285 /** 286 * Returns an instance of VersionInfo with the argument version. 287 * @param major major version, non-negative number <= 255. 288 * @param minor minor version, non-negative number <= 255. 289 * @param milli milli version, non-negative number <= 255. 290 * @param micro micro version, non-negative number <= 255. 291 * @exception IllegalArgumentException when either arguments are negative or > 255 292 */ getInstance(int major, int minor, int milli, int micro)293 public static VersionInfo getInstance(int major, int minor, int milli, 294 int micro) 295 { 296 // checks if it is in the hashmap 297 // else 298 if (major < 0 || major > 255 || minor < 0 || minor > 255 || 299 milli < 0 || milli > 255 || micro < 0 || micro > 255) { 300 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); 301 } 302 int version = getInt(major, minor, milli, micro); 303 Integer key = version; 304 VersionInfo result = MAP_.get(key); 305 if (result == null) { 306 result = new VersionInfo(version); 307 VersionInfo tmpvi = MAP_.putIfAbsent(key, result); 308 if (tmpvi != null) { 309 result = tmpvi; 310 } 311 } 312 return result; 313 } 314 315 /** 316 * Returns an instance of VersionInfo with the argument version. 317 * Equivalent to getInstance(major, minor, milli, 0). 318 * @param major major version, non-negative number <= 255. 319 * @param minor minor version, non-negative number <= 255. 320 * @param milli milli version, non-negative number <= 255. 321 * @exception IllegalArgumentException when either arguments are 322 * negative or > 255 323 */ getInstance(int major, int minor, int milli)324 public static VersionInfo getInstance(int major, int minor, int milli) 325 { 326 return getInstance(major, minor, milli, 0); 327 } 328 329 /** 330 * Returns an instance of VersionInfo with the argument version. 331 * Equivalent to getInstance(major, minor, 0, 0). 332 * @param major major version, non-negative number <= 255. 333 * @param minor minor version, non-negative number <= 255. 334 * @exception IllegalArgumentException when either arguments are 335 * negative or > 255 336 */ getInstance(int major, int minor)337 public static VersionInfo getInstance(int major, int minor) 338 { 339 return getInstance(major, minor, 0, 0); 340 } 341 342 /** 343 * Returns an instance of VersionInfo with the argument version. 344 * Equivalent to getInstance(major, 0, 0, 0). 345 * @param major major version, non-negative number <= 255. 346 * @exception IllegalArgumentException when either arguments are 347 * negative or > 255 348 */ getInstance(int major)349 public static VersionInfo getInstance(int major) 350 { 351 return getInstance(major, 0, 0, 0); 352 } 353 354 /** 355 * Returns the String representative of VersionInfo in the format of 356 * "major.minor.milli.micro" 357 * @return String representative of VersionInfo 358 */ 359 @Override toString()360 public String toString() 361 { 362 StringBuilder result = new StringBuilder(7); 363 result.append(getMajor()); 364 result.append('.'); 365 result.append(getMinor()); 366 result.append('.'); 367 result.append(getMilli()); 368 result.append('.'); 369 result.append(getMicro()); 370 return result.toString(); 371 } 372 373 /** 374 * Returns the major version number 375 * @return the major version number 376 */ getMajor()377 public int getMajor() 378 { 379 return (m_version_ >> 24) & LAST_BYTE_MASK_ ; 380 } 381 382 /** 383 * Returns the minor version number 384 * @return the minor version number 385 */ getMinor()386 public int getMinor() 387 { 388 return (m_version_ >> 16) & LAST_BYTE_MASK_ ; 389 } 390 391 /** 392 * Returns the milli version number 393 * @return the milli version number 394 */ getMilli()395 public int getMilli() 396 { 397 return (m_version_ >> 8) & LAST_BYTE_MASK_ ; 398 } 399 400 /** 401 * Returns the micro version number 402 * @return the micro version number 403 */ getMicro()404 public int getMicro() 405 { 406 return m_version_ & LAST_BYTE_MASK_ ; 407 } 408 409 /** 410 * Checks if this version information is equals to the argument version 411 * @param other object to be compared 412 * @return true if other is equals to this object's version information, 413 * false otherwise 414 */ 415 @Override equals(Object other)416 public boolean equals(Object other) 417 { 418 return other == this; 419 } 420 421 /** 422 * Returns the hash code value for this set. 423 * 424 * @return the hash code value for this set. 425 * @see java.lang.Object#hashCode() 426 */ 427 @Override hashCode()428 public int hashCode() { 429 return m_version_; 430 } 431 432 /** 433 * Compares other with this VersionInfo. 434 * @param other VersionInfo to be compared 435 * @return 0 if the argument is a VersionInfo object that has version 436 * information equals to this object. 437 * Less than 0 if the argument is a VersionInfo object that has 438 * version information greater than this object. 439 * Greater than 0 if the argument is a VersionInfo object that 440 * has version information less than this object. 441 */ 442 @Override compareTo(VersionInfo other)443 public int compareTo(VersionInfo other) 444 { 445 // m_version_ is an int, a signed 32-bit integer. 446 // When the major version is >=128, then the version int is negative. 447 // Compare it in two steps to simulate an unsigned-int comparison. 448 // (Alternatively we could turn each int into a long and reset the upper 32 bits.) 449 // Compare the upper bits first, using logical shift right (unsigned). 450 int diff = (m_version_ >>> 1) - (other.m_version_ >>> 1); 451 if (diff != 0) { return diff; } 452 // Compare the remaining bits. 453 return (m_version_ & 1) - (other.m_version_ & 1); 454 } 455 456 // private data members ---------------------------------------------- 457 458 /** 459 * Unicode data version used by the current release. 460 * Defined here privately for printing by the main() method in this class. 461 * Should be the same as {@link android.icu.lang.UCharacter#getUnicodeVersion()} 462 * which gets the version number from a data file. 463 * We do not want VersionInfo to have an import dependency on UCharacter. 464 */ 465 private static final VersionInfo UNICODE_VERSION; 466 467 /** 468 * Version number stored as a byte for each of the major, minor, milli and 469 * micro numbers in the 32 bit int. 470 * Most significant for the major and the least significant contains the 471 * micro numbers. 472 */ 473 private int m_version_; 474 /** 475 * Map of singletons 476 */ 477 private static final ConcurrentHashMap<Integer, VersionInfo> MAP_ = new ConcurrentHashMap<>(); 478 /** 479 * Last byte mask 480 */ 481 private static final int LAST_BYTE_MASK_ = 0xFF; 482 /** 483 * Error statement string 484 */ 485 private static final String INVALID_VERSION_NUMBER_ = 486 "Invalid version number: Version number may be negative or greater than 255"; 487 488 // static declaration ------------------------------------------------ 489 490 /** 491 * Initialize versions only after MAP_ has been created 492 */ 493 static { 494 UNICODE_1_0 = getInstance(1, 0, 0, 0); 495 UNICODE_1_0_1 = getInstance(1, 0, 1, 0); 496 UNICODE_1_1_0 = getInstance(1, 1, 0, 0); 497 UNICODE_1_1_5 = getInstance(1, 1, 5, 0); 498 UNICODE_2_0 = getInstance(2, 0, 0, 0); 499 UNICODE_2_1_2 = getInstance(2, 1, 2, 0); 500 UNICODE_2_1_5 = getInstance(2, 1, 5, 0); 501 UNICODE_2_1_8 = getInstance(2, 1, 8, 0); 502 UNICODE_2_1_9 = getInstance(2, 1, 9, 0); 503 UNICODE_3_0 = getInstance(3, 0, 0, 0); 504 UNICODE_3_0_1 = getInstance(3, 0, 1, 0); 505 UNICODE_3_1_0 = getInstance(3, 1, 0, 0); 506 UNICODE_3_1_1 = getInstance(3, 1, 1, 0); 507 UNICODE_3_2 = getInstance(3, 2, 0, 0); 508 UNICODE_4_0 = getInstance(4, 0, 0, 0); 509 UNICODE_4_0_1 = getInstance(4, 0, 1, 0); 510 UNICODE_4_1 = getInstance(4, 1, 0, 0); 511 UNICODE_5_0 = getInstance(5, 0, 0, 0); 512 UNICODE_5_1 = getInstance(5, 1, 0, 0); 513 UNICODE_5_2 = getInstance(5, 2, 0, 0); 514 UNICODE_6_0 = getInstance(6, 0, 0, 0); 515 UNICODE_6_1 = getInstance(6, 1, 0, 0); 516 UNICODE_6_2 = getInstance(6, 2, 0, 0); 517 UNICODE_6_3 = getInstance(6, 3, 0, 0); 518 UNICODE_7_0 = getInstance(7, 0, 0, 0); 519 UNICODE_8_0 = getInstance(8, 0, 0, 0); 520 UNICODE_9_0 = getInstance(9, 0, 0, 0); 521 UNICODE_10_0 = getInstance(10, 0, 0, 0); 522 UNICODE_11_0 = getInstance(11, 0, 0, 0); 523 UNICODE_12_0 = getInstance(12, 0, 0, 0); 524 UNICODE_12_1 = getInstance(12, 1, 0, 0); 525 UNICODE_13_0 = getInstance(13, 0, 0, 0); 526 UNICODE_14_0 = getInstance(14, 0, 0, 0); 527 UNICODE_15_0 = getInstance(15, 0, 0, 0); 528 UNICODE_15_1 = getInstance(15, 1, 0, 0); 529 530 ICU_VERSION = getInstance(75, 1, 0, 0); 531 ICU_DATA_VERSION = ICU_VERSION; 532 UNICODE_VERSION = UNICODE_15_1; 533 534 UCOL_RUNTIME_VERSION = getInstance(9); 535 UCOL_BUILDER_VERSION = getInstance(9); 536 UCOL_TAILORINGS_VERSION = getInstance(1); 537 } 538 539 // private constructor ----------------------------------------------- 540 541 /** 542 * Constructor with int 543 * @param compactversion a 32 bit int with each byte representing a number 544 */ VersionInfo(int compactversion)545 private VersionInfo(int compactversion) 546 { 547 m_version_ = compactversion; 548 } 549 550 /** 551 * Gets the int from the version numbers 552 * @param major non-negative version number 553 * @param minor non-negative version number 554 * @param milli non-negative version number 555 * @param micro non-negative version number 556 */ getInt(int major, int minor, int milli, int micro)557 private static int getInt(int major, int minor, int milli, int micro) 558 { 559 return (major << 24) | (minor << 16) | (milli << 8) | micro; 560 } 561 ///CLOVER:OFF 562 /** 563 * Main method prints out ICU version information 564 * @param args arguments (currently not used) 565 * @hide unsupported on Android 566 */ main(String[] args)567 public static void main(String[] args) { 568 String icuApiVer; 569 570 if (ICU_VERSION.getMajor() <= 4) { 571 if (ICU_VERSION.getMinor() % 2 != 0) { 572 // Development mile stone 573 int major = ICU_VERSION.getMajor(); 574 int minor = ICU_VERSION.getMinor() + 1; 575 if (minor >= 10) { 576 minor -= 10; 577 major++; 578 } 579 icuApiVer = "" + major + "." + minor + "M" + ICU_VERSION.getMilli(); 580 } else { 581 icuApiVer = ICU_VERSION.getVersionString(2, 2); 582 } 583 } else { 584 if (ICU_VERSION.getMinor() == 0) { 585 // Development mile stone 586 icuApiVer = "" + ICU_VERSION.getMajor() + "M" + ICU_VERSION.getMilli(); 587 } else { 588 icuApiVer = ICU_VERSION.getVersionString(2, 2); 589 } 590 } 591 592 593 System.out.println("International Components for Unicode for Java " + icuApiVer); 594 595 System.out.println(""); 596 System.out.println("Implementation Version: " + ICU_VERSION.getVersionString(2, 4)); 597 System.out.println("Unicode Data Version: " + UNICODE_VERSION.getVersionString(2, 4)); 598 System.out.println("CLDR Data Version: " + LocaleData.getCLDRVersion().getVersionString(2, 4)); 599 System.out.println("Time Zone Data Version: " + getTZDataVersion()); 600 } 601 602 /** 603 * Generate version string separated by dots with 604 * the specified digit width. Version digit 0 605 * after <code>minDigits</code> will be trimmed off. 606 * @param minDigits Minimum number of version digits 607 * @param maxDigits Maximum number of version digits 608 * @return A tailored version string 609 * @deprecated This API is ICU internal only. (For use in CLDR, etc.) 610 * @hide original deprecated declaration 611 * @hide draft / provisional / internal are hidden on Android 612 */ 613 @Deprecated getVersionString(int minDigits, int maxDigits)614 public String getVersionString(int minDigits, int maxDigits) { 615 if (minDigits < 1 || maxDigits < 1 616 || minDigits > 4 || maxDigits > 4 || minDigits > maxDigits) { 617 throw new IllegalArgumentException("Invalid min/maxDigits range"); 618 } 619 620 int[] digits = new int[4]; 621 digits[0] = getMajor(); 622 digits[1] = getMinor(); 623 digits[2] = getMilli(); 624 digits[3] = getMicro(); 625 626 int numDigits = maxDigits; 627 while (numDigits > minDigits) { 628 if (digits[numDigits - 1] != 0) { 629 break; 630 } 631 numDigits--; 632 } 633 634 StringBuilder verStr = new StringBuilder(7); 635 verStr.append(digits[0]); 636 for (int i = 1; i < numDigits; i++) { 637 verStr.append("."); 638 verStr.append(digits[i]); 639 } 640 641 return verStr.toString(); 642 } 643 ///CLOVER:ON 644 645 646 // Moved from TimeZone class 647 private static volatile String TZDATA_VERSION = null; 648 getTZDataVersion()649 static String getTZDataVersion() { 650 if (TZDATA_VERSION == null) { 651 synchronized (VersionInfo.class) { 652 if (TZDATA_VERSION == null) { 653 UResourceBundle tzbundle = UResourceBundle.getBundleInstance("android/icu/impl/data/icudt" 654 + VersionInfo.ICU_DATA_VERSION_PATH, "zoneinfo64"); 655 TZDATA_VERSION = tzbundle.getString("TZVersion"); 656 } 657 } 658 } 659 return TZDATA_VERSION; 660 } 661 } 662