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