static void umsg_set_timezone(MessageFormatter_object *mfo, intl_error& err) { MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf; TimeZone *used_tz = NULL; const Format **formats; int32_t count; /* Unfortanely, this cannot change the time zone for arguments that * appear inside complex formats because ::getFormats() returns NULL * for all uncached formats, which is the case for complex formats * unless they were set via one of the ::setFormat() methods */ if (mfo->mf_data.tz_set) { return; /* already done */ } formats = mf->getFormats(count); if (formats == NULL) { intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR, "Out of memory retrieving subformats", 0); } for (int i = 0; U_SUCCESS(err.code) && i < count; i++) { DateFormat* df = dynamic_cast<DateFormat*>( const_cast<Format *>(formats[i])); if (df == NULL) { continue; } if (used_tz == NULL) { zval nullzv, *zvptr = &nullzv; ZVAL_NULL(zvptr); used_tz = timezone_process_timezone_argument(zvptr, &err, "msgfmt_format"); if (used_tz == NULL) { continue; } } df->setTimeZone(*used_tz); } if (U_SUCCESS(err.code)) { mfo->mf_data.tz_set = 1; } }
static void umsg_set_timezone(MessageFormatter_object *mfo, intl_error& err) { MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf; TimeZone *used_tz = NULL; const Format **formats; int32_t count; /* Unfortanely, this cannot change the time zone for arguments that * appear inside complex formats because ::getFormats() returns NULL * for all uncached formats, which is the case for complex formats * unless they were set via one of the ::setFormat() methods */ if (mfo->mf_data.tz_set) { return; /* already done */ } /* There is a bug in ICU which prevents MessageFormatter::getFormats() to handle more than 10 formats correctly. The enumerator could be used to walk through the present formatters using getFormat(), which however seems to provide just a readonly access. This workaround prevents crash when there are > 10 formats but doesn't set any error. As a result, only DateFormatters with > 10 subformats are affected. This workaround should be ifdef'd out, when the bug has been fixed in ICU. */ icu::StringEnumeration* fnames = mf->getFormatNames(err.code); if (!fnames || U_FAILURE(err.code)) { return; } count = fnames->count(err.code); delete fnames; if (count > 10) { return; } formats = mf->getFormats(count); if (formats == NULL) { intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR, "Out of memory retrieving subformats", 0); } for (int i = 0; U_SUCCESS(err.code) && i < count; i++) { DateFormat* df = dynamic_cast<DateFormat*>( const_cast<Format *>(formats[i])); if (df == NULL) { continue; } if (used_tz == NULL) { zval nullzv, *zvptr = &nullzv; ZVAL_NULL(zvptr); used_tz = timezone_process_timezone_argument(zvptr, &err, "msgfmt_format"); if (used_tz == NULL) { continue; } } df->setTimeZone(*used_tz); } if (U_SUCCESS(err.code)) { mfo->mf_data.tz_set = 1; } }