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