number_asformat.cpp (4153B)
1 // © 2018 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 8 // Allow implicit conversion from char16_t* to UnicodeString for this file: 9 // Helpful in toString methods and elsewhere. 10 #define UNISTR_FROM_STRING_EXPLICIT 11 12 #include <stdlib.h> 13 #include <cmath> 14 #include "number_asformat.h" 15 #include "number_types.h" 16 #include "number_utils.h" 17 #include "fphdlimp.h" 18 #include "number_utypes.h" 19 20 using namespace icu; 21 using namespace icu::number; 22 using namespace icu::number::impl; 23 24 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocalizedNumberFormatterAsFormat) 25 26 LocalizedNumberFormatterAsFormat::LocalizedNumberFormatterAsFormat( 27 const LocalizedNumberFormatter& formatter, const Locale& locale) 28 : fFormatter(formatter), fLocale(locale) { 29 const char* localeName = locale.getName(); 30 setLocaleIDs(localeName, localeName); 31 } 32 33 LocalizedNumberFormatterAsFormat::~LocalizedNumberFormatterAsFormat() = default; 34 35 bool LocalizedNumberFormatterAsFormat::operator==(const Format& other) const { 36 const auto* _other = dynamic_cast<const LocalizedNumberFormatterAsFormat*>(&other); 37 if (_other == nullptr) { 38 return false; 39 } 40 // TODO: Change this to use LocalizedNumberFormatter::operator== if it is ever proposed. 41 // This implementation is fine, but not particularly efficient. 42 UErrorCode localStatus = U_ZERO_ERROR; 43 return fFormatter.toSkeleton(localStatus) == _other->fFormatter.toSkeleton(localStatus); 44 } 45 46 LocalizedNumberFormatterAsFormat* LocalizedNumberFormatterAsFormat::clone() const { 47 return new LocalizedNumberFormatterAsFormat(*this); 48 } 49 50 UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj, UnicodeString& appendTo, 51 FieldPosition& pos, UErrorCode& status) const { 52 if (U_FAILURE(status)) { return appendTo; } 53 UFormattedNumberData data; 54 obj.populateDecimalQuantity(data.quantity, status); 55 if (U_FAILURE(status)) { 56 return appendTo; 57 } 58 fFormatter.formatImpl(&data, status); 59 if (U_FAILURE(status)) { 60 return appendTo; 61 } 62 // always return first occurrence: 63 pos.setBeginIndex(0); 64 pos.setEndIndex(0); 65 bool found = data.nextFieldPosition(pos, status); 66 if (found && appendTo.length() != 0) { 67 pos.setBeginIndex(pos.getBeginIndex() + appendTo.length()); 68 pos.setEndIndex(pos.getEndIndex() + appendTo.length()); 69 } 70 appendTo.append(data.toTempString(status)); 71 return appendTo; 72 } 73 74 UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj, UnicodeString& appendTo, 75 FieldPositionIterator* posIter, 76 UErrorCode& status) const { 77 if (U_FAILURE(status)) { return appendTo; } 78 UFormattedNumberData data; 79 obj.populateDecimalQuantity(data.quantity, status); 80 if (U_FAILURE(status)) { 81 return appendTo; 82 } 83 fFormatter.formatImpl(&data, status); 84 if (U_FAILURE(status)) { 85 return appendTo; 86 } 87 appendTo.append(data.toTempString(status)); 88 if (posIter != nullptr) { 89 FieldPositionIteratorHandler fpih(posIter, status); 90 data.getAllFieldPositions(fpih, status); 91 } 92 return appendTo; 93 } 94 95 void LocalizedNumberFormatterAsFormat::parseObject(const UnicodeString&, Formattable&, 96 ParsePosition& parse_pos) const { 97 // Not supported. 98 parse_pos.setErrorIndex(0); 99 } 100 101 const LocalizedNumberFormatter& LocalizedNumberFormatterAsFormat::getNumberFormatter() const { 102 return fFormatter; 103 } 104 105 106 // Definitions of public API methods (put here for dependency disentanglement) 107 108 Format* LocalizedNumberFormatter::toFormat(UErrorCode& status) const { 109 if (U_FAILURE(status)) { 110 return nullptr; 111 } 112 LocalPointer<LocalizedNumberFormatterAsFormat> retval( 113 new LocalizedNumberFormatterAsFormat(*this, fMacros.locale), status); 114 return retval.orphan(); 115 } 116 117 #endif /* #if !UCONFIG_NO_FORMATTING */