locresdata.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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 "cstring.h"
  27. #include "ulocimp.h"
  28. #include "uresimp.h"
  29. /*
  30. * Lookup a resource bundle table item with fallback on the table level.
  31. * Regular resource bundle lookups perform fallback to parent locale bundles
  32. * and eventually the root bundle, but only for top-level items.
  33. * This function takes the name of a top-level table and of an item in that table
  34. * and performs a lookup of both, falling back until a bundle contains a table
  35. * with this item.
  36. *
  37. * Note: Only the opening of entire bundles falls back through the default locale
  38. * before root. Once a bundle is open, item lookups do not go through the
  39. * default locale because that would result in a mix of languages that is
  40. * unpredictable to the programmer and most likely useless.
  41. */
  42. U_CAPI const char16_t * U_EXPORT2
  43. uloc_getTableStringWithFallback(const char *path, const char *locale,
  44. const char *tableKey, const char *subTableKey,
  45. const char *itemKey,
  46. int32_t *pLength,
  47. UErrorCode *pErrorCode)
  48. {
  49. /* char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
  50. const char16_t *item=nullptr;
  51. UErrorCode errorCode;
  52. char explicitFallbackName[ULOC_FULLNAME_CAPACITY] = {0};
  53. /*
  54. * open the bundle for the current locale
  55. * this falls back through the locale's chain to root
  56. */
  57. errorCode=U_ZERO_ERROR;
  58. icu::LocalUResourceBundlePointer rb(ures_open(path, locale, &errorCode));
  59. if(U_FAILURE(errorCode)) {
  60. /* total failure, not even root could be opened */
  61. *pErrorCode=errorCode;
  62. return nullptr;
  63. } else if(errorCode==U_USING_DEFAULT_WARNING ||
  64. (errorCode==U_USING_FALLBACK_WARNING && *pErrorCode!=U_USING_DEFAULT_WARNING)
  65. ) {
  66. /* set the "strongest" error code (success->fallback->default->failure) */
  67. *pErrorCode=errorCode;
  68. }
  69. for(;;){
  70. icu::StackUResourceBundle table;
  71. icu::StackUResourceBundle subTable;
  72. ures_getByKeyWithFallback(rb.getAlias(), tableKey, table.getAlias(), &errorCode);
  73. if (subTableKey != nullptr) {
  74. /*
  75. ures_getByKeyWithFallback(table.getAlias(), subTableKey, subTable.getAlias(), &errorCode);
  76. item = ures_getStringByKeyWithFallback(subTable.getAlias(), itemKey, pLength, &errorCode);
  77. if(U_FAILURE(errorCode)){
  78. *pErrorCode = errorCode;
  79. }
  80. break;*/
  81. ures_getByKeyWithFallback(table.getAlias(), subTableKey, table.getAlias(), &errorCode);
  82. }
  83. if(U_SUCCESS(errorCode)){
  84. item = ures_getStringByKeyWithFallback(table.getAlias(), itemKey, pLength, &errorCode);
  85. if(U_FAILURE(errorCode)){
  86. const char* replacement = nullptr;
  87. *pErrorCode = errorCode; /*save the errorCode*/
  88. errorCode = U_ZERO_ERROR;
  89. /* may be a deprecated code */
  90. if(uprv_strcmp(tableKey, "Countries")==0){
  91. replacement = uloc_getCurrentCountryID(itemKey);
  92. }else if(uprv_strcmp(tableKey, "Languages")==0){
  93. replacement = uloc_getCurrentLanguageID(itemKey);
  94. }
  95. /*pointer comparison is ok since uloc_getCurrentCountryID & uloc_getCurrentLanguageID return the key itself is replacement is not found*/
  96. if(replacement!=nullptr && itemKey != replacement){
  97. item = ures_getStringByKeyWithFallback(table.getAlias(), replacement, pLength, &errorCode);
  98. if(U_SUCCESS(errorCode)){
  99. *pErrorCode = errorCode;
  100. break;
  101. }
  102. }
  103. }else{
  104. break;
  105. }
  106. }
  107. if(U_FAILURE(errorCode)){
  108. /* still can't figure out ?.. try the fallback mechanism */
  109. int32_t len = 0;
  110. const char16_t* fallbackLocale = nullptr;
  111. *pErrorCode = errorCode;
  112. errorCode = U_ZERO_ERROR;
  113. fallbackLocale = ures_getStringByKeyWithFallback(table.getAlias(), "Fallback", &len, &errorCode);
  114. if(U_FAILURE(errorCode)){
  115. *pErrorCode = errorCode;
  116. break;
  117. }
  118. u_UCharsToChars(fallbackLocale, explicitFallbackName, len);
  119. /* guard against recursive fallback */
  120. if(uprv_strcmp(explicitFallbackName, locale)==0){
  121. *pErrorCode = U_INTERNAL_PROGRAM_ERROR;
  122. break;
  123. }
  124. rb.adoptInstead(ures_open(path, explicitFallbackName, &errorCode));
  125. if(U_FAILURE(errorCode)){
  126. *pErrorCode = errorCode;
  127. break;
  128. }
  129. /* succeeded in opening the fallback bundle .. continue and try to fetch the item */
  130. }else{
  131. break;
  132. }
  133. }
  134. return item;
  135. }
  136. static ULayoutType
  137. _uloc_getOrientationHelper(const char* localeId,
  138. const char* key,
  139. UErrorCode *status)
  140. {
  141. ULayoutType result = ULOC_LAYOUT_UNKNOWN;
  142. if (!U_FAILURE(*status)) {
  143. int32_t length = 0;
  144. char localeBuffer[ULOC_FULLNAME_CAPACITY];
  145. uloc_canonicalize(localeId, localeBuffer, sizeof(localeBuffer), status);
  146. if (!U_FAILURE(*status)) {
  147. const char16_t* const value =
  148. uloc_getTableStringWithFallback(
  149. nullptr,
  150. localeBuffer,
  151. "layout",
  152. nullptr,
  153. key,
  154. &length,
  155. status);
  156. if (!U_FAILURE(*status) && length != 0) {
  157. switch(value[0])
  158. {
  159. case 0x0062: /* 'b' */
  160. result = ULOC_LAYOUT_BTT;
  161. break;
  162. case 0x006C: /* 'l' */
  163. result = ULOC_LAYOUT_LTR;
  164. break;
  165. case 0x0072: /* 'r' */
  166. result = ULOC_LAYOUT_RTL;
  167. break;
  168. case 0x0074: /* 't' */
  169. result = ULOC_LAYOUT_TTB;
  170. break;
  171. default:
  172. *status = U_INTERNAL_PROGRAM_ERROR;
  173. break;
  174. }
  175. }
  176. }
  177. }
  178. return result;
  179. }
  180. U_CAPI ULayoutType U_EXPORT2
  181. uloc_getCharacterOrientation(const char* localeId,
  182. UErrorCode *status)
  183. {
  184. return _uloc_getOrientationHelper(localeId, "characters", status);
  185. }
  186. /**
  187. * Get the layout line orientation for the specified locale.
  188. *
  189. * @param localeID locale name
  190. * @param status Error status
  191. * @return an enum indicating the layout orientation for lines.
  192. */
  193. U_CAPI ULayoutType U_EXPORT2
  194. uloc_getLineOrientation(const char* localeId,
  195. UErrorCode *status)
  196. {
  197. return _uloc_getOrientationHelper(localeId, "lines", status);
  198. }