Coverage Report

Created: 2025-06-24 06:43

/src/icu/source/i18n/units_data.h
Line
Count
Source (jump to first uncovered line)
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:
31
0
    ConversionRateInfo() {}
32
    ConversionRateInfo(StringPiece sourceUnit, StringPiece baseUnit, StringPiece factor,
33
                       StringPiece offset, UErrorCode &status)
34
0
        : sourceUnit(), baseUnit(), factor(), offset() {
35
0
        this->sourceUnit.append(sourceUnit, status);
36
0
        this->baseUnit.append(baseUnit, status);
37
0
        this->factor.append(factor, status);
38
0
        this->offset.append(offset, status);
39
0
    }
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
     */
80
0
    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
98
0
    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:
114
0
    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 */