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