/src/icu/icu4c/source/i18n/units_data.h
Line | Count | Source |
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 | 15.5k | ConversionRateInfo() {} |
33 | | ConversionRateInfo(StringPiece sourceUnit, StringPiece baseUnit, StringPiece factor, |
34 | | StringPiece offset, UErrorCode &status) |
35 | | : sourceUnit(sourceUnit), baseUnit(baseUnit), factor(factor), offset(offset), |
36 | 0 | specialMappingName(), systems() { |
37 | 0 | if (this->sourceUnit.isEmpty() != sourceUnit.empty() || |
38 | 0 | this->baseUnit.isEmpty() != baseUnit.empty() || |
39 | 0 | this->factor.isEmpty() != factor.empty() || |
40 | 0 | this->offset.isEmpty() != offset.empty()) { |
41 | 0 | status = U_MEMORY_ALLOCATION_ERROR; |
42 | 0 | } |
43 | 0 | } |
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 | 100 | 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 | 28.6k | UnitPreference() : geq(1.0) {} |
89 | | FixedString unit; |
90 | | double geq; |
91 | | UnicodeString skeleton; |
92 | | |
93 | 0 | UnitPreference(const UnitPreference &other) { |
94 | 0 | this->unit = other.unit; |
95 | 0 | this->geq = other.geq; |
96 | 0 | this->skeleton = other.skeleton; |
97 | 0 | } |
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 | 0 | 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 */ |