units_data.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // © 2020 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. #include "unicode/utypes.h"
  4. #if !UCONFIG_NO_FORMATTING
  5. #ifndef __UNITS_DATA_H__
  6. #define __UNITS_DATA_H__
  7. #include <limits>
  8. #include "charstr.h"
  9. #include "cmemory.h"
  10. #include "unicode/stringpiece.h"
  11. #include "unicode/uobject.h"
  12. U_NAMESPACE_BEGIN
  13. namespace units {
  14. /**
  15. * Encapsulates "convertUnits" information from units resources, specifying how
  16. * to convert from one unit to another.
  17. *
  18. * Information in this class is still in the form of strings: symbolic constants
  19. * need to be interpreted. Rationale: symbols can cancel out for higher
  20. * precision conversion - going from feet to inches should cancel out the
  21. * `ft_to_m` constant.
  22. */
  23. class U_I18N_API ConversionRateInfo : public UMemory {
  24. public:
  25. ConversionRateInfo() {}
  26. ConversionRateInfo(StringPiece sourceUnit, StringPiece baseUnit, StringPiece factor,
  27. StringPiece offset, UErrorCode &status)
  28. : sourceUnit(), baseUnit(), factor(), offset() {
  29. this->sourceUnit.append(sourceUnit, status);
  30. this->baseUnit.append(baseUnit, status);
  31. this->factor.append(factor, status);
  32. this->offset.append(offset, status);
  33. }
  34. CharString sourceUnit;
  35. CharString baseUnit;
  36. CharString factor;
  37. CharString offset;
  38. };
  39. } // namespace units
  40. // Export explicit template instantiations of MaybeStackArray, MemoryPool and
  41. // MaybeStackVector. This is required when building DLLs for Windows. (See
  42. // datefmt.h, collationiterator.h, erarules.h and others for similar examples.)
  43. //
  44. // Note: These need to be outside of the units namespace, or Clang will generate
  45. // a compile error.
  46. #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
  47. template class U_I18N_API MaybeStackArray<units::ConversionRateInfo*, 8>;
  48. template class U_I18N_API MemoryPool<units::ConversionRateInfo, 8>;
  49. template class U_I18N_API MaybeStackVector<units::ConversionRateInfo, 8>;
  50. #endif
  51. namespace units {
  52. /**
  53. * Returns ConversionRateInfo for all supported conversions.
  54. *
  55. * @param result Receives the set of conversion rates.
  56. * @param status Receives status.
  57. */
  58. void U_I18N_API getAllConversionRates(MaybeStackVector<ConversionRateInfo> &result, UErrorCode &status);
  59. /**
  60. * Contains all the supported conversion rates.
  61. */
  62. class U_I18N_API ConversionRates {
  63. public:
  64. /**
  65. * Constructor
  66. *
  67. * @param status Receives status.
  68. */
  69. ConversionRates(UErrorCode &status) { getAllConversionRates(conversionInfo_, status); }
  70. /**
  71. * Returns a pointer to the conversion rate info that match the `source`.
  72. *
  73. * @param source Contains the source.
  74. * @param status Receives status.
  75. */
  76. const ConversionRateInfo *extractConversionInfo(StringPiece source, UErrorCode &status) const;
  77. private:
  78. MaybeStackVector<ConversionRateInfo> conversionInfo_;
  79. };
  80. // Encapsulates unitPreferenceData information from units resources, specifying
  81. // a sequence of output unit preferences.
  82. struct U_I18N_API UnitPreference : public UMemory {
  83. // Set geq to 1.0 by default
  84. UnitPreference() : geq(1.0) {}
  85. CharString unit;
  86. double geq;
  87. UnicodeString skeleton;
  88. UnitPreference(const UnitPreference &other) {
  89. UErrorCode status = U_ZERO_ERROR;
  90. this->unit.append(other.unit, status);
  91. this->geq = other.geq;
  92. this->skeleton = other.skeleton;
  93. }
  94. };
  95. /**
  96. * Metadata about the preferences in UnitPreferences::unitPrefs_.
  97. *
  98. * This class owns all of its data.
  99. *
  100. * UnitPreferenceMetadata lives in the anonymous namespace, because it should
  101. * only be useful to internal code and unit testing code.
  102. */
  103. class U_I18N_API UnitPreferenceMetadata : public UMemory {
  104. public:
  105. UnitPreferenceMetadata() {}
  106. // Constructor, makes copies of the parameters passed to it.
  107. UnitPreferenceMetadata(StringPiece category, StringPiece usage, StringPiece region,
  108. int32_t prefsOffset, int32_t prefsCount, UErrorCode &status);
  109. // Unit category (e.g. "length", "mass", "electric-capacitance").
  110. CharString category;
  111. // Usage (e.g. "road", "vehicle-fuel", "blood-glucose"). Every category
  112. // should have an entry for "default" usage. TODO(hugovdm): add a test for
  113. // this.
  114. CharString usage;
  115. // Region code (e.g. "US", "CZ", "001"). Every usage should have an entry
  116. // for the "001" region ("world"). TODO(hugovdm): add a test for this.
  117. CharString region;
  118. // Offset into the UnitPreferences::unitPrefs_ list where the relevant
  119. // preferences are found.
  120. int32_t prefsOffset;
  121. // The number of preferences that form this set.
  122. int32_t prefsCount;
  123. int32_t compareTo(const UnitPreferenceMetadata &other) const;
  124. int32_t compareTo(const UnitPreferenceMetadata &other, bool *foundCategory, bool *foundUsage,
  125. bool *foundRegion) const;
  126. };
  127. } // namespace units
  128. // Export explicit template instantiations of MaybeStackArray, MemoryPool and
  129. // MaybeStackVector. This is required when building DLLs for Windows. (See
  130. // datefmt.h, collationiterator.h, erarules.h and others for similar examples.)
  131. //
  132. // Note: These need to be outside of the units namespace, or Clang will generate
  133. // a compile error.
  134. #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
  135. template class U_I18N_API MaybeStackArray<units::UnitPreferenceMetadata*, 8>;
  136. template class U_I18N_API MemoryPool<units::UnitPreferenceMetadata, 8>;
  137. template class U_I18N_API MaybeStackVector<units::UnitPreferenceMetadata, 8>;
  138. template class U_I18N_API MaybeStackArray<units::UnitPreference*, 8>;
  139. template class U_I18N_API MemoryPool<units::UnitPreference, 8>;
  140. template class U_I18N_API MaybeStackVector<units::UnitPreference, 8>;
  141. #endif
  142. namespace units {
  143. /**
  144. * Unit Preferences information for various locales and usages.
  145. */
  146. class U_I18N_API UnitPreferences {
  147. public:
  148. /**
  149. * Constructor, loads all the preference data.
  150. *
  151. * @param status Receives status.
  152. */
  153. UnitPreferences(UErrorCode &status);
  154. /**
  155. * Returns the set of unit preferences in the particular category that best
  156. * matches the specified usage and region.
  157. *
  158. * If region can't be found, falls back to global (001). If usage can't be
  159. * found, falls back to "default".
  160. *
  161. * @param category The category within which to look up usage and region.
  162. * (TODO(hugovdm): improve docs on how to find the category, once the lookup
  163. * function is added.)
  164. * @param usage The usage parameter. (TODO(hugovdm): improve this
  165. * documentation. Add reference to some list of usages we support.) If the
  166. * given usage is not found, the method automatically falls back to
  167. * "default".
  168. * @param region The region whose preferences are desired. If there are no
  169. * specific preferences for the requested region, the method automatically
  170. * falls back to region "001" ("world").
  171. * @param outPreferences A pointer into an array of preferences: essentially
  172. * an array slice in combination with preferenceCount.
  173. * @param preferenceCount The number of unit preferences that belong to the
  174. * result set.
  175. * @param status Receives status.
  176. */
  177. MaybeStackVector<UnitPreference> getPreferencesFor(StringPiece category, StringPiece usage,
  178. const Locale &locale,
  179. UErrorCode &status) const;
  180. protected:
  181. // Metadata about the sets of preferences, this is the index for looking up
  182. // preferences in the unitPrefs_ list.
  183. MaybeStackVector<UnitPreferenceMetadata> metadata_;
  184. // All the preferences as a flat list: which usage and region preferences
  185. // are associated with is stored in `metadata_`.
  186. MaybeStackVector<UnitPreference> unitPrefs_;
  187. };
  188. } // namespace units
  189. U_NAMESPACE_END
  190. #endif //__UNITS_DATA_H__
  191. #endif /* #if !UCONFIG_NO_FORMATTING */