}
}
-EraRules::EraRules(int32_t *startDates, int32_t numEras)
- : startDates(startDates), numEras(numEras) {
+EraRules::EraRules(LocalArray<int32_t>& eraStartDates, int32_t numEras)
+ : numEras(numEras) {
+ startDates.moveFrom(eraStartDates);
initCurrentEra();
}
EraRules::~EraRules() {
- uprv_free(startDates);
}
EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEra, UErrorCode& status) {
ures_getByKey(rb.getAlias(), "calendarData", rb.getAlias(), &status);
ures_getByKey(rb.getAlias(), calType, rb.getAlias(), &status);
ures_getByKey(rb.getAlias(), "eras", rb.getAlias(), &status);
-
+
if (U_FAILURE(status)) {
return nullptr;
}
int32_t numEras = ures_getSize(rb.getAlias());
int32_t firstTentativeIdx = MAX_INT32;
- int32_t *startDates = (int32_t*)uprv_malloc(numEras * sizeof(int32_t));
- if (startDates == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
+ LocalArray<int32_t> startDates(new int32_t[numEras], status);
+ if (U_FAILURE(status)) {
return nullptr;
}
- uprv_memset(startDates, 0, numEras * sizeof(int32_t));
+ uprv_memset(startDates.getAlias(), 0 , numEras * sizeof(int32_t));
while (ures_hasNext(rb.getAlias())) {
LocalUResourceBundlePointer eraRuleRes(ures_getNextResource(rb.getAlias(), nullptr, &status));
if (U_FAILURE(status)) {
- goto error;
+ return nullptr;
}
const char *eraIdxStr = ures_getKey(eraRuleRes.getAlias());
char *endp;
int32_t eraIdx = (int32_t)strtol(eraIdxStr, &endp, 10);
if ((size_t)(endp - eraIdxStr) != uprv_strlen(eraIdxStr)) {
status = U_INVALID_FORMAT_ERROR;
- goto error;
+ return nullptr;
}
if (eraIdx < 0 || eraIdx >= numEras) {
status = U_INVALID_FORMAT_ERROR;
- goto error;
+ return nullptr;
}
if (isSet(startDates[eraIdx])) {
// start date of the index was already set
status = U_INVALID_FORMAT_ERROR;
- goto error;
+ return nullptr;
}
UBool hasName = TRUE;
while (ures_hasNext(eraRuleRes.getAlias())) {
LocalUResourceBundlePointer res(ures_getNextResource(eraRuleRes.getAlias(), nullptr, &status));
if (U_FAILURE(status)) {
- goto error;
+ return nullptr;
}
const char *key = ures_getKey(res.getAlias());
if (uprv_strcmp(key, "start") == 0) {
const int32_t *fields = ures_getIntVector(res.getAlias(), &len, &status);
if (U_FAILURE(status)) {
- goto error;
+ return nullptr;
}
if (len != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) {
status = U_INVALID_FORMAT_ERROR;
- goto error;
+ return nullptr;
}
startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]);
} else if (uprv_strcmp(key, "named") == 0) {
// This implementation does not support end only rule for eras other than
// the first one.
status = U_INVALID_FORMAT_ERROR;
- goto error;
+ return nullptr;
}
U_ASSERT(eraIdx == 0);
startDates[eraIdx] = MIN_ENCODED_START;
} else {
status = U_INVALID_FORMAT_ERROR;
- goto error;
+ return nullptr;
}
}
if (hasName) {
if (eraIdx >= firstTentativeIdx) {
status = U_INVALID_FORMAT_ERROR;
- goto error;
+ return nullptr;
}
} else {
if (eraIdx < firstTentativeIdx) {
status = U_MEMORY_ALLOCATION_ERROR;
}
return result;
-
-error:
- uprv_free(startDates);
- return nullptr;
}
void EraRules::getStartDate(int32_t eraIdx, int32_t (&fields)[3], UErrorCode& status) const {
U_NAMESPACE_BEGIN
+// Export an explicit template instantiation of LocalArray used as a data member of EraRules.
+// When building DLLs for Windows this is required even though no direct access leaks out of the i18n library.
+// See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.
+#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
+// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
+#pragma warning(suppress: 4661)
+template class U_I18N_API LocalPointerBase<int32_t>;
+template class U_I18N_API LocalArray<int32_t>;
+#endif
+
class U_I18N_API EraRules : public UMemory {
public:
~EraRules();
}
private:
- EraRules(int32_t *startDates, int32_t numEra);
+ EraRules(LocalArray<int32_t>& eraStartDates, int32_t numEra);
void initCurrentEra();
- int32_t *startDates;
+ LocalArray<int32_t> startDates;
int32_t numEras;
int32_t currentEra;
};
// By default, such tentative era is disabled.
// 1. Environment variable ICU_ENABLE_TENTATIVE_ERA=true or false
- // 2. Windows registry (TBD)
UBool includeTentativeEra = FALSE;
-#if U_PLATFORM_HAS_WINUWP_API == 0
+#if U_PLATFORM_HAS_WINUWP_API == 1
+ // UWP doesn't allow access to getenv(), but we can call GetEnvironmentVariableW to do the same thing.
+ UChar varName[26] = {};
+ u_charsToUChars(TENTATIVE_ERA_VAR_NAME, varName, static_cast<int32_t>(uprv_strlen(TENTATIVE_ERA_VAR_NAME)));
+ WCHAR varValue[5] = {};
+ DWORD ret = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(varName), varValue, UPRV_LENGTHOF(varValue));
+ if ((ret == 4) && (_wcsicmp(varValue, L"true") == 0)) {
+ includeTentativeEra = TRUE;
+ }
+#else
char *envVarVal = getenv(TENTATIVE_ERA_VAR_NAME);
if (envVarVal != NULL && uprv_stricmp(envVarVal, "true") == 0) {
includeTentativeEra = TRUE;
*
* **Note:** for some non-Gregorian calendars, different
* fields may be necessary for complete disambiguation. For example, a full
- * specification of the historial Arabic astronomical calendar requires year,
+ * specification of the historical Arabic astronomical calendar requires year,
* month, day-of-month *and* day-of-week in some cases.
*
* **Note:** There are certain possible ambiguities in
/**
* Sets the behavior for handling wall time repeating multiple times
* at negative time zone offset transitions. For example, 1:30 AM on
- * November 6, 2011 in US Eastern time (Ameirca/New_York) occurs twice;
+ * November 6, 2011 in US Eastern time (America/New_York) occurs twice;
* 1:30 AM EDT, then 1:30 AM EST one hour later. When <code>UCAL_WALLTIME_FIRST</code>
* is used, the wall time 1:30AM in this example will be interpreted as 1:30 AM EDT
* (first occurrence). When <code>UCAL_WALLTIME_LAST</code> is used, it will be
TimeZone* fZone;
/**
- * Option for rpeated wall time
+ * Option for repeated wall time
* @see #setRepeatedWallTimeOption
*/
UCalendarWallTimeOption fRepeatedWallTime;
BasicTimeZone* getBasicTimeZone() const;
/**
- * Find the previous zone transtion near the given time.
+ * Find the previous zone transition near the given time.
* @param base The base time, inclusive
* @param transitionTime Receives the result time
* @param status The error status