locresdata.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. *******************************************************************************
  5. *
  6. * Copyright (C) 1997-2012, International Business Machines
  7. * Corporation and others. All Rights Reserved.
  8. *
  9. *******************************************************************************
  10. * file name: loclikely.cpp
  11. * encoding: UTF-8
  12. * tab size: 8 (not used)
  13. * indentation:4
  14. *
  15. * created on: 2010feb25
  16. * created by: Markus W. Scherer
  17. *
  18. * Code for miscellaneous locale-related resource bundle data access,
  19. * separated out from other .cpp files
  20. * that then do not depend on resource bundle code and this data.
  21. */
  22. #include "unicode/utypes.h"
  23. #include "unicode/putil.h"
  24. #include "unicode/uloc.h"
  25. #include "unicode/ures.h"
  26. #include "charstr.h"
  27. #include "cstring.h"
  28. #include "ulocimp.h"
  29. #include "uresimp.h"
  30. /*
  31. * Lookup a resource bundle table item with fallback on the table level.
  32. * Regular resource bundle lookups perform fallback to parent locale bundles
  33. * and eventually the root bundle, but only for top-level items.
  34. * This function takes the name of a top-level table and of an item in that table
  35. * and performs a lookup of both, falling back until a bundle contains a table
  36. * with this item.
  37. *
  38. * Note: Only the opening of entire bundles falls back through the default locale
  39. * before root. Once a bundle is open, item lookups do not go through the
  40. * default locale because that would result in a mix of languages that is
  41. * unpredictable to the programmer and most likely useless.
  42. */
  43. U_CAPI const char16_t * U_EXPORT2
  44. uloc_getTableStringWithFallback(const char *path, const char *locale,
  45. const char *tableKey, const char *subTableKey,
  46. const char *itemKey,
  47. int32_t *pLength,
  48. UErrorCode *pErrorCode)
  49. {
  50. if (U_FAILURE(*pErrorCode)) { return nullptr; }
  51. /* char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
  52. const char16_t *item=nullptr;
  53. UErrorCode errorCode;
  54. /*
  55. * open the bundle for the current locale
  56. * this falls back through the locale's chain to root
  57. */
  58. errorCode=U_ZERO_ERROR;
  59. icu::LocalUResourceBundlePointer rb(ures_open(path, locale, &errorCode));
  60. if(U_FAILURE(errorCode)) {
  61. /* total failure, not even root could be opened */
  62. *pErrorCode=errorCode;
  63. return nullptr;
  64. } else if(errorCode==U_USING_DEFAULT_WARNING ||
  65. (errorCode==U_USING_FALLBACK_WARNING && *pErrorCode!=U_USING_DEFAULT_WARNING)
  66. ) {
  67. /* set the "strongest" error code (success->fallback->default->failure) */
  68. *pErrorCode=errorCode;
  69. }
  70. for(;;){
  71. icu::StackUResourceBundle table;
  72. icu::StackUResourceBundle subTable;
  73. ures_getByKeyWithFallback(rb.getAlias(), tableKey, table.getAlias(), &errorCode);
  74. if (subTableKey != nullptr) {
  75. /*
  76. ures_getByKeyWithFallback(table.getAlias(), subTableKey, subTable.getAlias(), &errorCode);
  77. item = ures_getStringByKeyWithFallback(subTable.getAlias(), itemKey, pLength, &errorCode);
  78. if(U_FAILURE(errorCode)){
  79. *pErrorCode = errorCode;
  80. }
  81. break;*/
  82. ures_getByKeyWithFallback(table.getAlias(), subTableKey, table.getAlias(), &errorCode);
  83. }
  84. if(U_SUCCESS(errorCode)){
  85. item = ures_getStringByKeyWithFallback(table.getAlias(), itemKey, pLength, &errorCode);
  86. if(U_FAILURE(errorCode)){
  87. const char* replacement = nullptr;
  88. *pErrorCode = errorCode; /*save the errorCode*/
  89. errorCode = U_ZERO_ERROR;
  90. /* may be a deprecated code */
  91. if(uprv_strcmp(tableKey, "Countries")==0){
  92. replacement = uloc_getCurrentCountryID(itemKey);
  93. }else if(uprv_strcmp(tableKey, "Languages")==0){
  94. replacement = uloc_getCurrentLanguageID(itemKey);
  95. }
  96. /*pointer comparison is ok since uloc_getCurrentCountryID & uloc_getCurrentLanguageID return the key itself is replacement is not found*/
  97. if(replacement!=nullptr && itemKey != replacement){
  98. item = ures_getStringByKeyWithFallback(table.getAlias(), replacement, pLength, &errorCode);
  99. if(U_SUCCESS(errorCode)){
  100. *pErrorCode = errorCode;
  101. break;
  102. }
  103. }
  104. }else{
  105. break;
  106. }
  107. }
  108. if(U_FAILURE(errorCode)){
  109. /* still can't figure out ?.. try the fallback mechanism */
  110. int32_t len = 0;
  111. const char16_t* fallbackLocale = nullptr;
  112. *pErrorCode = errorCode;
  113. errorCode = U_ZERO_ERROR;
  114. fallbackLocale = ures_getStringByKeyWithFallback(table.getAlias(), "Fallback", &len, &errorCode);
  115. if(U_FAILURE(errorCode)){
  116. *pErrorCode = errorCode;
  117. break;
  118. }
  119. icu::CharString explicitFallbackName;
  120. explicitFallbackName.appendInvariantChars(fallbackLocale, len, errorCode);
  121. /* guard against recursive fallback */
  122. if (explicitFallbackName == locale) {
  123. *pErrorCode = U_INTERNAL_PROGRAM_ERROR;
  124. break;
  125. }
  126. rb.adoptInstead(ures_open(path, explicitFallbackName.data(), &errorCode));
  127. if(U_FAILURE(errorCode)){
  128. *pErrorCode = errorCode;
  129. break;
  130. }
  131. /* succeeded in opening the fallback bundle .. continue and try to fetch the item */
  132. }else{
  133. break;
  134. }
  135. }
  136. return item;
  137. }
  138. namespace {
  139. ULayoutType
  140. _uloc_getOrientationHelper(const char* localeId,
  141. const char* key,
  142. UErrorCode& status)
  143. {
  144. ULayoutType result = ULOC_LAYOUT_UNKNOWN;
  145. if (U_FAILURE(status)) { return result; }
  146. icu::CharString localeBuffer = ulocimp_canonicalize(localeId, status);
  147. if (U_FAILURE(status)) { return result; }
  148. int32_t length = 0;
  149. const char16_t* const value =
  150. uloc_getTableStringWithFallback(
  151. nullptr,
  152. localeBuffer.data(),
  153. "layout",
  154. nullptr,
  155. key,
  156. &length,
  157. &status);
  158. if (U_FAILURE(status)) { return result; }
  159. if (length != 0) {
  160. switch(value[0])
  161. {
  162. case 0x0062: /* 'b' */
  163. result = ULOC_LAYOUT_BTT;
  164. break;
  165. case 0x006C: /* 'l' */
  166. result = ULOC_LAYOUT_LTR;
  167. break;
  168. case 0x0072: /* 'r' */
  169. result = ULOC_LAYOUT_RTL;
  170. break;
  171. case 0x0074: /* 't' */
  172. result = ULOC_LAYOUT_TTB;
  173. break;
  174. default:
  175. status = U_INTERNAL_PROGRAM_ERROR;
  176. break;
  177. }
  178. }
  179. return result;
  180. }
  181. } // namespace
  182. U_CAPI ULayoutType U_EXPORT2
  183. uloc_getCharacterOrientation(const char* localeId,
  184. UErrorCode *status)
  185. {
  186. return _uloc_getOrientationHelper(localeId, "characters", *status);
  187. }
  188. /**
  189. * Get the layout line orientation for the specified locale.
  190. *
  191. * @param localeID locale name
  192. * @param status Error status
  193. * @return an enum indicating the layout orientation for lines.
  194. */
  195. U_CAPI ULayoutType U_EXPORT2
  196. uloc_getLineOrientation(const char* localeId,
  197. UErrorCode *status)
  198. {
  199. return _uloc_getOrientationHelper(localeId, "lines", *status);
  200. }