Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(219)

Unified Diff: icu4c/source/i18n/numparse_currency.cpp

Issue 339630043: ticket:13736 Change number parsing to require locale currency when using non-currency parse functio… (Closed) Base URL: svn+icussh://source.icu-project.org/repos/icu/trunk/
Patch Set: Porting to ICU4C and adding locale long name parsing as alternative to currency data parsing. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « icu4c/source/i18n/numparse_currency.h ('k') | icu4c/source/i18n/numparse_impl.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: icu4c/source/i18n/numparse_currency.cpp
===================================================================
--- icu4c/source/i18n/numparse_currency.cpp (revision 41389)
+++ icu4c/source/i18n/numparse_currency.cpp (working copy)
@@ -20,15 +20,25 @@
using namespace icu::numparse::impl;
-CombinedCurrencyMatcher::CombinedCurrencyMatcher(const CurrencySymbols& currencySymbols,
- const DecimalFormatSymbols& dfs, UErrorCode& status)
+CombinedCurrencyMatcher::CombinedCurrencyMatcher(const CurrencySymbols& currencySymbols, const DecimalFormatSymbols& dfs,
+ parse_flags_t parseFlags, UErrorCode& status)
: fCurrency1(currencySymbols.getCurrencySymbol(status)),
fCurrency2(currencySymbols.getIntlCurrencySymbol(status)),
+ fUseFullCurrencyData(0 == (parseFlags & PARSE_FLAG_NO_FOREIGN_CURRENCY)),
afterPrefixInsert(dfs.getPatternForCurrencySpacing(UNUM_CURRENCY_INSERT, false, status)),
beforeSuffixInsert(dfs.getPatternForCurrencySpacing(UNUM_CURRENCY_INSERT, true, status)),
fLocaleName(dfs.getLocale().getName(), -1, status) {
utils::copyCurrencyCode(fCurrencyCode, currencySymbols.getIsoCode());
+ // Pre-load the long names for the current locale and currency
+ // if we are parsing without the full currency data.
+ if (!fUseFullCurrencyData) {
+ for (int32_t i=0; i<StandardPlural::COUNT; i++) {
+ auto plural = static_cast<StandardPlural::Form>(i);
+ fLocalLongNames[i] = currencySymbols.getPluralName(plural, status);
+ }
+ }
+
// TODO: Figure out how to make this faster and re-enable.
// Computing the "lead code points" set for fastpathing is too slow to use in production.
// See http://bugs.icu-project.org/trac/ticket/13584
@@ -83,47 +93,73 @@
bool CombinedCurrencyMatcher::matchCurrency(StringSegment& segment, ParsedNumber& result,
UErrorCode& status) const {
+ bool maybeMore = false;
int32_t overlap1 = segment.getCaseSensitivePrefixLength(fCurrency1);
+ maybeMore = maybeMore || overlap1 == segment.length();
if (overlap1 == fCurrency1.length()) {
utils::copyCurrencyCode(result.currencyCode, fCurrencyCode);
segment.adjustOffset(overlap1);
result.setCharsConsumed(segment);
- return segment.length() == 0;
+ return maybeMore;
}
int32_t overlap2 = segment.getCaseSensitivePrefixLength(fCurrency2);
+ maybeMore = maybeMore || overlap2 == segment.length();
if (overlap2 == fCurrency2.length()) {
utils::copyCurrencyCode(result.currencyCode, fCurrencyCode);
segment.adjustOffset(overlap2);
result.setCharsConsumed(segment);
- return segment.length() == 0;
+ return maybeMore;
}
- // NOTE: This call site should be improved with #13584.
- const UnicodeString segmentString = segment.toTempUnicodeString();
+ if (fUseFullCurrencyData) {
+ // Use the full currency data.
+ // NOTE: This call site should be improved with #13584.
+ const UnicodeString segmentString = segment.toTempUnicodeString();
- // Try to parse the currency
- ParsePosition ppos(0);
- int32_t partialMatchLen = 0;
- uprv_parseCurrency(
- fLocaleName.data(),
- segmentString,
- ppos,
- UCURR_SYMBOL_NAME, // checks for both UCURR_SYMBOL_NAME and UCURR_LONG_NAME
- &partialMatchLen,
- result.currencyCode,
- status);
+ // Try to parse the currency
+ ParsePosition ppos(0);
+ int32_t partialMatchLen = 0;
+ uprv_parseCurrency(
+ fLocaleName.data(),
+ segmentString,
+ ppos,
+ UCURR_SYMBOL_NAME, // checks for both UCURR_SYMBOL_NAME and UCURR_LONG_NAME
+ &partialMatchLen,
+ result.currencyCode,
+ status);
+ maybeMore = maybeMore || partialMatchLen == segment.length();
- if (U_SUCCESS(status) && ppos.getIndex() != 0) {
- // Complete match.
- // NOTE: The currency code should already be saved in the ParsedNumber.
- segment.adjustOffset(ppos.getIndex());
- result.setCharsConsumed(segment);
+ if (U_SUCCESS(status) && ppos.getIndex() != 0) {
+ // Complete match.
+ // NOTE: The currency code should already be saved in the ParsedNumber.
+ segment.adjustOffset(ppos.getIndex());
+ result.setCharsConsumed(segment);
+ return maybeMore;
+ }
+
+ } else {
+ // Use the locale long names.
+ int32_t longestFullMatch = 0;
+ for (int32_t i=0; i<StandardPlural::COUNT; i++) {
+ const UnicodeString& name = fLocalLongNames[i];
+ int32_t overlap = segment.getCommonPrefixLength(name);
+ if (overlap == name.length() && name.length() > longestFullMatch) {
+ longestFullMatch = name.length();
+ }
+ maybeMore = maybeMore || overlap > 0;
+ }
+ if (longestFullMatch > 0) {
+ utils::copyCurrencyCode(result.currencyCode, fCurrencyCode);
+ segment.adjustOffset(longestFullMatch);
+ result.setCharsConsumed(segment);
+ return maybeMore;
+ }
}
- return overlap1 == segment.length() || overlap2 == segment.length() ||
- partialMatchLen == segment.length();
+ // No match found.
+ return maybeMore;
}
bool CombinedCurrencyMatcher::smokeTest(const StringSegment&) const {
« no previous file with comments | « icu4c/source/i18n/numparse_currency.h ('k') | icu4c/source/i18n/numparse_impl.cpp » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b