| // © 2020 and later: Unicode, Inc. and others. |
| // License & terms of use: http://www.unicode.org/copyright.html |
| |
| #include "unicode/utypes.h" |
| |
| #if !UCONFIG_NO_FORMATTING |
| #ifndef __UNITS_DATA_H__ |
| #define __UNITS_DATA_H__ |
| |
| #include <limits> |
| |
| #include "charstr.h" |
| #include "cmemory.h" |
| #include "unicode/stringpiece.h" |
| #include "unicode/uobject.h" |
| |
| U_NAMESPACE_BEGIN |
| namespace units { |
| |
| /** |
| * Looks up the unit category of a base unit identifier. |
| * |
| * Only supports base units, other units must be resolved to base units before |
| * passing to this function. |
| * |
| * Categories are found in `unitQuantities` in the `units` resource (see |
| * `units.txt`). |
| * |
| * TODO(hugovdm): if we give units_data.cpp access to the functionality of |
| * `extractCompoundBaseUnit` which is currently in units_converter.cpp, we could |
| * support all units for which there is a category. Does it make sense to move |
| * that function to units_data.cpp? |
| */ |
| CharString U_I18N_API getUnitCategory(const char *baseUnitIdentifier, UErrorCode &status); |
| |
| /** |
| * 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; |
| }; |
| |
| } // 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; |
| }; |
| |
| /** |
| * 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. |
| * |
| * TODO(hugovdm): maybe replace `UnitPreference **&outPreferences` with a slice class? |
| */ |
| void getPreferencesFor(StringPiece category, StringPiece usage, StringPiece region, |
| const UnitPreference *const *&outPreferences, int32_t &preferenceCount, |
| 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 */ |