lsr.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // © 2019 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. // lsr.cpp
  4. // created: 2019may08 Markus W. Scherer
  5. #include "unicode/utypes.h"
  6. #include "charstr.h"
  7. #include "cmemory.h"
  8. #include "cstring.h"
  9. #include "lsr.h"
  10. #include "uinvchar.h"
  11. #include "ustr_imp.h"
  12. U_NAMESPACE_BEGIN
  13. LSR::LSR(char prefix, const char *lang, const char *scr, const char *r, int32_t f,
  14. UErrorCode &errorCode) :
  15. language(nullptr), script(nullptr), region(r),
  16. regionIndex(indexForRegion(region)), flags(f) {
  17. if (U_SUCCESS(errorCode)) {
  18. CharString langScript;
  19. langScript.append(prefix, errorCode).append(lang, errorCode).append('\0', errorCode);
  20. int32_t scriptOffset = langScript.length();
  21. langScript.append(prefix, errorCode).append(scr, errorCode);
  22. owned = langScript.cloneData(errorCode);
  23. if (U_SUCCESS(errorCode)) {
  24. language = owned;
  25. script = owned + scriptOffset;
  26. }
  27. }
  28. }
  29. LSR::LSR(LSR &&other) noexcept :
  30. language(other.language), script(other.script), region(other.region), owned(other.owned),
  31. regionIndex(other.regionIndex), flags(other.flags),
  32. hashCode(other.hashCode) {
  33. if (owned != nullptr) {
  34. other.language = other.script = "";
  35. other.owned = nullptr;
  36. other.hashCode = 0;
  37. }
  38. }
  39. void LSR::deleteOwned() {
  40. uprv_free(owned);
  41. }
  42. LSR &LSR::operator=(LSR &&other) noexcept {
  43. this->~LSR();
  44. language = other.language;
  45. script = other.script;
  46. region = other.region;
  47. regionIndex = other.regionIndex;
  48. flags = other.flags;
  49. owned = other.owned;
  50. hashCode = other.hashCode;
  51. if (owned != nullptr) {
  52. other.language = other.script = "";
  53. other.owned = nullptr;
  54. other.hashCode = 0;
  55. }
  56. return *this;
  57. }
  58. UBool LSR::isEquivalentTo(const LSR &other) const {
  59. return
  60. uprv_strcmp(language, other.language) == 0 &&
  61. uprv_strcmp(script, other.script) == 0 &&
  62. regionIndex == other.regionIndex &&
  63. // Compare regions if both are ill-formed (and their indexes are 0).
  64. (regionIndex > 0 || uprv_strcmp(region, other.region) == 0);
  65. }
  66. bool LSR::operator==(const LSR &other) const {
  67. return
  68. uprv_strcmp(language, other.language) == 0 &&
  69. uprv_strcmp(script, other.script) == 0 &&
  70. regionIndex == other.regionIndex &&
  71. // Compare regions if both are ill-formed (and their indexes are 0).
  72. (regionIndex > 0 || uprv_strcmp(region, other.region) == 0) &&
  73. flags == other.flags;
  74. }
  75. int32_t LSR::indexForRegion(const char *region) {
  76. int32_t c = region[0];
  77. int32_t a = c - '0';
  78. if (0 <= a && a <= 9) { // digits: "419"
  79. int32_t b = region[1] - '0';
  80. if (b < 0 || 9 < b) { return 0; }
  81. c = region[2] - '0';
  82. if (c < 0 || 9 < c || region[3] != 0) { return 0; }
  83. return (10 * a + b) * 10 + c + 1;
  84. } else { // letters: "DE"
  85. a = uprv_upperOrdinal(c);
  86. if (a < 0 || 25 < a) { return 0; }
  87. int32_t b = uprv_upperOrdinal(region[1]);
  88. if (b < 0 || 25 < b || region[2] != 0) { return 0; }
  89. return 26 * a + b + 1001;
  90. }
  91. return 0;
  92. }
  93. LSR &LSR::setHashCode() {
  94. if (hashCode == 0) {
  95. uint32_t h = ustr_hashCharsN(language, static_cast<int32_t>(uprv_strlen(language)));
  96. h = h * 37 + ustr_hashCharsN(script, static_cast<int32_t>(uprv_strlen(script)));
  97. h = h * 37 + regionIndex;
  98. hashCode = h * 37 + flags;
  99. }
  100. return *this;
  101. }
  102. U_NAMESPACE_END