Skip to content

Conversation

@jowilco
Copy link
Contributor

@jowilco jowilco commented Sep 26, 2020

Checklist

@sffc sffc added the after-release Do not merge until after an upcoming release or at least until its maintenance branch has been cut. label Sep 29, 2020
@sffc sffc self-assigned this Jan 13, 2021
@sffc sffc self-requested a review January 13, 2021 02:15
Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, and sorry for the very much delayed review!

We need to think more about the lifecycle of the CurrencyDisplayNames objects. Who owns them? If you request one from the same locale multiple times in a row, are they saved in a cache? Although I don't generally like caches, I think this is a case where we might want to consider pulling in the UnifiedCache.

if (pluralCategory == PluralMapBase::NONE) {
errorCode = U_UNSUPPORTED_ERROR;
}
if (uhash_get(pluralsData->pluralsStringTable, (int32_t *)pluralCategory) == NULL) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can unconditionally set the hashtable key here. The keys in pluralsTable will be unique.

UBool isMissing = false;
UHashtable *pluralsStringTable = nullptr;

PluralsData(const UChar *isoCode) : isoCode(isoCode) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please either:

  1. Change the type of the UHashtable field to LocalUHashtablePointer
  2. Keep the type as UHashtable but add a destructor to close the UHashtable

CurrencyDisplayNames *instance = currencyDisplayDataCache;
if (instance == nullptr || strcmp((instance->locale)->getName(), loc->getName()) != 0 ||
instance->noSubstitute != noSubstitute) {
Locale *internalLocale;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stack-allocate the Locale.

return getInstance(loc, false, errorCode);
}

const CurrencyDisplayNames *CurrencyDisplayNames::getInstance(const Locale *loc, UBool noSubstitute,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and elsewhere: I would take a Locale by const reference, not const pointer

internalLocale = new Locale(*loc);
}
UErrorCode ec2 = U_ZERO_ERROR;
UResourceBundle *currencyResources = ures_open(U_ICUDATA_CURR, internalLocale->getName(), &ec2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a LocalUResourceBundlePointer

return nullptr;
}
instance = new CurrencyDisplayNames(internalLocale, currencyResources, noSubstitute);
currencyDisplayDataCache = instance;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line isn't thread-safe. You also need to delete the old instance if present.


const Locale *CurrencyDisplayNames::getLocale() { return locale; }

const UChar *CurrencyDisplayNames::getName(const UChar *isoCode, UErrorCode &errorCode) const {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and elsewhere: Why not return the data as a UnicodeString? It makes it easier to reason about who owns the data.

return getNarrowSymbol(isoCode, errorCode);
case UCURR_FORMAL_SYMBOL_NAME:
return getFormalSymbol(isoCode, errorCode);
case UCURR_VARIANT_SYMBOL_NAME:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we intend to add the formal symbol here?

return ((UnicodeString *)result)->getBuffer();
}

FormattingData *CurrencyDisplayNames::fetchFormattingData(const UChar *isoCode,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and on the following two functions: who owns the return value?

} else {
errorCode = ec2;
}
formattingDataCache = result;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and on the following two functions: this isn't thread-safe, and you need to delete the value previously in the static 1-element cache.

Base automatically changed from master to main March 24, 2021 17:56
@sffc
Copy link
Member

sffc commented Apr 24, 2021

(Closing and opening the PR to trigger fresh CI)

@sffc sffc closed this Apr 24, 2021
@sffc sffc reopened this Apr 24, 2021
@sffc
Copy link
Member

sffc commented May 1, 2021

You currently have the following build error:

../../lib/libicuuc.so: undefined reference to `icu_69::CurrencyDisplayNames::getName(char16_t const*, UCurrNameStyle, UErrorCode&) const'
../../lib/libicui18n.so: undefined reference to `icu_69::CurrencyDisplayNames::getPluralName(char16_t const*, icu_69::PluralMapBase::Category, UErrorCode&) const'
../../lib/libicui18n.so: undefined reference to `icu_69::CurrencyDisplayNames::getInstance(icu_69::Locale const*, UErrorCode&)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Makefile:81: recipe for target '../../bin/makeconv' failed

That error usually means either you haven't defined the functions, or you haven't told the compiler where to find them. I think you're in the second case. You added "currencydisplaynames.cpp" to the vcxproj files, but you also need to add it to the file icu4c/source/common/sources.txt for Unixy systems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

after-release Do not merge until after an upcoming release or at least until its maintenance branch has been cut.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants