Coverage Report

Created: 2026-05-06 06:16

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