summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilip Navara <filip.navara@gmail.com>2019-02-03 03:37:19 +0100
committerFilip Navara <filip.navara@gmail.com>2019-02-03 11:18:03 +0100
commit91df8d26a01cc50672ac4f7f71359cd19e8e2db2 (patch)
treee4d0219a5a3cd019029c4f20ecb1ec10ae9bc22c
parent1edbceb16f7f54c535d4a8416cf2c34691e484bc (diff)
downloadcoreclr-91df8d26a01cc50672ac4f7f71359cd19e8e2db2.tar.gz
coreclr-91df8d26a01cc50672ac4f7f71359cd19e8e2db2.tar.bz2
coreclr-91df8d26a01cc50672ac4f7f71359cd19e8e2db2.zip
Avoid memory allocation in EnumSymbols for small buffers
-rw-r--r--src/corefx/System.Globalization.Native/pal_calendarData.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/src/corefx/System.Globalization.Native/pal_calendarData.c b/src/corefx/System.Globalization.Native/pal_calendarData.c
index 8e14d8b556..12b735d1b2 100644
--- a/src/corefx/System.Globalization.Native/pal_calendarData.c
+++ b/src/corefx/System.Globalization.Native/pal_calendarData.c
@@ -319,39 +319,44 @@ bool EnumSymbols(const char* locale,
udat_setCalendar(pFormat, pCalendar);
int32_t symbolCount = udat_countSymbols(pFormat, type);
+ UChar stackSymbolBuf[100];
+ UChar* symbolBuf;
- for (int32_t i = startIndex; i < symbolCount; i++)
+ for (int32_t i = startIndex; U_SUCCESS(err) && i < symbolCount; i++)
{
UErrorCode ignore = U_ZERO_ERROR;
int symbolLen = udat_getSymbols(pFormat, type, i, NULL, 0, &ignore) + 1;
- UChar* symbolBuf = calloc(symbolLen, sizeof(UChar));
- if (symbolBuf == NULL)
+ if (symbolLen <= sizeof(stackSymbolBuf) / sizeof(stackSymbolBuf[0]))
{
- udat_close(pFormat);
- ucal_close(pCalendar);
- return false;
+ symbolBuf = stackSymbolBuf;
+ }
+ else
+ {
+ symbolBuf = calloc(symbolLen, sizeof(UChar));
+ if (symbolBuf == NULL)
+ {
+ err = U_MEMORY_ALLOCATION_ERROR;
+ break;
+ }
}
udat_getSymbols(pFormat, type, i, symbolBuf, symbolLen, &err);
- assert(U_SUCCESS(err));
+ if (U_SUCCESS(err))
+ {
+ callback(symbolBuf, context);
+ }
- if (U_FAILURE(err))
+ if (symbolBuf != stackSymbolBuf)
{
- udat_close(pFormat);
- ucal_close(pCalendar);
free(symbolBuf);
- return false;
}
-
- callback(symbolBuf, context);
- free(symbolBuf);
}
udat_close(pFormat);
ucal_close(pCalendar);
- return true;
+ return U_SUCCESS(err);
}
bool EnumUResourceBundle(const UResourceBundle* bundle, EnumCalendarInfoCallback callback, const void* context)