• 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 };
103 
104 /**
105  * Metadata about the preferences in UnitPreferences::unitPrefs_.
106  *
107  * This class owns all of its data.
108  *
109  * UnitPreferenceMetadata lives in the anonymous namespace, because it should
110  * only be useful to internal code and unit testing code.
111  */
112 class U_I18N_API UnitPreferenceMetadata : public UMemory {
113   public:
UnitPreferenceMetadata()114     UnitPreferenceMetadata() {}
115     // Constructor, makes copies of the parameters passed to it.
116     UnitPreferenceMetadata(StringPiece category, StringPiece usage, StringPiece region,
117                            int32_t prefsOffset, int32_t prefsCount, UErrorCode &status);
118 
119     // Unit category (e.g. "length", "mass", "electric-capacitance").
120     CharString category;
121     // Usage (e.g. "road", "vehicle-fuel", "blood-glucose"). Every category
122     // should have an entry for "default" usage. TODO(hugovdm): add a test for
123     // this.
124     CharString usage;
125     // Region code (e.g. "US", "CZ", "001"). Every usage should have an entry
126     // for the "001" region ("world"). TODO(hugovdm): add a test for this.
127     CharString region;
128     // Offset into the UnitPreferences::unitPrefs_ list where the relevant
129     // preferences are found.
130     int32_t prefsOffset;
131     // The number of preferences that form this set.
132     int32_t prefsCount;
133 
134     int32_t compareTo(const UnitPreferenceMetadata &other) const;
135     int32_t compareTo(const UnitPreferenceMetadata &other, bool *foundCategory, bool *foundUsage,
136                       bool *foundRegion) const;
137 };
138 
139 } // namespace units
140 
141 // Export explicit template instantiations of MaybeStackArray, MemoryPool and
142 // MaybeStackVector. This is required when building DLLs for Windows. (See
143 // datefmt.h, collationiterator.h, erarules.h and others for similar examples.)
144 //
145 // Note: These need to be outside of the units namespace, or Clang will generate
146 // a compile error.
147 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
148 template class U_I18N_API MaybeStackArray<units::UnitPreferenceMetadata*, 8>;
149 template class U_I18N_API MemoryPool<units::UnitPreferenceMetadata, 8>;
150 template class U_I18N_API MaybeStackVector<units::UnitPreferenceMetadata, 8>;
151 template class U_I18N_API MaybeStackArray<units::UnitPreference*, 8>;
152 template class U_I18N_API MemoryPool<units::UnitPreference, 8>;
153 template class U_I18N_API MaybeStackVector<units::UnitPreference, 8>;
154 #endif
155 
156 namespace units {
157 
158 /**
159  * Unit Preferences information for various locales and usages.
160  */
161 class U_I18N_API UnitPreferences {
162   public:
163     /**
164      * Constructor, loads all the preference data.
165      *
166      * @param status Receives status.
167      */
168     UnitPreferences(UErrorCode &status);
169 
170     /**
171      * Returns the set of unit preferences in the particular category that best
172      * matches the specified usage and region.
173      *
174      * If region can't be found, falls back to global (001). If usage can't be
175      * found, falls back to "default".
176      *
177      * @param category The category within which to look up usage and region.
178      * (TODO(hugovdm): improve docs on how to find the category, once the lookup
179      * function is added.)
180      * @param usage The usage parameter. (TODO(hugovdm): improve this
181      * documentation. Add reference to some list of usages we support.) If the
182      * given usage is not found, the method automatically falls back to
183      * "default".
184      * @param region The region whose preferences are desired. If there are no
185      * specific preferences for the requested region, the method automatically
186      * falls back to region "001" ("world").
187      * @param outPreferences A pointer into an array of preferences: essentially
188      * an array slice in combination with preferenceCount.
189      * @param preferenceCount The number of unit preferences that belong to the
190      * result set.
191      * @param status Receives status.
192      *
193      * TODO(hugovdm): maybe replace `UnitPreference **&outPreferences` with a slice class?
194      */
195     void getPreferencesFor(StringPiece category, StringPiece usage, StringPiece region,
196                            const UnitPreference *const *&outPreferences, int32_t &preferenceCount,
197                            UErrorCode &status) const;
198 
199   protected:
200     // Metadata about the sets of preferences, this is the index for looking up
201     // preferences in the unitPrefs_ list.
202     MaybeStackVector<UnitPreferenceMetadata> metadata_;
203     // All the preferences as a flat list: which usage and region preferences
204     // are associated with is stored in `metadata_`.
205     MaybeStackVector<UnitPreference> unitPrefs_;
206 };
207 
208 } // namespace units
209 U_NAMESPACE_END
210 
211 #endif //__UNITS_DATA_H__
212 
213 #endif /* #if !UCONFIG_NO_FORMATTING */
214