mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-20568 Improve MacroProps error handling.
In particular: actually handle Usage memory allocation errors. Also: correct Scale's error condition.
This commit is contained in:
parent
7888b23e87
commit
5ed09dc9b8
3 changed files with 44 additions and 17 deletions
|
@ -1547,7 +1547,7 @@ bool GeneratorHelpers::perUnit(const MacroProps& macros, UnicodeString& sb, UErr
|
|||
}
|
||||
|
||||
bool GeneratorHelpers::usage(const MacroProps& macros, UnicodeString& sb, UErrorCode& /* status */) {
|
||||
if (macros.usage.fLength > 0) {
|
||||
if (macros.usage.isSet()) {
|
||||
sb.append(u"usage/", -1);
|
||||
sb.append(UnicodeString(macros.usage.fUsage, -1, US_INV));
|
||||
return true;
|
||||
|
|
|
@ -28,21 +28,33 @@ using icu::StringSegment;
|
|||
using icu::units::ConversionRates;
|
||||
|
||||
// Copy constructor
|
||||
Usage::Usage(const Usage &other) : fUsage(nullptr), fLength(other.fLength), fError(other.fError) {
|
||||
if (other.fUsage != nullptr) {
|
||||
fUsage = (char *)uprv_malloc(fLength + 1);
|
||||
uprv_strncpy(fUsage, other.fUsage, fLength + 1);
|
||||
}
|
||||
Usage::Usage(const Usage &other) : Usage() {
|
||||
this->operator=(other);
|
||||
}
|
||||
|
||||
// Copy assignment operator
|
||||
Usage &Usage::operator=(const Usage &other) {
|
||||
fLength = other.fLength;
|
||||
if (other.fUsage != nullptr) {
|
||||
fUsage = (char *)uprv_malloc(fLength + 1);
|
||||
uprv_strncpy(fUsage, other.fUsage, fLength + 1);
|
||||
}
|
||||
fLength = 0;
|
||||
fError = other.fError;
|
||||
if (fUsage != nullptr) {
|
||||
uprv_free(fUsage);
|
||||
fUsage = nullptr;
|
||||
}
|
||||
if (other.fUsage == nullptr) {
|
||||
return *this;
|
||||
}
|
||||
if (U_FAILURE(other.fError)) {
|
||||
// We don't bother trying to allocating memory if we're in any case busy
|
||||
// copying an errored Usage.
|
||||
return *this;
|
||||
}
|
||||
fUsage = (char *)uprv_malloc(other.fLength + 1);
|
||||
if (fUsage == nullptr) {
|
||||
fError = U_MEMORY_ALLOCATION_ERROR;
|
||||
return *this;
|
||||
}
|
||||
fLength = other.fLength;
|
||||
uprv_strncpy(fUsage, other.fUsage, fLength + 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -82,6 +94,11 @@ void Usage::set(StringPiece value) {
|
|||
}
|
||||
fLength = value.length();
|
||||
fUsage = (char *)uprv_malloc(fLength + 1);
|
||||
if (fUsage == nullptr) {
|
||||
fLength = 0;
|
||||
fError = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
uprv_strncpy(fUsage, value.data(), fLength);
|
||||
fUsage[fLength] = 0;
|
||||
}
|
||||
|
|
|
@ -1094,7 +1094,7 @@ class U_I18N_API Scale : public UMemory {
|
|||
}
|
||||
|
||||
UBool copyErrorTo(UErrorCode &status) const {
|
||||
if (fError != U_ZERO_ERROR) {
|
||||
if (U_FAILURE(fError)) {
|
||||
status = fError;
|
||||
return true;
|
||||
}
|
||||
|
@ -1154,13 +1154,15 @@ class U_I18N_API Usage : public UMemory {
|
|||
int16_t length() const { return fLength; }
|
||||
|
||||
/** @internal
|
||||
* Makes a copy of value.
|
||||
* Makes a copy of value. Set to "" to unset.
|
||||
*/
|
||||
void set(StringPiece value);
|
||||
|
||||
/** @internal */
|
||||
bool isSet() const { return fLength > 0; }
|
||||
|
||||
#endif // U_HIDE_INTERNAL_API
|
||||
|
||||
private:
|
||||
char *fUsage;
|
||||
int16_t fLength;
|
||||
|
@ -1168,16 +1170,24 @@ class U_I18N_API Usage : public UMemory {
|
|||
|
||||
Usage() : fUsage(nullptr), fLength(0), fError(U_ZERO_ERROR) {}
|
||||
|
||||
/** @internal */
|
||||
UBool copyErrorTo(UErrorCode &status) const {
|
||||
if (U_FAILURE(fError)) {
|
||||
status = fError;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allow NumberFormatterImpl to access fUsage.
|
||||
friend class impl::NumberFormatterImpl;
|
||||
|
||||
// Allow skeleton generation code to access private members.
|
||||
friend class impl::GeneratorHelpers;
|
||||
|
||||
// Allow MacroProps/MicroProps to initialize empty instances.
|
||||
// Allow MacroProps/MicroProps to initialize empty instances and to call
|
||||
// copyErrorTo().
|
||||
friend struct impl::MacroProps;
|
||||
|
||||
#endif // U_HIDE_INTERNAL_API
|
||||
};
|
||||
|
||||
// Do not enclose entire SymbolsWrapper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
|
||||
|
@ -1487,7 +1497,7 @@ struct U_I18N_API MacroProps : public UMemory {
|
|||
bool copyErrorTo(UErrorCode &status) const {
|
||||
return notation.copyErrorTo(status) || precision.copyErrorTo(status) ||
|
||||
padder.copyErrorTo(status) || integerWidth.copyErrorTo(status) ||
|
||||
symbols.copyErrorTo(status) || scale.copyErrorTo(status);
|
||||
symbols.copyErrorTo(status) || scale.copyErrorTo(status) || usage.copyErrorTo(status);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue