Coverage Report

Created: 2025-06-13 06:38

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