PassOwnPtr<Vector<String>> LocaleICU::createLabelVector(const UDateFormat* dateFormat, UDateFormatSymbolType type, int32_t startIndex, int32_t size) { if (!dateFormat) return PassOwnPtr<Vector<String>>(); if (udat_countSymbols(dateFormat, type) != startIndex + size) return PassOwnPtr<Vector<String>>(); OwnPtr<Vector<String>> labels = adoptPtr(new Vector<String>()); labels->reserveCapacity(size); bool isStandAloneMonth = (type == UDAT_STANDALONE_MONTHS) || (type == UDAT_STANDALONE_SHORT_MONTHS); for (int32_t i = 0; i < size; ++i) { UErrorCode status = U_ZERO_ERROR; int32_t length; static const UDate kEpoch = U_MILLIS_PER_DAY * 15u; // 1970-01-15 static const UDate kMonth = U_MILLIS_PER_DAY * 30u; // 30 days in ms if (isStandAloneMonth) { length = udat_format(dateFormat, kEpoch + i * kMonth, 0, 0, 0, &status); } else { length = udat_getSymbols(dateFormat, type, startIndex + i, 0, 0, &status); } if (status != U_BUFFER_OVERFLOW_ERROR) return PassOwnPtr<Vector<String>>(); StringBuffer<UChar> buffer(length); status = U_ZERO_ERROR; if (isStandAloneMonth) { udat_format(dateFormat, kEpoch + i * kMonth, buffer.characters(), length, 0, &status); } else { udat_getSymbols(dateFormat, type, startIndex + i, buffer.characters(), length, &status); } if (U_FAILURE(status)) return PassOwnPtr<Vector<String>>(); labels->append(String::adopt(buffer)); } return labels.release(); }
/* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */ static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected) { UChar *pattern=NULL; UErrorCode status = U_ZERO_ERROR; UChar *result=NULL; int32_t resultlength, resultlengthout; pattern=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1)); u_uastrcpy(pattern, expected); resultlength=0; resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status); if(status==U_BUFFER_OVERFLOW_ERROR) { status=U_ZERO_ERROR; resultlength=resultlengthout+1; result=(UChar*)malloc(sizeof(UChar) * resultlength); udat_getSymbols(datfor, type, idx, result, resultlength, &status); } if(U_FAILURE(status)) { log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) ); return; } if(u_strcmp(result, pattern)==0) log_verbose("PASS: getSymbols retrieved the right value\n"); else{ log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", austrdup(pattern), austrdup(result) ); } free(result); free(pattern); }
static void get_symbols(const UDateFormat *fmt, UDateFormatSymbolType type, UChar *array[], int32_t arrayLength, int32_t lowestIndex, int32_t firstIndex, UErrorCode *status) { int32_t count, i; if (U_FAILURE(*status)) { return; } count = udat_countSymbols(fmt, type); if(count != arrayLength + lowestIndex) { return; } for(i = 0; i < arrayLength; i++) { int32_t idx = (i + firstIndex) % arrayLength; int32_t size = 1 + udat_getSymbols(fmt, type, idx + lowestIndex, NULL, 0, status); array[idx] = (UChar *) malloc(sizeof(UChar) * size); *status = U_ZERO_ERROR; udat_getSymbols(fmt, type, idx + lowestIndex, array[idx], size, status); } }
static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx) { UChar *result=NULL; UChar *value=NULL; int32_t resultlength, resultlengthout; UErrorCode status = U_ZERO_ERROR; resultlength=0; resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status); if(status==U_BUFFER_OVERFLOW_ERROR){ status=U_ZERO_ERROR; resultlength=resultlengthout+1; result=(UChar*)malloc(sizeof(UChar) * resultlength); udat_getSymbols(from, type, idx, result, resultlength, &status); } if(U_FAILURE(status)){ log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) ); return; } resultlength=resultlengthout+1; udat_setSymbols(to, type, idx, result, resultlength, &status); if(U_FAILURE(status)) { log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) ); return; } resultlength=0; resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status); if(status==U_BUFFER_OVERFLOW_ERROR){ status=U_ZERO_ERROR; resultlength=resultlengthout+1; value=(UChar*)malloc(sizeof(UChar) * resultlength); udat_getSymbols(to, type, idx, value, resultlength, &status); } if(U_FAILURE(status)){ log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n", myErrorName(status) ); return; } if(u_strcmp(result, value)!=0){ log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result), austrdup(value) ); } else log_verbose("PASS: setSymbols successful\n"); free(value); free(result); }
/* Function: GetLocaleInfoAmPm Obtains the value of the AM or PM string for a locale. */ static UErrorCode GetLocaleInfoAmPm(const char* locale, int am, UChar* value, int32_t valueLength) { UErrorCode status = U_ZERO_ERROR; UDateFormat* pFormat = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, locale, NULL, 0, NULL, 0, &status); udat_getSymbols(pFormat, UDAT_AM_PMS, am ? 0 : 1, value, valueLength, &status); udat_close(pFormat); return status; }
static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected) { UChar *result=NULL; UChar *value=NULL; int32_t resultlength, resultlengthout; UErrorCode status = U_ZERO_ERROR; value=(UChar*)malloc(sizeof(UChar) * (strlen(expected) + 1)); u_uastrcpy(value, expected); udat_setSymbols(datfor, type, idx, value, u_strlen(value), &status); if(U_FAILURE(status)) { log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status) ); return; } resultlength=0; resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status); if(status==U_BUFFER_OVERFLOW_ERROR){ status=U_ZERO_ERROR; resultlength=resultlengthout+1; result=(UChar*)malloc(sizeof(UChar) * resultlength); udat_getSymbols(datfor, type, idx, result, resultlength, &status); } if(U_FAILURE(status)){ log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n", myErrorName(status) ); return; } if(u_strcmp(result, value)!=0){ log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(value), austrdup(result) ); } else log_verbose("PASS: setSymbols successful\n"); free(value); free(result); }
PassOwnPtr<Vector<String> > ICULocale::createLabelVector(UDateFormatSymbolType type, int32_t startIndex, int32_t size) { if (!m_shortDateFormat) return PassOwnPtr<Vector<String> >(); if (udat_countSymbols(m_shortDateFormat, type) != startIndex + size) return PassOwnPtr<Vector<String> >(); OwnPtr<Vector<String> > labels = adoptPtr(new Vector<String>()); labels->reserveCapacity(size); for (int32_t i = 0; i < size; ++i) { UErrorCode status = U_ZERO_ERROR; int32_t length = udat_getSymbols(m_shortDateFormat, type, startIndex + i, 0, 0, &status); if (status != U_BUFFER_OVERFLOW_ERROR) return PassOwnPtr<Vector<String> >(); Vector<UChar> buffer(length); status = U_ZERO_ERROR; udat_getSymbols(m_shortDateFormat, type, startIndex + i, buffer.data(), length, &status); if (U_FAILURE(status)) return PassOwnPtr<Vector<String> >(); labels->append(String::adopt(buffer)); } return labels.release(); }
/* Function: GetLocaleInfoAmPm Obtains the value of the AM or PM string for a locale. */ UErrorCode GetLocaleInfoAmPm(const char* locale, bool am, UChar* value, int32_t valueLength) { UErrorCode status = U_ZERO_ERROR; UDateFormat* pFormat = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, locale, nullptr, 0, nullptr, 0, &status); UDateFormatHolder formatHolder(pFormat, status); if (U_FAILURE(status)) { return status; } udat_getSymbols(pFormat, UDAT_AM_PMS, am ? 0 : 1, value, valueLength, &status); return status; }
/*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/ static void TestSymbols() { UDateFormat *def, *fr; UErrorCode status = U_ZERO_ERROR; UChar *value=NULL; UChar *result = NULL; int32_t resultlength; int32_t resultlengthout; UChar *pattern; /*creating a dateformat with french locale */ log_verbose("\ncreating a date format with french locale\n"); fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL, 0, NULL, 0, &status); if(U_FAILURE(status)) { log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n", myErrorName(status) ); return; } /*creating a default dateformat */ log_verbose("\ncreating a date format with default locale\n"); /* this is supposed to open default date format, but later on it treats it like it is "en_US" - very bad if you try to run the tests on machine where default locale is NOT "en_US" */ /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */ def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, NULL, 0, &status); if(U_FAILURE(status)) { log_err("error in creating the dateformat using short date and time style\n %s\n", myErrorName(status) ); return; } /*Testing countSymbols, getSymbols and setSymbols*/ log_verbose("\nTesting countSymbols\n"); /*since the month names has the last string empty and week names are 1 based 1.e first string in the weeknames array is empty */ if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 || udat_countSymbols(def, UDAT_SHORT_MONTHS)!=12 || udat_countSymbols(def, UDAT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_SHORT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_AM_PMS)!=2 || udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_LOCALIZED_CHARS)!=1) { log_err("FAIL: error in udat_countSymbols\n"); } else log_verbose("PASS: udat_countSymbols() successful\n"); /*testing getSymbols*/ log_verbose("\nTesting getSymbols\n"); pattern=(UChar*)malloc(sizeof(UChar) * 10); u_uastrcpy(pattern, "jeudi"); resultlength=0; resultlengthout=udat_getSymbols(fr, UDAT_WEEKDAYS, 5 , NULL, resultlength, &status); if(status==U_BUFFER_OVERFLOW_ERROR) { status=U_ZERO_ERROR; resultlength=resultlengthout+1; if(result != NULL) { free(result); result = NULL; } result=(UChar*)malloc(sizeof(UChar) * resultlength); udat_getSymbols(fr, UDAT_WEEKDAYS, 5, result, resultlength, &status); } if(U_FAILURE(status)) { log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status) ); } else log_verbose("PASS: getSymbols succesful\n"); if(u_strcmp(result, pattern)==0) log_verbose("PASS: getSymbols retrieved the right value\n"); else log_data_err("FAIL: getSymbols retrieved the wrong value\n"); /*run series of tests to test getsymbols regressively*/ log_verbose("\nTesting getSymbols() regressively\n"); VerifygetSymbols(fr, UDAT_WEEKDAYS, 1, "dimanche"); VerifygetSymbols(def, UDAT_WEEKDAYS, 1, "Sunday"); VerifygetSymbols(fr, UDAT_SHORT_WEEKDAYS, 7, "sam."); VerifygetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Sat"); VerifygetSymbols(def, UDAT_MONTHS, 11, "December"); VerifygetSymbols(def, UDAT_MONTHS, 0, "January"); VerifygetSymbols(fr, UDAT_ERAS, 0, "av. J.-C."); VerifygetSymbols(def, UDAT_AM_PMS, 0, "AM"); VerifygetSymbols(def, UDAT_AM_PMS, 1, "PM"); VerifygetSymbols(fr, UDAT_SHORT_MONTHS, 0, "janv."); VerifygetSymbols(def, UDAT_SHORT_MONTHS, 11, "Dec"); VerifygetSymbols(fr, UDAT_QUARTERS, 0, "1er trimestre"); VerifygetSymbols(def, UDAT_QUARTERS, 3, "4th quarter"); VerifygetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "T2"); VerifygetSymbols(def, UDAT_SHORT_QUARTERS, 2, "Q3"); VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqV"); if(result != NULL) { free(result); result = NULL; } free(pattern); log_verbose("\nTesting setSymbols\n"); /*applying the pattern so that setSymbolss works */ resultlength=0; resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status); if(status==U_BUFFER_OVERFLOW_ERROR) { status=U_ZERO_ERROR; resultlength=resultlengthout + 1; pattern=(UChar*)malloc(sizeof(UChar) * resultlength); udat_toPattern(fr, FALSE, pattern, resultlength, &status); } if(U_FAILURE(status)) { log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n", myErrorName(status) ); } udat_applyPattern(def, FALSE, pattern, u_strlen(pattern)); resultlength=0; resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status); if(status==U_BUFFER_OVERFLOW_ERROR) { status=U_ZERO_ERROR; resultlength=resultlengthout + 1; if(result != NULL) { free(result); result = NULL; } result=(UChar*)malloc(sizeof(UChar) * resultlength); udat_toPattern(fr, FALSE,result, resultlength, &status); } if(U_FAILURE(status)) { log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n", myErrorName(status) ); } if(u_strcmp(result, pattern)==0) log_verbose("Pattern applied properly\n"); else log_err("pattern could not be applied properly\n"); free(pattern); /*testing set symbols */ resultlength=0; resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status); if(status==U_BUFFER_OVERFLOW_ERROR){ status=U_ZERO_ERROR; resultlength=resultlengthout+1; if(result != NULL) { free(result); result = NULL; } result=(UChar*)malloc(sizeof(UChar) * resultlength); udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status); } if(U_FAILURE(status)) log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) ); resultlength=resultlengthout+1; udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status); if(U_FAILURE(status)) { log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) ); } else log_verbose("PASS: SetSymbols successful\n"); resultlength=0; resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status); if(status==U_BUFFER_OVERFLOW_ERROR){ status=U_ZERO_ERROR; resultlength=resultlengthout+1; value=(UChar*)malloc(sizeof(UChar) * resultlength); udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status); } if(U_FAILURE(status)) log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n"); if(u_strcmp(result, value)!=0) log_data_err("FAIL: Error in settting and getting symbols\n"); else log_verbose("PASS: setSymbols successful\n"); /*run series of tests to test setSymbols regressively*/ log_verbose("\nTesting setSymbols regressively\n"); VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist"); VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini"); VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek"); VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek"); VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M"); VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek"); VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams"); VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V"); VerifysetSymbols(fr, UDAT_MONTHS, 11, "december"); VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan"); VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R"); VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember"); VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug"); VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M"); VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart"); VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2"); VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar."); VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ"); /*run series of tests to test get and setSymbols regressively*/ log_verbose("\nTesting get and set symbols regressively\n"); VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1); VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7); VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1); VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7); VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0); VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0); VerifygetsetSymbols(fr, def, UDAT_ERAS,1); VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0); VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1); /*closing*/ udat_close(fr); udat_close(def); if(result != NULL) { free(result); result = NULL; } free(value); }
static void TestRelativeCrash(void) { static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; static const UDate aDate = -631152000000.0; UErrorCode status = U_ZERO_ERROR; UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR; UDateFormat icudf; icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status); if ( U_SUCCESS(status) ) { const char *what = "???"; { UErrorCode subStatus = U_ZERO_ERROR; what = "udat_set2DigitYearStart"; log_verbose("Trying %s on a relative date..\n", what); udat_set2DigitYearStart(icudf, aDate, &subStatus); if(subStatus == expectStatus) { log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); } else { log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); } } { /* clone works polymorphically. try it anyways */ UErrorCode subStatus = U_ZERO_ERROR; UDateFormat *oth; what = "clone"; log_verbose("Trying %s on a relative date..\n", what); oth = udat_clone(icudf, &subStatus); if(subStatus == U_ZERO_ERROR) { log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); udat_close(oth); /* ? */ } else { log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); } } { UErrorCode subStatus = U_ZERO_ERROR; what = "udat_get2DigitYearStart"; log_verbose("Trying %s on a relative date..\n", what); udat_get2DigitYearStart(icudf, &subStatus); if(subStatus == expectStatus) { log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); } else { log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); } } { /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */ UErrorCode subStatus = U_ZERO_ERROR; what = "udat_toPattern"; log_verbose("Trying %s on a relative date..\n", what); udat_toPattern(icudf, TRUE,NULL,0, &subStatus); if(subStatus == expectStatus) { log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); } else { log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); } } { UErrorCode subStatus = U_ZERO_ERROR; what = "udat_applyPattern"; log_verbose("Trying %s on a relative date..\n", what); udat_applyPattern(icudf, FALSE,tzName,-1); subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */ if(subStatus == expectStatus) { log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); } else { log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); } } { UErrorCode subStatus = U_ZERO_ERROR; what = "udat_getSymbols"; log_verbose("Trying %s on a relative date..\n", what); udat_getSymbols(icudf, UDAT_ERAS,0,NULL,0, &subStatus); /* bogus values */ if(subStatus == expectStatus) { log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); } else { log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); } } { UErrorCode subStatus = U_ZERO_ERROR; what = "udat_countSymbols"; log_verbose("Trying %s on a relative date..\n", what); udat_countSymbols(icudf, UDAT_ERAS); subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */ if(subStatus == expectStatus) { log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); } else { log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); } } udat_close(icudf); } else { log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status)); } }
/* Function: EnumSymbols Enumerates all of the symbols of a type for a locale and calendar and invokes a callback for each value. */ static int32_t EnumSymbols(const char* locale, CalendarId calendarId, UDateFormatSymbolType type, int32_t startIndex, EnumCalendarInfoCallback callback, const void* context) { UErrorCode err = U_ZERO_ERROR; UDateFormat* pFormat = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, locale, NULL, 0, NULL, 0, &err); if (U_FAILURE(err)) return FALSE; char localeWithCalendarName[ULOC_FULLNAME_CAPACITY]; strncpy(localeWithCalendarName, locale, ULOC_FULLNAME_CAPACITY); uloc_setKeywordValue("calendar", GetCalendarName(calendarId), localeWithCalendarName, ULOC_FULLNAME_CAPACITY, &err); UCalendar* pCalendar = ucal_open(NULL, 0, localeWithCalendarName, UCAL_DEFAULT, &err); if (U_FAILURE(err)) { udat_close(pFormat); return FALSE; } udat_setCalendar(pFormat, pCalendar); int32_t symbolCount = udat_countSymbols(pFormat, type); UChar stackSymbolBuf[100]; UChar* symbolBuf; 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; if (symbolLen <= sizeof(stackSymbolBuf) / sizeof(stackSymbolBuf[0])) { 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); if (U_SUCCESS(err)) { callback(symbolBuf, context); } if (symbolBuf != stackSymbolBuf) { free(symbolBuf); } } udat_close(pFormat); ucal_close(pCalendar); return UErrorCodeToBool(err); }