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