// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 1997-2016, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
* File DTFMTSYM.CPP
*
* Modification History:
*
*   Date        Name        Description
*   02/19/97    aliu        Converted from java.
*   07/21/98    stephen     Added getZoneIndex
*                            Changed weekdays/short weekdays to be one-based
*   06/14/99    stephen     Removed SimpleDateFormat::fgTimeZoneDataSuffix
*   11/16/99    weiv        Added 'Y' and 'e' to fgPatternChars
*   03/27/00    weiv        Keeping resource bundle around!
*   06/30/05    emmons      Added eraNames, narrow month/day, standalone context
*   10/12/05    emmons      Added setters for eraNames, month/day by width/context
*******************************************************************************
*/
#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING
#include "unicode/ustring.h"
#include "unicode/localpointer.h"
#include "unicode/dtfmtsym.h"
#include "unicode/smpdtfmt.h"
#include "unicode/msgfmt.h"
#include "unicode/numsys.h"
#include "unicode/tznames.h"
#include "cpputils.h"
#include "umutex.h"
#include "cmemory.h"
#include "cstring.h"
#include "charstr.h"
#include "dt_impl.h"
#include "locbased.h"
#include "gregoimp.h"
#include "hash.h"
#include "uassert.h"
#include "uresimp.h"
#include "ureslocs.h"
#include "uvector.h"
#include "shareddateformatsymbols.h"
#include "unicode/calendar.h"
#include "unifiedcache.h"

// *****************************************************************************
// class DateFormatSymbols
// *****************************************************************************

/**
 * These are static arrays we use only in the case where we have no
 * resource data.
 */

#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
#define PATTERN_CHARS_LEN 38
#else
#define PATTERN_CHARS_LEN 37
#endif

/**
 * Unlocalized date-time pattern characters. For example: 'y', 'd', etc. All
 * locales use the same these unlocalized pattern characters.
 */
static const UChar gPatternChars[] = {
    // if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR:
    //   GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:
    // else:
    //   GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB

    0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45,
    0x44, 0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65,
    0x75, 0x67, 0x41, 0x5A, 0x76, 0x63, 0x4c, 0x51, 0x71, 0x56,
    0x55, 0x4F, 0x58, 0x78, 0x72, 0x62, 0x42,
#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
    0x3a,
#endif
    0
};

//------------------------------------------------------
// Strings of last resort.  These are only used if we have no resource
// files.  They aren't designed for actual use, just for backup.

// These are the month names and abbreviations of last resort.
static const UChar gLastResortMonthNames[13][3] =
{
    {0x0030, 0x0031, 0x0000}, /* "01" */
    {0x0030, 0x0032, 0x0000}, /* "02" */
    {0x0030, 0x0033, 0x0000}, /* "03" */
    {0x0030, 0x0034, 0x0000}, /* "04" */
    {0x0030, 0x0035, 0x0000}, /* "05" */
    {0x0030, 0x0036, 0x0000}, /* "06" */
    {0x0030, 0x0037, 0x0000}, /* "07" */
    {0x0030, 0x0038, 0x0000}, /* "08" */
    {0x0030, 0x0039, 0x0000}, /* "09" */
    {0x0031, 0x0030, 0x0000}, /* "10" */
    {0x0031, 0x0031, 0x0000}, /* "11" */
    {0x0031, 0x0032, 0x0000}, /* "12" */
    {0x0031, 0x0033, 0x0000}  /* "13" */
};

// These are the weekday names and abbreviations of last resort.
static const UChar gLastResortDayNames[8][2] =
{
    {0x0030, 0x0000}, /* "0" */
    {0x0031, 0x0000}, /* "1" */
    {0x0032, 0x0000}, /* "2" */
    {0x0033, 0x0000}, /* "3" */
    {0x0034, 0x0000}, /* "4" */
    {0x0035, 0x0000}, /* "5" */
    {0x0036, 0x0000}, /* "6" */
    {0x0037, 0x0000}  /* "7" */
};

// These are the quarter names and abbreviations of last resort.
static const UChar gLastResortQuarters[4][2] =
{
    {0x0031, 0x0000}, /* "1" */
    {0x0032, 0x0000}, /* "2" */
    {0x0033, 0x0000}, /* "3" */
    {0x0034, 0x0000}, /* "4" */
};

// These are the am/pm and BC/AD markers of last resort.
static const UChar gLastResortAmPmMarkers[2][3] =
{
    {0x0041, 0x004D, 0x0000}, /* "AM" */
    {0x0050, 0x004D, 0x0000}  /* "PM" */
};

static const UChar gLastResortEras[2][3] =
{
    {0x0042, 0x0043, 0x0000}, /* "BC" */
    {0x0041, 0x0044, 0x0000}  /* "AD" */
};

/* Sizes for the last resort string arrays */
typedef enum LastResortSize {
    kMonthNum = 13,
    kMonthLen = 3,

    kDayNum = 8,
    kDayLen = 2,

    kAmPmNum = 2,
    kAmPmLen = 3,

    kQuarterNum = 4,
    kQuarterLen = 2,

    kEraNum = 2,
    kEraLen = 3,

    kZoneNum = 5,
    kZoneLen = 4,

    kGmtHourNum = 4,
    kGmtHourLen = 10
} LastResortSize;

U_NAMESPACE_BEGIN

SharedDateFormatSymbols::~SharedDateFormatSymbols() {
}

template<> U_I18N_API
const SharedDateFormatSymbols *
        LocaleCacheKey<SharedDateFormatSymbols>::createObject(
                const void * /*unusedContext*/, UErrorCode &status) const {
    char type[256];
    Calendar::getCalendarTypeFromLocale(fLoc, type, UPRV_LENGTHOF(type), status);
    if (U_FAILURE(status)) {
        return NULL;
    }
    SharedDateFormatSymbols *shared
            = new SharedDateFormatSymbols(fLoc, type, status);
    if (shared == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    if (U_FAILURE(status)) {
        delete shared;
        return NULL;
    }
    shared->addRef();
    return shared;
}

UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateFormatSymbols)

#define kSUPPLEMENTAL "supplementalData"

/**
 * These are the tags we expect to see in normal resource bundle files associated
 * with a locale and calendar
 */
static const char gCalendarTag[]="calendar";
static const char gGregorianTag[]="gregorian";
static const char gErasTag[]="eras";
static const char gCyclicNameSetsTag[]="cyclicNameSets";
static const char gNameSetYearsTag[]="years";
static const char gNameSetZodiacsTag[]="zodiacs";
static const char gMonthNamesTag[]="monthNames";
static const char gMonthPatternsTag[]="monthPatterns";
static const char gDayNamesTag[]="dayNames";
static const char gNamesWideTag[]="wide";
static const char gNamesAbbrTag[]="abbreviated";
static const char gNamesShortTag[]="short";
static const char gNamesNarrowTag[]="narrow";
static const char gNamesAllTag[]="all";
static const char gNamesFormatTag[]="format";
static const char gNamesStandaloneTag[]="stand-alone";
static const char gNamesNumericTag[]="numeric";
static const char gAmPmMarkersTag[]="AmPmMarkers";
static const char gAmPmMarkersAbbrTag[]="AmPmMarkersAbbr";
static const char gAmPmMarkersNarrowTag[]="AmPmMarkersNarrow";
static const char gQuartersTag[]="quarters";
static const char gNumberElementsTag[]="NumberElements";
static const char gSymbolsTag[]="symbols";
static const char gTimeSeparatorTag[]="timeSeparator";
static const char gDayPeriodTag[]="dayPeriod";

// static const char gZoneStringsTag[]="zoneStrings";

// static const char gLocalPatternCharsTag[]="localPatternChars";

static const char gContextTransformsTag[]="contextTransforms";

static UMutex LOCK = U_MUTEX_INITIALIZER;

/**
 * Jitterbug 2974: MSVC has a bug whereby new X[0] behaves badly.
 * Work around this.
 */
static inline UnicodeString* newUnicodeStringArray(size_t count) {
    return new UnicodeString[count ? count : 1];
}

//------------------------------------------------------

DateFormatSymbols * U_EXPORT2
DateFormatSymbols::createForLocale(
        const Locale& locale, UErrorCode &status) {
    const SharedDateFormatSymbols *shared = NULL;
    UnifiedCache::getByLocale(locale, shared, status);
    if (U_FAILURE(status)) {
        return NULL;
    }
    DateFormatSymbols *result = new DateFormatSymbols(shared->get());
    shared->removeRef();
    if (result == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    return result;
}

DateFormatSymbols::DateFormatSymbols(const Locale& locale,
                                     UErrorCode& status)
    : UObject()
{
  initializeData(locale, NULL,  status);
}

DateFormatSymbols::DateFormatSymbols(UErrorCode& status)
    : UObject()
{
  initializeData(Locale::getDefault(), NULL, status, TRUE);
}


DateFormatSymbols::DateFormatSymbols(const Locale& locale,
                                     const char *type,
                                     UErrorCode& status)
    : UObject()
{
  initializeData(locale, type,  status);
}

DateFormatSymbols::DateFormatSymbols(const char *type, UErrorCode& status)
    : UObject()
{
  initializeData(Locale::getDefault(), type, status, TRUE);
}

DateFormatSymbols::DateFormatSymbols(const DateFormatSymbols& other)
    : UObject(other)
{
    copyData(other);
}

void
DateFormatSymbols::assignArray(UnicodeString*& dstArray,
                               int32_t& dstCount,
                               const UnicodeString* srcArray,
                               int32_t srcCount)
{
    // assignArray() is only called by copyData() and initializeData(), which in turn
    // implements the copy constructor and the assignment operator.
    // All strings in a DateFormatSymbols object are created in one of the following
    // three ways that all allow to safely use UnicodeString::fastCopyFrom():
    // - readonly-aliases from resource bundles
    // - readonly-aliases or allocated strings from constants
    // - safely cloned strings (with owned buffers) from setXYZ() functions
    //
    // Note that this is true for as long as DateFormatSymbols can be constructed
    // only from a locale bundle or set via the cloning API,
    // *and* for as long as all the strings are in *private* fields, preventing
    // a subclass from creating these strings in an "unsafe" way (with respect to fastCopyFrom()).
    dstCount = srcCount;
    dstArray = newUnicodeStringArray(srcCount);
    if(dstArray != NULL) {
        int32_t i;
        for(i=0; i<srcCount; ++i) {
            dstArray[i].fastCopyFrom(srcArray[i]);
        }
    }
}

/**
 * Create a copy, in fZoneStrings, of the given zone strings array.  The
 * member variables fZoneStringsRowCount and fZoneStringsColCount should
 * be set already by the caller.
 */
void
DateFormatSymbols::createZoneStrings(const UnicodeString *const * otherStrings)
{
    int32_t row, col;
    UBool failed = FALSE;

    fZoneStrings = (UnicodeString **)uprv_malloc(fZoneStringsRowCount * sizeof(UnicodeString *));
    if (fZoneStrings != NULL) {
        for (row=0; row<fZoneStringsRowCount; ++row)
        {
            fZoneStrings[row] = newUnicodeStringArray(fZoneStringsColCount);
            if (fZoneStrings[row] == NULL) {
                failed = TRUE;
                break;
            }
            for (col=0; col<fZoneStringsColCount; ++col) {
                // fastCopyFrom() - see assignArray comments
                fZoneStrings[row][col].fastCopyFrom(otherStrings[row][col]);
            }
        }
    }
    // If memory allocation failed, roll back and delete fZoneStrings
    if (failed) {
        for (int i = row; i >= 0; i--) {
            delete[] fZoneStrings[i];
        }
        uprv_free(fZoneStrings);
        fZoneStrings = NULL;
    }
}

/**
 * Copy all of the other's data to this.
 */
void
DateFormatSymbols::copyData(const DateFormatSymbols& other) {
    UErrorCode status = U_ZERO_ERROR;
    U_LOCALE_BASED(locBased, *this);
    locBased.setLocaleIDs(
        other.getLocale(ULOC_VALID_LOCALE, status),
        other.getLocale(ULOC_ACTUAL_LOCALE, status));
    assignArray(fEras, fErasCount, other.fEras, other.fErasCount);
    assignArray(fEraNames, fEraNamesCount, other.fEraNames, other.fEraNamesCount);
    assignArray(fNarrowEras, fNarrowErasCount, other.fNarrowEras, other.fNarrowErasCount);
    assignArray(fMonths, fMonthsCount, other.fMonths, other.fMonthsCount);
    assignArray(fShortMonths, fShortMonthsCount, other.fShortMonths, other.fShortMonthsCount);
    assignArray(fNarrowMonths, fNarrowMonthsCount, other.fNarrowMonths, other.fNarrowMonthsCount);
    assignArray(fStandaloneMonths, fStandaloneMonthsCount, other.fStandaloneMonths, other.fStandaloneMonthsCount);
    assignArray(fStandaloneShortMonths, fStandaloneShortMonthsCount, other.fStandaloneShortMonths, other.fStandaloneShortMonthsCount);
    assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, other.fStandaloneNarrowMonths, other.fStandaloneNarrowMonthsCount);
    assignArray(fWeekdays, fWeekdaysCount, other.fWeekdays, other.fWeekdaysCount);
    assignArray(fShortWeekdays, fShortWeekdaysCount, other.fShortWeekdays, other.fShortWeekdaysCount);
    assignArray(fShorterWeekdays, fShorterWeekdaysCount, other.fShorterWeekdays, other.fShorterWeekdaysCount);
    assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, other.fNarrowWeekdays, other.fNarrowWeekdaysCount);
    assignArray(fStandaloneWeekdays, fStandaloneWeekdaysCount, other.fStandaloneWeekdays, other.fStandaloneWeekdaysCount);
    assignArray(fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, other.fStandaloneShortWeekdays, other.fStandaloneShortWeekdaysCount);
    assignArray(fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, other.fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdaysCount);
    assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, other.fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdaysCount);
    assignArray(fAmPms, fAmPmsCount, other.fAmPms, other.fAmPmsCount);
    assignArray(fNarrowAmPms, fNarrowAmPmsCount, other.fNarrowAmPms, other.fNarrowAmPmsCount );
    fTimeSeparator.fastCopyFrom(other.fTimeSeparator);  // fastCopyFrom() - see assignArray comments
    assignArray(fQuarters, fQuartersCount, other.fQuarters, other.fQuartersCount);
    assignArray(fShortQuarters, fShortQuartersCount, other.fShortQuarters, other.fShortQuartersCount);
    assignArray(fStandaloneQuarters, fStandaloneQuartersCount, other.fStandaloneQuarters, other.fStandaloneQuartersCount);
    assignArray(fStandaloneShortQuarters, fStandaloneShortQuartersCount, other.fStandaloneShortQuarters, other.fStandaloneShortQuartersCount);
    assignArray(fWideDayPeriods, fWideDayPeriodsCount,
                other.fWideDayPeriods, other.fWideDayPeriodsCount);
    assignArray(fNarrowDayPeriods, fNarrowDayPeriodsCount,
                other.fNarrowDayPeriods, other.fNarrowDayPeriodsCount);
    assignArray(fAbbreviatedDayPeriods, fAbbreviatedDayPeriodsCount,
                other.fAbbreviatedDayPeriods, other.fAbbreviatedDayPeriodsCount);
    assignArray(fStandaloneWideDayPeriods, fStandaloneWideDayPeriodsCount,
                other.fStandaloneWideDayPeriods, other.fStandaloneWideDayPeriodsCount);
    assignArray(fStandaloneNarrowDayPeriods, fStandaloneNarrowDayPeriodsCount,
                other.fStandaloneNarrowDayPeriods, other.fStandaloneNarrowDayPeriodsCount);
    assignArray(fStandaloneAbbreviatedDayPeriods, fStandaloneAbbreviatedDayPeriodsCount,
                other.fStandaloneAbbreviatedDayPeriods, other.fStandaloneAbbreviatedDayPeriodsCount);
    if (other.fLeapMonthPatterns != NULL) {
        assignArray(fLeapMonthPatterns, fLeapMonthPatternsCount, other.fLeapMonthPatterns, other.fLeapMonthPatternsCount);
    } else {
        fLeapMonthPatterns = NULL;
        fLeapMonthPatternsCount = 0;
    }
    if (other.fShortYearNames != NULL) {
        assignArray(fShortYearNames, fShortYearNamesCount, other.fShortYearNames, other.fShortYearNamesCount);
    } else {
        fShortYearNames = NULL;
        fShortYearNamesCount = 0;
    }
    if (other.fShortZodiacNames != NULL) {
        assignArray(fShortZodiacNames, fShortZodiacNamesCount, other.fShortZodiacNames, other.fShortZodiacNamesCount);
    } else {
        fShortZodiacNames = NULL;
        fShortZodiacNamesCount = 0;
    }

    if (other.fZoneStrings != NULL) {
        fZoneStringsColCount = other.fZoneStringsColCount;
        fZoneStringsRowCount = other.fZoneStringsRowCount;
        createZoneStrings((const UnicodeString**)other.fZoneStrings);

    } else {
        fZoneStrings = NULL;
        fZoneStringsColCount = 0;
        fZoneStringsRowCount = 0;
    }
    fZSFLocale = other.fZSFLocale;
    // Other zone strings data is created on demand
    fLocaleZoneStrings = NULL;

    // fastCopyFrom() - see assignArray comments
    fLocalPatternChars.fastCopyFrom(other.fLocalPatternChars);

    uprv_memcpy(fCapitalization, other.fCapitalization, sizeof(fCapitalization));
}

/**
 * Assignment operator.
 */
DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)
{
    dispose();
    copyData(other);

    return *this;
}

DateFormatSymbols::~DateFormatSymbols()
{
    dispose();
}

void DateFormatSymbols::dispose()
{
    delete[] fEras;
    delete[] fEraNames;
    delete[] fNarrowEras;
    delete[] fMonths;
    delete[] fShortMonths;
    delete[] fNarrowMonths;
    delete[] fStandaloneMonths;
    delete[] fStandaloneShortMonths;
    delete[] fStandaloneNarrowMonths;
    delete[] fWeekdays;
    delete[] fShortWeekdays;
    delete[] fShorterWeekdays;
    delete[] fNarrowWeekdays;
    delete[] fStandaloneWeekdays;
    delete[] fStandaloneShortWeekdays;
    delete[] fStandaloneShorterWeekdays;
    delete[] fStandaloneNarrowWeekdays;
    delete[] fAmPms;
    delete[] fNarrowAmPms;
    delete[] fQuarters;
    delete[] fShortQuarters;
    delete[] fStandaloneQuarters;
    delete[] fStandaloneShortQuarters;
    delete[] fLeapMonthPatterns;
    delete[] fShortYearNames;
    delete[] fShortZodiacNames;
    delete[] fAbbreviatedDayPeriods;
    delete[] fWideDayPeriods;
    delete[] fNarrowDayPeriods;
    delete[] fStandaloneAbbreviatedDayPeriods;
    delete[] fStandaloneWideDayPeriods;
    delete[] fStandaloneNarrowDayPeriods;

    disposeZoneStrings();
}

void DateFormatSymbols::disposeZoneStrings()
{
    if (fZoneStrings) {
        for (int32_t row = 0; row < fZoneStringsRowCount; ++row) {
            delete[] fZoneStrings[row];
        }
        uprv_free(fZoneStrings);
    }
    if (fLocaleZoneStrings) {
        for (int32_t row = 0; row < fZoneStringsRowCount; ++row) {
            delete[] fLocaleZoneStrings[row];
        }
        uprv_free(fLocaleZoneStrings);
    }

    fZoneStrings = NULL;
    fLocaleZoneStrings = NULL;
    fZoneStringsRowCount = 0;
    fZoneStringsColCount = 0;
}

UBool
DateFormatSymbols::arrayCompare(const UnicodeString* array1,
                                const UnicodeString* array2,
                                int32_t count)
{
    if (array1 == array2) return TRUE;
    while (count>0)
    {
        --count;
        if (array1[count] != array2[count]) return FALSE;
    }
    return TRUE;
}

UBool
DateFormatSymbols::operator==(const DateFormatSymbols& other) const
{
    // First do cheap comparisons
    if (this == &other) {
        return TRUE;
    }
    if (fErasCount == other.fErasCount &&
        fEraNamesCount == other.fEraNamesCount &&
        fNarrowErasCount == other.fNarrowErasCount &&
        fMonthsCount == other.fMonthsCount &&
        fShortMonthsCount == other.fShortMonthsCount &&
        fNarrowMonthsCount == other.fNarrowMonthsCount &&
        fStandaloneMonthsCount == other.fStandaloneMonthsCount &&
        fStandaloneShortMonthsCount == other.fStandaloneShortMonthsCount &&
        fStandaloneNarrowMonthsCount == other.fStandaloneNarrowMonthsCount &&
        fWeekdaysCount == other.fWeekdaysCount &&
        fShortWeekdaysCount == other.fShortWeekdaysCount &&
        fShorterWeekdaysCount == other.fShorterWeekdaysCount &&
        fNarrowWeekdaysCount == other.fNarrowWeekdaysCount &&
        fStandaloneWeekdaysCount == other.fStandaloneWeekdaysCount &&
        fStandaloneShortWeekdaysCount == other.fStandaloneShortWeekdaysCount &&
        fStandaloneShorterWeekdaysCount == other.fStandaloneShorterWeekdaysCount &&
        fStandaloneNarrowWeekdaysCount == other.fStandaloneNarrowWeekdaysCount &&
        fAmPmsCount == other.fAmPmsCount &&
        fNarrowAmPmsCount == other.fNarrowAmPmsCount &&
        fQuartersCount == other.fQuartersCount &&
        fShortQuartersCount == other.fShortQuartersCount &&
        fStandaloneQuartersCount == other.fStandaloneQuartersCount &&
        fStandaloneShortQuartersCount == other.fStandaloneShortQuartersCount &&
        fLeapMonthPatternsCount == other.fLeapMonthPatternsCount &&
        fShortYearNamesCount == other.fShortYearNamesCount &&
        fShortZodiacNamesCount == other.fShortZodiacNamesCount &&
        fAbbreviatedDayPeriodsCount == other.fAbbreviatedDayPeriodsCount &&
        fWideDayPeriodsCount == other.fWideDayPeriodsCount &&
        fNarrowDayPeriodsCount == other.fNarrowDayPeriodsCount &&
        fStandaloneAbbreviatedDayPeriodsCount == other.fStandaloneAbbreviatedDayPeriodsCount &&
        fStandaloneWideDayPeriodsCount == other.fStandaloneWideDayPeriodsCount &&
        fStandaloneNarrowDayPeriodsCount == other.fStandaloneNarrowDayPeriodsCount &&
        (uprv_memcmp(fCapitalization, other.fCapitalization, sizeof(fCapitalization))==0))
    {
        // Now compare the arrays themselves
        if (arrayCompare(fEras, other.fEras, fErasCount) &&
            arrayCompare(fEraNames, other.fEraNames, fEraNamesCount) &&
            arrayCompare(fNarrowEras, other.fNarrowEras, fNarrowErasCount) &&
            arrayCompare(fMonths, other.fMonths, fMonthsCount) &&
            arrayCompare(fShortMonths, other.fShortMonths, fShortMonthsCount) &&
            arrayCompare(fNarrowMonths, other.fNarrowMonths, fNarrowMonthsCount) &&
            arrayCompare(fStandaloneMonths, other.fStandaloneMonths, fStandaloneMonthsCount) &&
            arrayCompare(fStandaloneShortMonths, other.fStandaloneShortMonths, fStandaloneShortMonthsCount) &&
            arrayCompare(fStandaloneNarrowMonths, other.fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount) &&
            arrayCompare(fWeekdays, other.fWeekdays, fWeekdaysCount) &&
            arrayCompare(fShortWeekdays, other.fShortWeekdays, fShortWeekdaysCount) &&
            arrayCompare(fShorterWeekdays, other.fShorterWeekdays, fShorterWeekdaysCount) &&
            arrayCompare(fNarrowWeekdays, other.fNarrowWeekdays, fNarrowWeekdaysCount) &&
            arrayCompare(fStandaloneWeekdays, other.fStandaloneWeekdays, fStandaloneWeekdaysCount) &&
            arrayCompare(fStandaloneShortWeekdays, other.fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount) &&
            arrayCompare(fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount) &&
            arrayCompare(fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount) &&
            arrayCompare(fAmPms, other.fAmPms, fAmPmsCount) &&
            arrayCompare(fNarrowAmPms, other.fNarrowAmPms, fNarrowAmPmsCount) &&
            fTimeSeparator == other.fTimeSeparator &&
            arrayCompare(fQuarters, other.fQuarters, fQuartersCount) &&
            arrayCompare(fShortQuarters, other.fShortQuarters, fShortQuartersCount) &&
            arrayCompare(fStandaloneQuarters, other.fStandaloneQuarters, fStandaloneQuartersCount) &&
            arrayCompare(fStandaloneShortQuarters, other.fStandaloneShortQuarters, fStandaloneShortQuartersCount) &&
            arrayCompare(fLeapMonthPatterns, other.fLeapMonthPatterns, fLeapMonthPatternsCount) &&
            arrayCompare(fShortYearNames, other.fShortYearNames, fShortYearNamesCount) &&
            arrayCompare(fShortZodiacNames, other.fShortZodiacNames, fShortZodiacNamesCount) &&
            arrayCompare(fAbbreviatedDayPeriods, other.fAbbreviatedDayPeriods, fAbbreviatedDayPeriodsCount) &&
            arrayCompare(fWideDayPeriods, other.fWideDayPeriods, fWideDayPeriodsCount) &&
            arrayCompare(fNarrowDayPeriods, other.fNarrowDayPeriods, fNarrowDayPeriodsCount) &&
            arrayCompare(fStandaloneAbbreviatedDayPeriods, other.fStandaloneAbbreviatedDayPeriods,
                         fStandaloneAbbreviatedDayPeriodsCount) &&
            arrayCompare(fStandaloneWideDayPeriods, other.fStandaloneWideDayPeriods,
                         fStandaloneWideDayPeriodsCount) &&
            arrayCompare(fStandaloneNarrowDayPeriods, other.fStandaloneNarrowDayPeriods,
                         fStandaloneWideDayPeriodsCount))
        {
            // Compare the contents of fZoneStrings
            if (fZoneStrings == NULL && other.fZoneStrings == NULL) {
                if (fZSFLocale == other.fZSFLocale) {
                    return TRUE;
                }
            } else if (fZoneStrings != NULL && other.fZoneStrings != NULL) {
                if (fZoneStringsRowCount == other.fZoneStringsRowCount
                    && fZoneStringsColCount == other.fZoneStringsColCount) {
                    UBool cmpres = TRUE;
                    for (int32_t i = 0; (i < fZoneStringsRowCount) && cmpres; i++) {
                        cmpres = arrayCompare(fZoneStrings[i], other.fZoneStrings[i], fZoneStringsColCount);
                    }
                    return cmpres;
                }
            }
            return FALSE;
        }
    }
    return FALSE;
}

//------------------------------------------------------

const UnicodeString*
DateFormatSymbols::getEras(int32_t &count) const
{
    count = fErasCount;
    return fEras;
}

const UnicodeString*
DateFormatSymbols::getEraNames(int32_t &count) const
{
    count = fEraNamesCount;
    return fEraNames;
}

const UnicodeString*
DateFormatSymbols::getNarrowEras(int32_t &count) const
{
    count = fNarrowErasCount;
    return fNarrowEras;
}

const UnicodeString*
DateFormatSymbols::getMonths(int32_t &count) const
{
    count = fMonthsCount;
    return fMonths;
}

const UnicodeString*
DateFormatSymbols::getShortMonths(int32_t &count) const
{
    count = fShortMonthsCount;
    return fShortMonths;
}

const UnicodeString*
DateFormatSymbols::getMonths(int32_t &count, DtContextType context, DtWidthType width ) const
{
    UnicodeString *returnValue = NULL;

    switch (context) {
    case FORMAT :
        switch(width) {
        case WIDE :
            count = fMonthsCount;
            returnValue = fMonths;
            break;
        case ABBREVIATED :
        case SHORT : // no month data for this, defaults to ABBREVIATED
            count = fShortMonthsCount;
            returnValue = fShortMonths;
            break;
        case NARROW :
            count = fNarrowMonthsCount;
            returnValue = fNarrowMonths;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case STANDALONE :
        switch(width) {
        case WIDE :
            count = fStandaloneMonthsCount;
            returnValue = fStandaloneMonths;
            break;
        case ABBREVIATED :
        case SHORT : // no month data for this, defaults to ABBREVIATED
            count = fStandaloneShortMonthsCount;
            returnValue = fStandaloneShortMonths;
            break;
        case NARROW :
            count = fStandaloneNarrowMonthsCount;
            returnValue = fStandaloneNarrowMonths;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
    return returnValue;
}

const UnicodeString*
DateFormatSymbols::getWeekdays(int32_t &count) const
{
    count = fWeekdaysCount;
    return fWeekdays;
}

const UnicodeString*
DateFormatSymbols::getShortWeekdays(int32_t &count) const
{
    count = fShortWeekdaysCount;
    return fShortWeekdays;
}

const UnicodeString*
DateFormatSymbols::getWeekdays(int32_t &count, DtContextType context, DtWidthType width) const
{
    UnicodeString *returnValue = NULL;
    switch (context) {
    case FORMAT :
        switch(width) {
            case WIDE :
                count = fWeekdaysCount;
                returnValue = fWeekdays;
                break;
            case ABBREVIATED :
                count = fShortWeekdaysCount;
                returnValue = fShortWeekdays;
                break;
            case SHORT :
                count = fShorterWeekdaysCount;
                returnValue = fShorterWeekdays;
                break;
            case NARROW :
                count = fNarrowWeekdaysCount;
                returnValue = fNarrowWeekdays;
                break;
            case DT_WIDTH_COUNT :
                break;
        }
        break;
    case STANDALONE :
        switch(width) {
            case WIDE :
                count = fStandaloneWeekdaysCount;
                returnValue = fStandaloneWeekdays;
                break;
            case ABBREVIATED :
                count = fStandaloneShortWeekdaysCount;
                returnValue = fStandaloneShortWeekdays;
                break;
            case SHORT :
                count = fStandaloneShorterWeekdaysCount;
                returnValue = fStandaloneShorterWeekdays;
                break;
            case NARROW :
                count = fStandaloneNarrowWeekdaysCount;
                returnValue = fStandaloneNarrowWeekdays;
                break;
            case DT_WIDTH_COUNT :
                break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
    return returnValue;
}

const UnicodeString*
DateFormatSymbols::getQuarters(int32_t &count, DtContextType context, DtWidthType width ) const
{
    UnicodeString *returnValue = NULL;

    switch (context) {
    case FORMAT :
        switch(width) {
        case WIDE :
            count = fQuartersCount;
            returnValue = fQuarters;
            break;
        case ABBREVIATED :
        case SHORT : // no quarter data for this, defaults to ABBREVIATED
            count = fShortQuartersCount;
            returnValue = fShortQuarters;
            break;
        case NARROW :
            count = 0;
            returnValue = NULL;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case STANDALONE :
        switch(width) {
        case WIDE :
            count = fStandaloneQuartersCount;
            returnValue = fStandaloneQuarters;
            break;
        case ABBREVIATED :
        case SHORT : // no quarter data for this, defaults to ABBREVIATED
            count = fStandaloneShortQuartersCount;
            returnValue = fStandaloneShortQuarters;
            break;
        case NARROW :
            count = 0;
            returnValue = NULL;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
    return returnValue;
}

UnicodeString&
DateFormatSymbols::getTimeSeparatorString(UnicodeString& result) const
{
    // fastCopyFrom() - see assignArray comments
    return result.fastCopyFrom(fTimeSeparator);
}

const UnicodeString*
DateFormatSymbols::getAmPmStrings(int32_t &count) const
{
    count = fAmPmsCount;
    return fAmPms;
}

const UnicodeString*
DateFormatSymbols::getLeapMonthPatterns(int32_t &count) const
{
    count = fLeapMonthPatternsCount;
    return fLeapMonthPatterns;
}

const UnicodeString*
DateFormatSymbols::getYearNames(int32_t& count,
                                DtContextType /*ignored*/, DtWidthType /*ignored*/) const
{
    count = fShortYearNamesCount;
    return fShortYearNames;
}

void
DateFormatSymbols::setYearNames(const UnicodeString* yearNames, int32_t count,
                                DtContextType context, DtWidthType width)
{
    if (context == FORMAT && width == ABBREVIATED) {
        if (fShortYearNames) {
            delete[] fShortYearNames;
        }
        fShortYearNames = newUnicodeStringArray(count);
        uprv_arrayCopy(yearNames, fShortYearNames, count);
        fShortYearNamesCount = count;
    }
}

const UnicodeString*
DateFormatSymbols::getZodiacNames(int32_t& count,
                                DtContextType /*ignored*/, DtWidthType /*ignored*/) const
{
    count = fShortZodiacNamesCount;
    return fShortZodiacNames;
}

void
DateFormatSymbols::setZodiacNames(const UnicodeString* zodiacNames, int32_t count,
                                DtContextType context, DtWidthType width)
{
    if (context == FORMAT && width == ABBREVIATED) {
        if (fShortZodiacNames) {
            delete[] fShortZodiacNames;
        }
        fShortZodiacNames = newUnicodeStringArray(count);
        uprv_arrayCopy(zodiacNames, fShortZodiacNames, count);
        fShortZodiacNamesCount = count;
    }
}

//------------------------------------------------------

void
DateFormatSymbols::setEras(const UnicodeString* erasArray, int32_t count)
{
    // delete the old list if we own it
    if (fEras)
        delete[] fEras;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fEras = newUnicodeStringArray(count);
    uprv_arrayCopy(erasArray,fEras,  count);
    fErasCount = count;
}

void
DateFormatSymbols::setEraNames(const UnicodeString* eraNamesArray, int32_t count)
{
    // delete the old list if we own it
    if (fEraNames)
        delete[] fEraNames;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fEraNames = newUnicodeStringArray(count);
    uprv_arrayCopy(eraNamesArray,fEraNames,  count);
    fEraNamesCount = count;
}

void
DateFormatSymbols::setNarrowEras(const UnicodeString* narrowErasArray, int32_t count)
{
    // delete the old list if we own it
    if (fNarrowEras)
        delete[] fNarrowEras;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fNarrowEras = newUnicodeStringArray(count);
    uprv_arrayCopy(narrowErasArray,fNarrowEras,  count);
    fNarrowErasCount = count;
}

void
DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count)
{
    // delete the old list if we own it
    if (fMonths)
        delete[] fMonths;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fMonths = newUnicodeStringArray(count);
    uprv_arrayCopy( monthsArray,fMonths,count);
    fMonthsCount = count;
}

void
DateFormatSymbols::setShortMonths(const UnicodeString* shortMonthsArray, int32_t count)
{
    // delete the old list if we own it
    if (fShortMonths)
        delete[] fShortMonths;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fShortMonths = newUnicodeStringArray(count);
    uprv_arrayCopy(shortMonthsArray,fShortMonths,  count);
    fShortMonthsCount = count;
}

void
DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count, DtContextType context, DtWidthType width)
{
    // delete the old list if we own it
    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)

    switch (context) {
    case FORMAT :
        switch (width) {
        case WIDE :
            if (fMonths)
                delete[] fMonths;
            fMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fMonths,count);
            fMonthsCount = count;
            break;
        case ABBREVIATED :
            if (fShortMonths)
                delete[] fShortMonths;
            fShortMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fShortMonths,count);
            fShortMonthsCount = count;
            break;
        case NARROW :
            if (fNarrowMonths)
                delete[] fNarrowMonths;
            fNarrowMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fNarrowMonths,count);
            fNarrowMonthsCount = count;
            break;
        default :
            break;
        }
        break;
    case STANDALONE :
        switch (width) {
        case WIDE :
            if (fStandaloneMonths)
                delete[] fStandaloneMonths;
            fStandaloneMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fStandaloneMonths,count);
            fStandaloneMonthsCount = count;
            break;
        case ABBREVIATED :
            if (fStandaloneShortMonths)
                delete[] fStandaloneShortMonths;
            fStandaloneShortMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fStandaloneShortMonths,count);
            fStandaloneShortMonthsCount = count;
            break;
        case NARROW :
           if (fStandaloneNarrowMonths)
                delete[] fStandaloneNarrowMonths;
            fStandaloneNarrowMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fStandaloneNarrowMonths,count);
            fStandaloneNarrowMonthsCount = count;
            break;
        default :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
}

void DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count)
{
    // delete the old list if we own it
    if (fWeekdays)
        delete[] fWeekdays;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fWeekdays = newUnicodeStringArray(count);
    uprv_arrayCopy(weekdaysArray,fWeekdays,count);
    fWeekdaysCount = count;
}

void
DateFormatSymbols::setShortWeekdays(const UnicodeString* shortWeekdaysArray, int32_t count)
{
    // delete the old list if we own it
    if (fShortWeekdays)
        delete[] fShortWeekdays;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fShortWeekdays = newUnicodeStringArray(count);
    uprv_arrayCopy(shortWeekdaysArray, fShortWeekdays, count);
    fShortWeekdaysCount = count;
}

void
DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count, DtContextType context, DtWidthType width)
{
    // delete the old list if we own it
    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)

    switch (context) {
    case FORMAT :
        switch (width) {
        case WIDE :
            if (fWeekdays)
                delete[] fWeekdays;
            fWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fWeekdays, count);
            fWeekdaysCount = count;
            break;
        case ABBREVIATED :
            if (fShortWeekdays)
                delete[] fShortWeekdays;
            fShortWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fShortWeekdays, count);
            fShortWeekdaysCount = count;
            break;
        case SHORT :
            if (fShorterWeekdays)
                delete[] fShorterWeekdays;
            fShorterWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fShorterWeekdays, count);
            fShorterWeekdaysCount = count;
            break;
        case NARROW :
            if (fNarrowWeekdays)
                delete[] fNarrowWeekdays;
            fNarrowWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fNarrowWeekdays, count);
            fNarrowWeekdaysCount = count;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case STANDALONE :
        switch (width) {
        case WIDE :
            if (fStandaloneWeekdays)
                delete[] fStandaloneWeekdays;
            fStandaloneWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fStandaloneWeekdays, count);
            fStandaloneWeekdaysCount = count;
            break;
        case ABBREVIATED :
            if (fStandaloneShortWeekdays)
                delete[] fStandaloneShortWeekdays;
            fStandaloneShortWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fStandaloneShortWeekdays, count);
            fStandaloneShortWeekdaysCount = count;
            break;
        case SHORT :
            if (fStandaloneShorterWeekdays)
                delete[] fStandaloneShorterWeekdays;
            fStandaloneShorterWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fStandaloneShorterWeekdays, count);
            fStandaloneShorterWeekdaysCount = count;
            break;
        case NARROW :
            if (fStandaloneNarrowWeekdays)
                delete[] fStandaloneNarrowWeekdays;
            fStandaloneNarrowWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fStandaloneNarrowWeekdays, count);
            fStandaloneNarrowWeekdaysCount = count;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
}

void
DateFormatSymbols::setQuarters(const UnicodeString* quartersArray, int32_t count, DtContextType context, DtWidthType width)
{
    // delete the old list if we own it
    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)

    switch (context) {
    case FORMAT :
        switch (width) {
        case WIDE :
            if (fQuarters)
                delete[] fQuarters;
            fQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fQuarters,count);
            fQuartersCount = count;
            break;
        case ABBREVIATED :
            if (fShortQuarters)
                delete[] fShortQuarters;
            fShortQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fShortQuarters,count);
            fShortQuartersCount = count;
            break;
        case NARROW :
        /*
            if (fNarrowQuarters)
                delete[] fNarrowQuarters;
            fNarrowQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fNarrowQuarters,count);
            fNarrowQuartersCount = count;
        */
            break;
        default :
            break;
        }
        break;
    case STANDALONE :
        switch (width) {
        case WIDE :
            if (fStandaloneQuarters)
                delete[] fStandaloneQuarters;
            fStandaloneQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fStandaloneQuarters,count);
            fStandaloneQuartersCount = count;
            break;
        case ABBREVIATED :
            if (fStandaloneShortQuarters)
                delete[] fStandaloneShortQuarters;
            fStandaloneShortQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fStandaloneShortQuarters,count);
            fStandaloneShortQuartersCount = count;
            break;
        case NARROW :
        /*
           if (fStandaloneNarrowQuarters)
                delete[] fStandaloneNarrowQuarters;
            fStandaloneNarrowQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fStandaloneNarrowQuarters,count);
            fStandaloneNarrowQuartersCount = count;
        */
            break;
        default :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
}

void
DateFormatSymbols::setAmPmStrings(const UnicodeString* amPmsArray, int32_t count)
{
    // delete the old list if we own it
    if (fAmPms) delete[] fAmPms;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fAmPms = newUnicodeStringArray(count);
    uprv_arrayCopy(amPmsArray,fAmPms,count);
    fAmPmsCount = count;
}

void
DateFormatSymbols::setTimeSeparatorString(const UnicodeString& newTimeSeparator)
{
    fTimeSeparator = newTimeSeparator;
}

const UnicodeString**
DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const
{
    const UnicodeString **result = NULL;

    umtx_lock(&LOCK);
    if (fZoneStrings == NULL) {
        if (fLocaleZoneStrings == NULL) {
            ((DateFormatSymbols*)this)->initZoneStringsArray();
        }
        result = (const UnicodeString**)fLocaleZoneStrings;
    } else {
        result = (const UnicodeString**)fZoneStrings;
    }
    rowCount = fZoneStringsRowCount;
    columnCount = fZoneStringsColCount;
    umtx_unlock(&LOCK);

    return result;
}

// For now, we include all zones
#define ZONE_SET UCAL_ZONE_TYPE_ANY

// This code must be called within a synchronized block
void
DateFormatSymbols::initZoneStringsArray(void) {
    if (fZoneStrings != NULL || fLocaleZoneStrings != NULL) {
        return;
    }

    UErrorCode status = U_ZERO_ERROR;

    StringEnumeration *tzids = NULL;
    UnicodeString ** zarray = NULL;
    TimeZoneNames *tzNames = NULL;
    int32_t rows = 0;

    static const UTimeZoneNameType TYPES[] = {
        UTZNM_LONG_STANDARD, UTZNM_SHORT_STANDARD,
        UTZNM_LONG_DAYLIGHT, UTZNM_SHORT_DAYLIGHT
    };
    static const int32_t NUM_TYPES = 4;

    do { // dummy do-while

        tzids = TimeZone::createTimeZoneIDEnumeration(ZONE_SET, NULL, NULL, status);
        rows = tzids->count(status);
        if (U_FAILURE(status)) {
            break;
        }

        // Allocate array
        int32_t size = rows * sizeof(UnicodeString*);
        zarray = (UnicodeString**)uprv_malloc(size);
        if (zarray == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            break;
        }
        uprv_memset(zarray, 0, size);

        tzNames = TimeZoneNames::createInstance(fZSFLocale, status);
        tzNames->loadAllDisplayNames(status);
        if (U_FAILURE(status)) { break; }

        const UnicodeString *tzid;
        int32_t i = 0;
        UDate now = Calendar::getNow();
        UnicodeString tzDispName;

        while ((tzid = tzids->snext(status)) != 0) {
            if (U_FAILURE(status)) {
                break;
            }

            zarray[i] = new UnicodeString[5];
            if (zarray[i] == NULL) {
                status = U_MEMORY_ALLOCATION_ERROR;
                break;
            }

            zarray[i][0].setTo(*tzid);
            tzNames->getDisplayNames(*tzid, TYPES, NUM_TYPES, now, zarray[i]+1, status);
            i++;
        }

    } while (FALSE);

    if (U_FAILURE(status)) {
        if (zarray) {
            for (int32_t i = 0; i < rows; i++) {
                if (zarray[i]) {
                    delete[] zarray[i];
                }
            }
            uprv_free(zarray);
            zarray = NULL;
        }
    }

    if (tzNames) {
        delete tzNames;
    }
    if (tzids) {
        delete tzids;
    }

    fLocaleZoneStrings = zarray;
    fZoneStringsRowCount = rows;
    fZoneStringsColCount = 1 + NUM_TYPES;
}

void
DateFormatSymbols::setZoneStrings(const UnicodeString* const *strings, int32_t rowCount, int32_t columnCount)
{
    // since deleting a 2-d array is a pain in the butt, we offload that task to
    // a separate function
    disposeZoneStrings();
    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fZoneStringsRowCount = rowCount;
    fZoneStringsColCount = columnCount;
    createZoneStrings((const UnicodeString**)strings);
}

//------------------------------------------------------

const char16_t * U_EXPORT2
DateFormatSymbols::getPatternUChars(void)
{
    return gPatternChars;
}

UDateFormatField U_EXPORT2
DateFormatSymbols::getPatternCharIndex(UChar c) {
    const UChar *p = u_strchr(gPatternChars, c);
    if (p == NULL) {
        return UDAT_FIELD_COUNT;
    } else {
        return static_cast<UDateFormatField>(p - gPatternChars);
    }
}

static const uint64_t kNumericFieldsAlways =
    ((uint64_t)1 << UDAT_YEAR_FIELD) |                      // y
    ((uint64_t)1 << UDAT_DATE_FIELD) |                      // d
    ((uint64_t)1 << UDAT_HOUR_OF_DAY1_FIELD) |              // k
    ((uint64_t)1 << UDAT_HOUR_OF_DAY0_FIELD) |              // H
    ((uint64_t)1 << UDAT_MINUTE_FIELD) |                    // m
    ((uint64_t)1 << UDAT_SECOND_FIELD) |                    // s
    ((uint64_t)1 << UDAT_FRACTIONAL_SECOND_FIELD) |         // S
    ((uint64_t)1 << UDAT_DAY_OF_YEAR_FIELD) |               // D
    ((uint64_t)1 << UDAT_DAY_OF_WEEK_IN_MONTH_FIELD) |      // F
    ((uint64_t)1 << UDAT_WEEK_OF_YEAR_FIELD) |              // w
    ((uint64_t)1 << UDAT_WEEK_OF_MONTH_FIELD) |             // W
    ((uint64_t)1 << UDAT_HOUR1_FIELD) |                     // h
    ((uint64_t)1 << UDAT_HOUR0_FIELD) |                     // K
    ((uint64_t)1 << UDAT_YEAR_WOY_FIELD) |                  // Y
    ((uint64_t)1 << UDAT_EXTENDED_YEAR_FIELD) |             // u
    ((uint64_t)1 << UDAT_JULIAN_DAY_FIELD) |                // g
    ((uint64_t)1 << UDAT_MILLISECONDS_IN_DAY_FIELD) |       // A
    ((uint64_t)1 << UDAT_RELATED_YEAR_FIELD);               // r

static const uint64_t kNumericFieldsForCount12 =
    ((uint64_t)1 << UDAT_MONTH_FIELD) |                     // M or MM
    ((uint64_t)1 << UDAT_DOW_LOCAL_FIELD) |                 // e or ee
    ((uint64_t)1 << UDAT_STANDALONE_DAY_FIELD) |            // c or cc
    ((uint64_t)1 << UDAT_STANDALONE_MONTH_FIELD) |          // L or LL
    ((uint64_t)1 << UDAT_QUARTER_FIELD) |                   // Q or QQ
    ((uint64_t)1 << UDAT_STANDALONE_QUARTER_FIELD);         // q or qq

UBool U_EXPORT2
DateFormatSymbols::isNumericField(UDateFormatField f, int32_t count) {
    if (f == UDAT_FIELD_COUNT) {
        return FALSE;
    }
    uint64_t flag = ((uint64_t)1 << f);
    return ((kNumericFieldsAlways & flag) != 0 || ((kNumericFieldsForCount12 & flag) != 0 && count < 3));
}

UBool U_EXPORT2
DateFormatSymbols::isNumericPatternChar(UChar c, int32_t count) {
    return isNumericField(getPatternCharIndex(c), count);
}

//------------------------------------------------------

UnicodeString&
DateFormatSymbols::getLocalPatternChars(UnicodeString& result) const
{
    // fastCopyFrom() - see assignArray comments
    return result.fastCopyFrom(fLocalPatternChars);
}

//------------------------------------------------------

void
DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChars)
{
    fLocalPatternChars = newLocalPatternChars;
}

//------------------------------------------------------

namespace {

// Constants declarations
static const UChar kCalendarAliasPrefixUChar[] = {
    SOLIDUS, CAP_L, CAP_O, CAP_C, CAP_A, CAP_L, CAP_E, SOLIDUS,
    LOW_C, LOW_A, LOW_L, LOW_E, LOW_N, LOW_D, LOW_A, LOW_R, SOLIDUS
};
static const UChar kGregorianTagUChar[] = {
    LOW_G, LOW_R, LOW_E, LOW_G, LOW_O, LOW_R, LOW_I, LOW_A, LOW_N
};
static const UChar kVariantTagUChar[] = {
    PERCENT, LOW_V, LOW_A, LOW_R, LOW_I, LOW_A, LOW_N, LOW_T
};
static const UChar kLeapTagUChar[] = {
    LOW_L, LOW_E, LOW_A, LOW_P
};
static const UChar kCyclicNameSetsTagUChar[] = {
    LOW_C, LOW_Y, LOW_C, LOW_L, LOW_I, LOW_C, CAP_N, LOW_A, LOW_M, LOW_E, CAP_S, LOW_E, LOW_T, LOW_S
};
static const UChar kYearsTagUChar[] = {
    SOLIDUS, LOW_Y, LOW_E, LOW_A, LOW_R, LOW_S
};
static const UChar kZodiacsUChar[] = {
    SOLIDUS, LOW_Z, LOW_O, LOW_D, LOW_I, LOW_A, LOW_C, LOW_S
};
static const UChar kDayPartsTagUChar[] = {
    SOLIDUS, LOW_D, LOW_A, LOW_Y, CAP_P, LOW_A, LOW_R, LOW_T, LOW_S
};
static const UChar kFormatTagUChar[] = {
    SOLIDUS, LOW_F, LOW_O, LOW_R, LOW_M, LOW_A, LOW_T
};
static const UChar kAbbrTagUChar[] = {
    SOLIDUS, LOW_A, LOW_B, LOW_B, LOW_R, LOW_E, LOW_V, LOW_I, LOW_A, LOW_T, LOW_E, LOW_D
};

// ResourceSink to enumerate all calendar resources
struct CalendarDataSink : public ResourceSink {

    // Enum which specifies the type of alias received, or no alias
    enum AliasType {
        SAME_CALENDAR,
        DIFFERENT_CALENDAR,
        GREGORIAN,
        NONE
    };

    // Data structures to store resources from the current resource bundle
    Hashtable arrays;
    Hashtable arraySizes;
    Hashtable maps;
    /** 
     * Whenever there are aliases, the same object will be added twice to 'map'.
     * To avoid double deletion, 'maps' won't take ownership of the objects. Instead,
     * 'mapRefs' will own them and will delete them when CalendarDataSink is deleted.
     */
    UVector mapRefs;

    // Paths and the aliases they point to
    UVector aliasPathPairs;

    // Current and next calendar resource table which should be loaded
    UnicodeString currentCalendarType;
    UnicodeString nextCalendarType;

    // Resources to visit when enumerating fallback calendars
    LocalPointer<UVector> resourcesToVisit;

    // Alias' relative path populated whenever an alias is read
    UnicodeString aliasRelativePath;

    // Initializes CalendarDataSink with default values
    CalendarDataSink(UErrorCode& status)
    :   arrays(FALSE, status), arraySizes(FALSE, status), maps(FALSE, status),
        mapRefs(deleteHashtable, NULL, 10, status),
        aliasPathPairs(uprv_deleteUObject, uhash_compareUnicodeString, status),
        currentCalendarType(), nextCalendarType(),
        resourcesToVisit(NULL), aliasRelativePath() {
        if (U_FAILURE(status)) { return; }
    }
    virtual ~CalendarDataSink();

    // Configure the CalendarSink to visit all the resources
    void visitAllResources() {
        resourcesToVisit.adoptInstead(NULL);
    }

    // Actions to be done before enumerating
    void preEnumerate(const UnicodeString &calendarType) {
        currentCalendarType = calendarType;
        nextCalendarType.setToBogus();
        aliasPathPairs.removeAllElements();
    }

    virtual void put(const char *key, ResourceValue &value, UBool, UErrorCode &errorCode) {
        if (U_FAILURE(errorCode)) { return; }
        U_ASSERT(!currentCalendarType.isEmpty());

        // Stores the resources to visit on the next calendar.
        LocalPointer<UVector> resourcesToVisitNext(NULL);
        ResourceTable calendarData = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) { return; }

        // Enumerate all resources for this calendar
        for (int i = 0; calendarData.getKeyAndValue(i, key, value); i++) {
            UnicodeString keyUString(key, -1, US_INV);

            // == Handle aliases ==
            AliasType aliasType = processAliasFromValue(keyUString, value, errorCode);
            if (U_FAILURE(errorCode)) { return; }
            if (aliasType == GREGORIAN) {
                // Ignore aliases to the gregorian calendar, all of its resources will be loaded anyway.
                continue;

            } else if (aliasType == DIFFERENT_CALENDAR) {
                // Whenever an alias to the next calendar (except gregorian) is encountered, register the
                // calendar type it's pointing to
                if (resourcesToVisitNext.isNull()) {
                    resourcesToVisitNext
                        .adoptInsteadAndCheckErrorCode(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, errorCode),
                                                       errorCode);
                    if (U_FAILURE(errorCode)) { return; }
                }
                LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);
                resourcesToVisitNext->addElement(aliasRelativePathCopy.getAlias(), errorCode);
                if (U_FAILURE(errorCode)) { return; }
                // Only release ownership after resourcesToVisitNext takes it (no error happened):
                aliasRelativePathCopy.orphan();
                continue;

            } else if (aliasType == SAME_CALENDAR) {
                // Register same-calendar alias
                if (arrays.get(aliasRelativePath) == NULL && maps.get(aliasRelativePath) == NULL) {
                    LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);
                    aliasPathPairs.addElement(aliasRelativePathCopy.getAlias(), errorCode);
                    if (U_FAILURE(errorCode)) { return; }
                    // Only release ownership after aliasPathPairs takes it (no error happened):
                    aliasRelativePathCopy.orphan();
                    LocalPointer<UnicodeString> keyUStringCopy(new UnicodeString(keyUString), errorCode);
                    aliasPathPairs.addElement(keyUStringCopy.getAlias(), errorCode);
                    if (U_FAILURE(errorCode)) { return; }
                    // Only release ownership after aliasPathPairs takes it (no error happened):
                    keyUStringCopy.orphan();
                }
                continue;
            }

            // Only visit the resources that were referenced by an alias on the previous calendar
            // (AmPmMarkersAbbr is an exception).
            if (!resourcesToVisit.isNull() && !resourcesToVisit->isEmpty() && !resourcesToVisit->contains(&keyUString)
                && uprv_strcmp(key, gAmPmMarkersAbbrTag) != 0) { continue; }

            // == Handle data ==
            if (uprv_strcmp(key, gAmPmMarkersTag) == 0
                || uprv_strcmp(key, gAmPmMarkersAbbrTag) == 0
                || uprv_strcmp(key, gAmPmMarkersNarrowTag) == 0) {
                if (arrays.get(keyUString) == NULL) {
                    ResourceArray resourceArray = value.getArray(errorCode);
                    int32_t arraySize = resourceArray.getSize();
                    LocalArray<UnicodeString> stringArray(new UnicodeString[arraySize], errorCode);
                    value.getStringArray(stringArray.getAlias(), arraySize, errorCode);
                    arrays.put(keyUString, stringArray.orphan(), errorCode);
                    arraySizes.puti(keyUString, arraySize, errorCode);
                    if (U_FAILURE(errorCode)) { return; }
                }
            } else if (uprv_strcmp(key, gErasTag) == 0
                       || uprv_strcmp(key, gDayNamesTag) == 0
                       || uprv_strcmp(key, gMonthNamesTag) == 0
                       || uprv_strcmp(key, gQuartersTag) == 0
                       || uprv_strcmp(key, gDayPeriodTag) == 0
                       || uprv_strcmp(key, gMonthPatternsTag) == 0
                       || uprv_strcmp(key, gCyclicNameSetsTag) == 0) {
                processResource(keyUString, key, value, errorCode);
            }
        }

        // Apply same-calendar aliases
        UBool modified;
        do {
            modified = false;
            for (int32_t i = 0; i < aliasPathPairs.size();) {
                UBool mod = false;
                UnicodeString *alias = (UnicodeString*)aliasPathPairs[i];
                UnicodeString *aliasArray;
                Hashtable *aliasMap;
                if ((aliasArray = (UnicodeString*)arrays.get(*alias)) != NULL) {
                    UnicodeString *path = (UnicodeString*)aliasPathPairs[i + 1];
                    if (arrays.get(*path) == NULL) {
                        // Clone the array
                        int32_t aliasArraySize = arraySizes.geti(*alias);
                        LocalArray<UnicodeString> aliasArrayCopy(new UnicodeString[aliasArraySize], errorCode);
                        if (U_FAILURE(errorCode)) { return; }
                        uprv_arrayCopy(aliasArray, aliasArrayCopy.getAlias(), aliasArraySize);
                        // Put the array on the 'arrays' map
                        arrays.put(*path, aliasArrayCopy.orphan(), errorCode);
                        arraySizes.puti(*path, aliasArraySize, errorCode);
                    }
                    if (U_FAILURE(errorCode)) { return; }
                    mod = true;
                } else if ((aliasMap = (Hashtable*)maps.get(*alias)) != NULL) {
                    UnicodeString *path = (UnicodeString*)aliasPathPairs[i + 1];
                    if (maps.get(*path) == NULL) {
                        maps.put(*path, aliasMap, errorCode);
                    }
                    if (U_FAILURE(errorCode)) { return; }
                    mod = true;
                }
                if (mod) {
                    aliasPathPairs.removeElementAt(i + 1);
                    aliasPathPairs.removeElementAt(i);
                    modified = true;
                } else {
                    i += 2;
                }
            }
        } while (modified && !aliasPathPairs.isEmpty());

        // Set the resources to visit on the next calendar
        if (!resourcesToVisitNext.isNull()) {
            resourcesToVisit.moveFrom(resourcesToVisitNext);
        }
    }

    // Process the nested resource bundle tables
    void processResource(UnicodeString &path, const char *key, ResourceValue &value, UErrorCode &errorCode) {
        if (U_FAILURE(errorCode)) return;

        ResourceTable table = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) return;
        Hashtable* stringMap = NULL;

        // Iterate over all the elements of the table and add them to the map
        for (int i = 0; table.getKeyAndValue(i, key, value); i++) {
            UnicodeString keyUString(key, -1, US_INV);

            // Ignore '%variant' keys
            if (keyUString.endsWith(kVariantTagUChar, UPRV_LENGTHOF(kVariantTagUChar))) {
                continue;
            }

            // == Handle String elements ==
            if (value.getType() == URES_STRING) {
                // We are on a leaf, store the map elements into the stringMap
                if (i == 0) {
                    LocalPointer<Hashtable> stringMapPtr(new Hashtable(FALSE, errorCode), errorCode);
                    stringMap = stringMapPtr.getAlias();
                    maps.put(path, stringMap, errorCode);
                    // mapRefs will take ownership of 'stringMap':
                    mapRefs.addElement(stringMap, errorCode);
                    if (U_FAILURE(errorCode)) { return; }
                    // Only release ownership after mapRefs takes it (no error happened):
                    stringMapPtr.orphan();
                    stringMap->setValueDeleter(uprv_deleteUObject);
                }
                U_ASSERT(stringMap != NULL);
                int32_t valueStringSize;
                const UChar *valueString = value.getString(valueStringSize, errorCode);
                if (U_FAILURE(errorCode)) { return; }
                LocalPointer<UnicodeString> valueUString(new UnicodeString(TRUE, valueString, valueStringSize), errorCode);
                stringMap->put(keyUString, valueUString.orphan(), errorCode);
                if (U_FAILURE(errorCode)) { return; }
                continue;
            }
            U_ASSERT(stringMap == NULL);

            // Store the current path's length and append the current key to the path.
            int32_t pathLength = path.length();
            path.append(SOLIDUS).append(keyUString);

            // In cyclicNameSets ignore everything but years/format/abbreviated
            // and zodiacs/format/abbreviated
            if (path.startsWith(kCyclicNameSetsTagUChar, UPRV_LENGTHOF(kCyclicNameSetsTagUChar))) {
                UBool skip = TRUE;
                int32_t startIndex = UPRV_LENGTHOF(kCyclicNameSetsTagUChar);
                int32_t length = 0;
                if (startIndex == path.length()
                    || path.compare(startIndex, (length = UPRV_LENGTHOF(kZodiacsUChar)), kZodiacsUChar, 0, UPRV_LENGTHOF(kZodiacsUChar)) == 0
                    || path.compare(startIndex, (length = UPRV_LENGTHOF(kYearsTagUChar)), kYearsTagUChar, 0, UPRV_LENGTHOF(kYearsTagUChar)) == 0
                    || path.compare(startIndex, (length = UPRV_LENGTHOF(kDayPartsTagUChar)), kDayPartsTagUChar, 0, UPRV_LENGTHOF(kDayPartsTagUChar)) == 0) {
                    startIndex += length;
                    length = 0;
                    if (startIndex == path.length()
                        || path.compare(startIndex, (length = UPRV_LENGTHOF(kFormatTagUChar)), kFormatTagUChar, 0, UPRV_LENGTHOF(kFormatTagUChar)) == 0) {
                        startIndex += length;
                        length = 0;
                        if (startIndex == path.length()
                            || path.compare(startIndex, (length = UPRV_LENGTHOF(kAbbrTagUChar)), kAbbrTagUChar, 0, UPRV_LENGTHOF(kAbbrTagUChar)) == 0) {
                            skip = FALSE;
                        }
                    }
                }
                if (skip) {
                    // Drop the latest key on the path and continue
                    path.retainBetween(0, pathLength);
                    continue;
                }
            }

            // == Handle aliases ==
            if (arrays.get(path) != NULL || maps.get(path) != NULL) {
                // Drop the latest key on the path and continue
                path.retainBetween(0, pathLength);
                continue;
            }

            AliasType aliasType = processAliasFromValue(path, value, errorCode);
            if (U_FAILURE(errorCode)) { return; }
            if (aliasType == SAME_CALENDAR) {
                // Store the alias path and the current path on aliasPathPairs
                LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);
                aliasPathPairs.addElement(aliasRelativePathCopy.getAlias(), errorCode);
                if (U_FAILURE(errorCode)) { return; }
                // Only release ownership after aliasPathPairs takes it (no error happened):
                aliasRelativePathCopy.orphan();
                LocalPointer<UnicodeString> pathCopy(new UnicodeString(path), errorCode);
                aliasPathPairs.addElement(pathCopy.getAlias(), errorCode);
                if (U_FAILURE(errorCode)) { return; }
                // Only release ownership after aliasPathPairs takes it (no error happened):
                pathCopy.orphan();

                // Drop the latest key on the path and continue
                path.retainBetween(0, pathLength);
                continue;
            }
            U_ASSERT(aliasType == NONE);

            // == Handle data ==
            if (value.getType() == URES_ARRAY) {
                // We are on a leaf, store the array
                ResourceArray rDataArray = value.getArray(errorCode);
                int32_t dataArraySize = rDataArray.getSize();
                LocalArray<UnicodeString> dataArray(new UnicodeString[dataArraySize], errorCode);
                value.getStringArray(dataArray.getAlias(), dataArraySize, errorCode);
                arrays.put(path, dataArray.orphan(), errorCode);
                arraySizes.puti(path, dataArraySize, errorCode);
                if (U_FAILURE(errorCode)) { return; }
            } else if (value.getType() == URES_TABLE) {
                // We are not on a leaf, recursively process the subtable.
                processResource(path, key, value, errorCode);
                if (U_FAILURE(errorCode)) { return; }
            }

            // Drop the latest key on the path
            path.retainBetween(0, pathLength);
        }
    }

    // Populates an AliasIdentifier with the alias information contained on the UResource.Value.
    AliasType processAliasFromValue(UnicodeString &currentRelativePath, ResourceValue &value,
                                    UErrorCode &errorCode) {
        if (U_FAILURE(errorCode)) { return NONE; }

        if (value.getType() == URES_ALIAS) {
            int32_t aliasPathSize;
            const UChar* aliasPathUChar = value.getAliasString(aliasPathSize, errorCode);
            if (U_FAILURE(errorCode)) { return NONE; }
            UnicodeString aliasPath(aliasPathUChar, aliasPathSize);
            const int32_t aliasPrefixLength = UPRV_LENGTHOF(kCalendarAliasPrefixUChar);
            if (aliasPath.startsWith(kCalendarAliasPrefixUChar, aliasPrefixLength)
                && aliasPath.length() > aliasPrefixLength) {
                int32_t typeLimit = aliasPath.indexOf(SOLIDUS, aliasPrefixLength);
                if (typeLimit > aliasPrefixLength) {
                    const UnicodeString aliasCalendarType =
                        aliasPath.tempSubStringBetween(aliasPrefixLength, typeLimit);
                    aliasRelativePath.setTo(aliasPath, typeLimit + 1, aliasPath.length());

                    if (currentCalendarType == aliasCalendarType
                        && currentRelativePath != aliasRelativePath) {
                        // If we have an alias to the same calendar, the path to the resource must be different
                        return SAME_CALENDAR;

                    } else if (currentCalendarType != aliasCalendarType
                               && currentRelativePath == aliasRelativePath) {
                        // If we have an alias to a different calendar, the path to the resource must be the same
                        if (aliasCalendarType.compare(kGregorianTagUChar, UPRV_LENGTHOF(kGregorianTagUChar)) == 0) {
                            return GREGORIAN;
                        } else if (nextCalendarType.isBogus()) {
                            nextCalendarType = aliasCalendarType;
                            return DIFFERENT_CALENDAR;
                        } else if (nextCalendarType == aliasCalendarType) {
                            return DIFFERENT_CALENDAR;
                        }
                    }
                }
            }
            errorCode = U_INTERNAL_PROGRAM_ERROR;
            return NONE;
        }
        return NONE;
    }

    // Deleter function to be used by 'arrays'
    static void U_CALLCONV deleteUnicodeStringArray(void *uArray) {
        delete[] static_cast<UnicodeString *>(uArray);
    }

    // Deleter function to be used by 'maps'
    static void U_CALLCONV deleteHashtable(void *table) {
        delete static_cast<Hashtable *>(table);
    }
};
// Virtual destructors have to be defined out of line
CalendarDataSink::~CalendarDataSink() {
    arrays.setValueDeleter(deleteUnicodeStringArray);
}
}

//------------------------------------------------------

static void
initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortSize numStr, LastResortSize strLen, UErrorCode &status) {
    if (U_SUCCESS(status)) {
        length = numStr;
        *field = newUnicodeStringArray((size_t)numStr);
        if (*field) {
            for(int32_t i = 0; i<length; i++) {
                // readonly aliases - all "data" strings are constant
                // -1 as length for variable-length strings (gLastResortDayNames[0] is empty)
                (*(field)+i)->setTo(TRUE, data+(i*((int32_t)strLen)), -1);
            }
        }
        else {
            length = 0;
            status = U_MEMORY_ALLOCATION_ERROR;
        }
    }
}

static void
initField(UnicodeString **field, int32_t& length, CalendarDataSink &sink, CharString &key, UErrorCode &status) {
    if (U_SUCCESS(status)) {
        UnicodeString keyUString(key.data(), -1, US_INV);
        UnicodeString* array = static_cast<UnicodeString*>(sink.arrays.get(keyUString));

        if (array != NULL) {
            length = sink.arraySizes.geti(keyUString);
            *field = array;
            // DateFormatSymbols takes ownership of the array:
            sink.arrays.remove(keyUString);
        } else {
            length = 0;
            status = U_MISSING_RESOURCE_ERROR;
        }
    }
}

static void
initField(UnicodeString **field, int32_t& length, CalendarDataSink &sink, CharString &key, int32_t arrayOffset, UErrorCode &status) {
    if (U_SUCCESS(status)) {
        UnicodeString keyUString(key.data(), -1, US_INV);
        UnicodeString* array = static_cast<UnicodeString*>(sink.arrays.get(keyUString));

        if (array != NULL) {
            int32_t arrayLength = sink.arraySizes.geti(keyUString);
            length = arrayLength + arrayOffset;
            *field = new UnicodeString[length];
            if (*field == NULL) {
                status = U_MEMORY_ALLOCATION_ERROR;
                return;
            }
            uprv_arrayCopy(array, 0, *field, arrayOffset, arrayLength);
        } else {
            length = 0;
            status = U_MISSING_RESOURCE_ERROR;
        }
    }
}

static void
initLeapMonthPattern(UnicodeString *field, int32_t index, CalendarDataSink &sink, CharString &path, UErrorCode &status) {
    field[index].remove();
    if (U_SUCCESS(status)) {
        UnicodeString pathUString(path.data(), -1, US_INV);
        Hashtable *leapMonthTable = static_cast<Hashtable*>(sink.maps.get(pathUString));
        if (leapMonthTable != NULL) {
            UnicodeString leapLabel(FALSE, kLeapTagUChar, UPRV_LENGTHOF(kLeapTagUChar));
            UnicodeString *leapMonthPattern = static_cast<UnicodeString*>(leapMonthTable->get(leapLabel));
            if (leapMonthPattern != NULL) {
                field[index].fastCopyFrom(*leapMonthPattern);
            } else {
                field[index].setToBogus();
            }
            return;
        }
        status = U_MISSING_RESOURCE_ERROR;
    }
}

static CharString
&buildResourcePath(CharString &path, const char* segment1, UErrorCode &errorCode) {
    return path.clear().append(segment1, -1, errorCode);
}

static CharString
&buildResourcePath(CharString &path, const char* segment1, const char* segment2,
                   UErrorCode &errorCode) {
    return buildResourcePath(path, segment1, errorCode).append('/', errorCode)
                                                       .append(segment2, -1, errorCode);
}

static CharString
&buildResourcePath(CharString &path, const char* segment1, const char* segment2,
                   const char* segment3, UErrorCode &errorCode) {
    return buildResourcePath(path, segment1, segment2, errorCode).append('/', errorCode)
                                                                 .append(segment3, -1, errorCode);
}

static CharString
&buildResourcePath(CharString &path, const char* segment1, const char* segment2,
                   const char* segment3, const char* segment4, UErrorCode &errorCode) {
    return buildResourcePath(path, segment1, segment2, segment3, errorCode).append('/', errorCode)
                                                                           .append(segment4, -1, errorCode);
}

typedef struct {
    const char * usageTypeName;
    DateFormatSymbols::ECapitalizationContextUsageType usageTypeEnumValue;
} ContextUsageTypeNameToEnumValue;

static const ContextUsageTypeNameToEnumValue contextUsageTypeMap[] = {
   // Entries must be sorted by usageTypeName; entry with NULL name terminates list.
    { "day-format-except-narrow", DateFormatSymbols::kCapContextUsageDayFormat },
    { "day-narrow",     DateFormatSymbols::kCapContextUsageDayNarrow },
    { "day-standalone-except-narrow", DateFormatSymbols::kCapContextUsageDayStandalone },
    { "era-abbr",       DateFormatSymbols::kCapContextUsageEraAbbrev },
    { "era-name",       DateFormatSymbols::kCapContextUsageEraWide },
    { "era-narrow",     DateFormatSymbols::kCapContextUsageEraNarrow },
    { "metazone-long",  DateFormatSymbols::kCapContextUsageMetazoneLong },
    { "metazone-short", DateFormatSymbols::kCapContextUsageMetazoneShort },
    { "month-format-except-narrow", DateFormatSymbols::kCapContextUsageMonthFormat },
    { "month-narrow",   DateFormatSymbols::kCapContextUsageMonthNarrow },
    { "month-standalone-except-narrow", DateFormatSymbols::kCapContextUsageMonthStandalone },
    { "zone-long",      DateFormatSymbols::kCapContextUsageZoneLong },
    { "zone-short",     DateFormatSymbols::kCapContextUsageZoneShort },
    { NULL, (DateFormatSymbols::ECapitalizationContextUsageType)0 },
};

// Resource keys to look up localized strings for day periods.
// The first one must be midnight and the second must be noon, so that their indices coincide
// with the am/pm field. Formatting and parsing code for day periods relies on this coincidence.
static const char *dayPeriodKeys[] = {"midnight", "noon",
                         "morning1", "afternoon1", "evening1", "night1",
                         "morning2", "afternoon2", "evening2", "night2"};

UnicodeString* loadDayPeriodStrings(CalendarDataSink &sink, CharString &path,
                                    int32_t &stringCount,  UErrorCode &status) {
    if (U_FAILURE(status)) { return NULL; }

    UnicodeString pathUString(path.data(), -1, US_INV);
    Hashtable* map = static_cast<Hashtable*>(sink.maps.get(pathUString));

    stringCount = UPRV_LENGTHOF(dayPeriodKeys);
    UnicodeString *strings = new UnicodeString[stringCount];
    if (strings == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    if (map != NULL) {
        for (int32_t i = 0; i < stringCount; ++i) {
            UnicodeString dayPeriodKey(dayPeriodKeys[i], -1, US_INV);
            UnicodeString *dayPeriod = static_cast<UnicodeString*>(map->get(dayPeriodKey));
            if (dayPeriod != NULL) {
                strings[i].fastCopyFrom(*dayPeriod);
            } else {
                strings[i].setToBogus();
            }
        }
    } else {
        for (int32_t i = 0; i < stringCount; i++) {
            strings[i].setToBogus();
        }
    }
    return strings;
}


void
DateFormatSymbols::initializeData(const Locale& locale, const char *type, UErrorCode& status, UBool useLastResortData)
{
    int32_t len = 0;
    /* In case something goes wrong, initialize all of the data to NULL. */
    fEras = NULL;
    fErasCount = 0;
    fEraNames = NULL;
    fEraNamesCount = 0;
    fNarrowEras = NULL;
    fNarrowErasCount = 0;
    fMonths = NULL;
    fMonthsCount=0;
    fShortMonths = NULL;
    fShortMonthsCount=0;
    fNarrowMonths = NULL;
    fNarrowMonthsCount=0;
    fStandaloneMonths = NULL;
    fStandaloneMonthsCount=0;
    fStandaloneShortMonths = NULL;
    fStandaloneShortMonthsCount=0;
    fStandaloneNarrowMonths = NULL;
    fStandaloneNarrowMonthsCount=0;
    fWeekdays = NULL;
    fWeekdaysCount=0;
    fShortWeekdays = NULL;
    fShortWeekdaysCount=0;
    fShorterWeekdays = NULL;
    fShorterWeekdaysCount=0;
    fNarrowWeekdays = NULL;
    fNarrowWeekdaysCount=0;
    fStandaloneWeekdays = NULL;
    fStandaloneWeekdaysCount=0;
    fStandaloneShortWeekdays = NULL;
    fStandaloneShortWeekdaysCount=0;
    fStandaloneShorterWeekdays = NULL;
    fStandaloneShorterWeekdaysCount=0;
    fStandaloneNarrowWeekdays = NULL;
    fStandaloneNarrowWeekdaysCount=0;
    fAmPms = NULL;
    fAmPmsCount=0;
    fNarrowAmPms = NULL;
    fNarrowAmPmsCount=0;
    fTimeSeparator.setToBogus();
    fQuarters = NULL;
    fQuartersCount = 0;
    fShortQuarters = NULL;
    fShortQuartersCount = 0;
    fStandaloneQuarters = NULL;
    fStandaloneQuartersCount = 0;
    fStandaloneShortQuarters = NULL;
    fStandaloneShortQuartersCount = 0;
    fLeapMonthPatterns = NULL;
    fLeapMonthPatternsCount = 0;
    fShortYearNames = NULL;
    fShortYearNamesCount = 0;
    fShortZodiacNames = NULL;
    fShortZodiacNamesCount = 0;
    fZoneStringsRowCount = 0;
    fZoneStringsColCount = 0;
    fZoneStrings = NULL;
    fLocaleZoneStrings = NULL;
    fAbbreviatedDayPeriods = NULL;
    fAbbreviatedDayPeriodsCount = 0;
    fWideDayPeriods = NULL;
    fWideDayPeriodsCount = 0;
    fNarrowDayPeriods = NULL;
    fNarrowDayPeriodsCount = 0;
    fStandaloneAbbreviatedDayPeriods = NULL;
    fStandaloneAbbreviatedDayPeriodsCount = 0;
    fStandaloneWideDayPeriods = NULL;
    fStandaloneWideDayPeriodsCount = 0;
    fStandaloneNarrowDayPeriods = NULL;
    fStandaloneNarrowDayPeriodsCount = 0;
    uprv_memset(fCapitalization, 0, sizeof(fCapitalization));

    // We need to preserve the requested locale for
    // lazy ZoneStringFormat instantiation.  ZoneStringFormat
    // is region sensitive, thus, bundle locale bundle's locale
    // is not sufficient.
    fZSFLocale = locale;

    if (U_FAILURE(status)) return;

    // Create a CalendarDataSink to process this data and the resouce bundles
    CalendarDataSink calendarSink(status);
    UResourceBundle *rb = ures_open(NULL, locale.getBaseName(), &status);
    UResourceBundle *cb = ures_getByKey(rb, gCalendarTag, NULL, &status);

    if (U_FAILURE(status)) return;

    // Iterate over the resource bundle data following the fallbacks through different calendar types
    UnicodeString calendarType((type != NULL && *type != '\0')? type : gGregorianTag, -1, US_INV);
    while (!calendarType.isBogus()) {
        CharString calendarTypeBuffer;
        calendarTypeBuffer.appendInvariantChars(calendarType, status);
        if (U_FAILURE(status)) { return; }
        const char *calendarTypeCArray = calendarTypeBuffer.data();

        // Enumerate this calendar type. If the calendar is not found fallback to gregorian
        UErrorCode oldStatus = status;
        UResourceBundle *ctb = ures_getByKeyWithFallback(cb, calendarTypeCArray, NULL, &status);
        if (status == U_MISSING_RESOURCE_ERROR) {
            ures_close(ctb);
            if (uprv_strcmp(calendarTypeCArray, gGregorianTag) != 0) {
                calendarType.setTo(FALSE, kGregorianTagUChar, UPRV_LENGTHOF(kGregorianTagUChar));
                calendarSink.visitAllResources();
                status = oldStatus;
                continue;
            }
            return;
        }

        calendarSink.preEnumerate(calendarType);
        ures_getAllItemsWithFallback(ctb, "", calendarSink, status);
        ures_close(ctb);
        if (U_FAILURE(status)) break;

        // Stop loading when gregorian was loaded
        if (uprv_strcmp(calendarTypeCArray, gGregorianTag) == 0) {
            break;
        }

        // Get the next calendar type to process from the sink
        calendarType = calendarSink.nextCalendarType;

        // Gregorian is always the last fallback
        if (calendarType.isBogus()) {
            calendarType.setTo(FALSE, kGregorianTagUChar, UPRV_LENGTHOF(kGregorianTagUChar));
            calendarSink.visitAllResources();
        }
    }

    // CharString object to build paths
    CharString path;

    // Load Leap Month Patterns
    UErrorCode tempStatus = status;
    fLeapMonthPatterns = newUnicodeStringArray(kMonthPatternsCount);
    if (fLeapMonthPatterns) {
        initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatWide, calendarSink,
                             buildResourcePath(path, gMonthPatternsTag, gNamesFormatTag, gNamesWideTag, tempStatus), tempStatus);
        initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatAbbrev, calendarSink,
                             buildResourcePath(path, gMonthPatternsTag, gNamesFormatTag, gNamesAbbrTag, tempStatus), tempStatus);
        initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternFormatNarrow, calendarSink,
                             buildResourcePath(path, gMonthPatternsTag, gNamesFormatTag, gNamesNarrowTag, tempStatus), tempStatus);
        initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneWide, calendarSink,
                             buildResourcePath(path, gMonthPatternsTag, gNamesStandaloneTag, gNamesWideTag, tempStatus), tempStatus);
        initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneAbbrev, calendarSink,
                             buildResourcePath(path, gMonthPatternsTag, gNamesStandaloneTag, gNamesAbbrTag, tempStatus), tempStatus);
        initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternStandaloneNarrow, calendarSink,
                             buildResourcePath(path, gMonthPatternsTag, gNamesStandaloneTag, gNamesNarrowTag, tempStatus), tempStatus);
        initLeapMonthPattern(fLeapMonthPatterns, kLeapMonthPatternNumeric, calendarSink,
                             buildResourcePath(path, gMonthPatternsTag, gNamesNumericTag, gNamesAllTag, tempStatus), tempStatus);
        if (U_SUCCESS(tempStatus)) {
            // Hack to fix bad C inheritance for dangi monthPatterns (OK in J); this should be handled by aliases in root, but isn't.
            // The ordering of the following statements is important.
            if (fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].isEmpty()) {
                fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);
            };
            if (fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].isEmpty()) {
                fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].setTo(fLeapMonthPatterns[kLeapMonthPatternStandaloneNarrow]);
            };
            if (fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].isEmpty()) {
                fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);
            };
            if (fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].isEmpty()) {
                fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev]);
            };
            // end of hack
            fLeapMonthPatternsCount = kMonthPatternsCount;
        } else {
            delete[] fLeapMonthPatterns;
            fLeapMonthPatterns = NULL;
        }
    }

    // Load cyclic names sets
    tempStatus = status;
    initField(&fShortYearNames, fShortYearNamesCount, calendarSink,
              buildResourcePath(path, gCyclicNameSetsTag, gNameSetYearsTag, gNamesFormatTag, gNamesAbbrTag, tempStatus), tempStatus);
    initField(&fShortZodiacNames, fShortZodiacNamesCount, calendarSink,
              buildResourcePath(path, gCyclicNameSetsTag, gNameSetZodiacsTag, gNamesFormatTag, gNamesAbbrTag, tempStatus), tempStatus);

    // Load context transforms and capitalization
    tempStatus = U_ZERO_ERROR;
    UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &tempStatus);
    if (U_SUCCESS(tempStatus)) {
        UResourceBundle *contextTransforms = ures_getByKeyWithFallback(localeBundle, gContextTransformsTag, NULL, &tempStatus);
        if (U_SUCCESS(tempStatus)) {
            UResourceBundle *contextTransformUsage;
            while ( (contextTransformUsage = ures_getNextResource(contextTransforms, NULL, &tempStatus)) != NULL ) {
                const int32_t * intVector = ures_getIntVector(contextTransformUsage, &len, &status);
                if (U_SUCCESS(tempStatus) && intVector != NULL && len >= 2) {
                    const char* usageType = ures_getKey(contextTransformUsage);
                    if (usageType != NULL) {
                        const ContextUsageTypeNameToEnumValue * typeMapPtr = contextUsageTypeMap;
                        int32_t compResult = 0;
                        // linear search; list is short and we cannot be sure that bsearch is available
                        while ( typeMapPtr->usageTypeName != NULL && (compResult = uprv_strcmp(usageType, typeMapPtr->usageTypeName)) > 0 ) {
                            ++typeMapPtr;
                        }
                        if (typeMapPtr->usageTypeName != NULL && compResult == 0) {
                            fCapitalization[typeMapPtr->usageTypeEnumValue][0] = static_cast<UBool>(intVector[0]);
                            fCapitalization[typeMapPtr->usageTypeEnumValue][1] = static_cast<UBool>(intVector[1]);
                        }
                    }
                }
                tempStatus = U_ZERO_ERROR;
                ures_close(contextTransformUsage);
            }
            ures_close(contextTransforms);
        }

        tempStatus = U_ZERO_ERROR;
        const LocalPointer<NumberingSystem> numberingSystem(
                NumberingSystem::createInstance(locale, tempStatus), tempStatus);
        if (U_SUCCESS(tempStatus)) {
            // These functions all fail gracefully if passed NULL pointers and
            // do nothing unless U_SUCCESS(tempStatus), so it's only necessary
            // to check for errors once after all calls are made.
            const LocalUResourceBundlePointer numberElementsData(ures_getByKeyWithFallback(
                    localeBundle, gNumberElementsTag, NULL, &tempStatus));
            const LocalUResourceBundlePointer nsNameData(ures_getByKeyWithFallback(
                    numberElementsData.getAlias(), numberingSystem->getName(), NULL, &tempStatus));
            const LocalUResourceBundlePointer symbolsData(ures_getByKeyWithFallback(
                    nsNameData.getAlias(), gSymbolsTag, NULL, &tempStatus));
            fTimeSeparator = ures_getUnicodeStringByKey(
                    symbolsData.getAlias(), gTimeSeparatorTag, &tempStatus);
            if (U_FAILURE(tempStatus)) {
                fTimeSeparator.setToBogus();
            }
        }

        ures_close(localeBundle);
    }

    if (fTimeSeparator.isBogus()) {
        fTimeSeparator.setTo(DateFormatSymbols::DEFAULT_TIME_SEPARATOR);
    }

    // Load day periods
    fWideDayPeriods = loadDayPeriodStrings(calendarSink,
                            buildResourcePath(path, gDayPeriodTag, gNamesFormatTag, gNamesWideTag, status),
                            fWideDayPeriodsCount, status);
    fNarrowDayPeriods = loadDayPeriodStrings(calendarSink,
                            buildResourcePath(path, gDayPeriodTag, gNamesFormatTag, gNamesNarrowTag, status),
                            fNarrowDayPeriodsCount, status);
    fAbbreviatedDayPeriods = loadDayPeriodStrings(calendarSink,
                            buildResourcePath(path, gDayPeriodTag, gNamesFormatTag, gNamesAbbrTag, status),
                            fAbbreviatedDayPeriodsCount, status);
    fStandaloneWideDayPeriods = loadDayPeriodStrings(calendarSink,
                            buildResourcePath(path, gDayPeriodTag, gNamesStandaloneTag, gNamesWideTag, status),
                            fStandaloneWideDayPeriodsCount, status);
    fStandaloneNarrowDayPeriods = loadDayPeriodStrings(calendarSink,
                            buildResourcePath(path, gDayPeriodTag, gNamesStandaloneTag, gNamesNarrowTag, status),
                            fStandaloneNarrowDayPeriodsCount, status);
    fStandaloneAbbreviatedDayPeriods = loadDayPeriodStrings(calendarSink,
                            buildResourcePath(path, gDayPeriodTag, gNamesStandaloneTag, gNamesAbbrTag, status),
                            fStandaloneAbbreviatedDayPeriodsCount, status);

    U_LOCALE_BASED(locBased, *this);
    // if we make it to here, the resource data is cool, and we can get everything out
    // of it that we need except for the time-zone and localized-pattern data, which
    // are stored in a separate file
    locBased.setLocaleIDs(ures_getLocaleByType(cb, ULOC_VALID_LOCALE, &status),
                          ures_getLocaleByType(cb, ULOC_ACTUAL_LOCALE, &status));

    // Load eras
    initField(&fEras, fErasCount, calendarSink, buildResourcePath(path, gErasTag, gNamesAbbrTag, status), status);
    UErrorCode oldStatus = status;
    initField(&fEraNames, fEraNamesCount, calendarSink, buildResourcePath(path, gErasTag, gNamesWideTag, status), status);
    if (status == U_MISSING_RESOURCE_ERROR) { // Workaround because eras/wide was omitted from CLDR 1.3
        status = oldStatus;
        assignArray(fEraNames, fEraNamesCount, fEras, fErasCount);
    }
    // current ICU4J falls back to abbreviated if narrow eras are missing, so we will too
    oldStatus = status;
    initField(&fNarrowEras, fNarrowErasCount, calendarSink, buildResourcePath(path, gErasTag, gNamesNarrowTag, status), status);
    if (status == U_MISSING_RESOURCE_ERROR) { // Workaround because eras/wide was omitted from CLDR 1.3
        status = oldStatus;
        assignArray(fNarrowEras, fNarrowErasCount, fEras, fErasCount);
    }

    // Load month names
    initField(&fMonths, fMonthsCount, calendarSink,
              buildResourcePath(path, gMonthNamesTag, gNamesFormatTag, gNamesWideTag, status), status);
    initField(&fShortMonths, fShortMonthsCount, calendarSink,
              buildResourcePath(path, gMonthNamesTag, gNamesFormatTag, gNamesAbbrTag, status), status);
    initField(&fStandaloneMonths, fStandaloneMonthsCount, calendarSink,
              buildResourcePath(path, gMonthNamesTag, gNamesStandaloneTag, gNamesWideTag, status), status);
    if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/wide not available, use format/wide */
        status = U_ZERO_ERROR;
        assignArray(fStandaloneMonths, fStandaloneMonthsCount, fMonths, fMonthsCount);
    }
    initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calendarSink,
              buildResourcePath(path, gMonthNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);
    if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/abbreviated not available, use format/abbreviated */
        status = U_ZERO_ERROR;
        assignArray(fStandaloneShortMonths, fStandaloneShortMonthsCount, fShortMonths, fShortMonthsCount);
    }

    UErrorCode narrowMonthsEC = status;
    UErrorCode standaloneNarrowMonthsEC = status;
    initField(&fNarrowMonths, fNarrowMonthsCount, calendarSink,
              buildResourcePath(path, gMonthNamesTag, gNamesFormatTag, gNamesNarrowTag, narrowMonthsEC), narrowMonthsEC);
    initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calendarSink,
              buildResourcePath(path, gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, narrowMonthsEC), standaloneNarrowMonthsEC);
    if (narrowMonthsEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowMonthsEC != U_MISSING_RESOURCE_ERROR) {
        // If format/narrow not available, use standalone/narrow
        assignArray(fNarrowMonths, fNarrowMonthsCount, fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount);
    } else if (narrowMonthsEC != U_MISSING_RESOURCE_ERROR && standaloneNarrowMonthsEC == U_MISSING_RESOURCE_ERROR) {
        // If standalone/narrow not availabe, use format/narrow
        assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, fNarrowMonths, fNarrowMonthsCount);
    } else if (narrowMonthsEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowMonthsEC == U_MISSING_RESOURCE_ERROR) {
        // If neither is available, use format/abbreviated
        assignArray(fNarrowMonths, fNarrowMonthsCount, fShortMonths, fShortMonthsCount);
        assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, fShortMonths, fShortMonthsCount);
    }

    // Load AM/PM markers
    initField(&fAmPms, fAmPmsCount, calendarSink,
              buildResourcePath(path, gAmPmMarkersTag, status), status);
    initField(&fNarrowAmPms, fNarrowAmPmsCount, calendarSink,
              buildResourcePath(path, gAmPmMarkersNarrowTag, status), status);

    // Load quarters
    initField(&fQuarters, fQuartersCount, calendarSink,
              buildResourcePath(path, gQuartersTag, gNamesFormatTag, gNamesWideTag, status), status);
    initField(&fShortQuarters, fShortQuartersCount, calendarSink,
              buildResourcePath(path, gQuartersTag, gNamesFormatTag, gNamesAbbrTag, status), status);

    initField(&fStandaloneQuarters, fStandaloneQuartersCount, calendarSink,
              buildResourcePath(path, gQuartersTag, gNamesStandaloneTag, gNamesWideTag, status), status);
    if(status == U_MISSING_RESOURCE_ERROR) {
        status = U_ZERO_ERROR;
        assignArray(fStandaloneQuarters, fStandaloneQuartersCount, fQuarters, fQuartersCount);
    }
    initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calendarSink,
              buildResourcePath(path, gQuartersTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);
    if(status == U_MISSING_RESOURCE_ERROR) {
        status = U_ZERO_ERROR;
        assignArray(fStandaloneShortQuarters, fStandaloneShortQuartersCount, fShortQuarters, fShortQuartersCount);
    }

    // ICU 3.8 or later version no longer uses localized date-time pattern characters by default (ticket#5597)
    /*
    // fastCopyFrom()/setTo() - see assignArray comments
    resStr = ures_getStringByKey(fResourceBundle, gLocalPatternCharsTag, &len, &status);
    fLocalPatternChars.setTo(TRUE, resStr, len);
    // If the locale data does not include new pattern chars, use the defaults
    // TODO: Consider making this an error, since this may add conflicting characters.
    if (len < PATTERN_CHARS_LEN) {
        fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len));
    }
    */
    fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);

    // Format wide weekdays -> fWeekdays
    // {sfb} fixed to handle 1-based weekdays
    initField(&fWeekdays, fWeekdaysCount, calendarSink,
              buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesWideTag, status), 1, status);

    // Format abbreviated weekdays -> fShortWeekdays
    initField(&fShortWeekdays, fShortWeekdaysCount, calendarSink,
              buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesAbbrTag, status), 1, status);

    // Format short weekdays -> fShorterWeekdays (fall back to abbreviated)
    initField(&fShorterWeekdays, fShorterWeekdaysCount, calendarSink,
              buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesShortTag, status), 1, status);
    if (status == U_MISSING_RESOURCE_ERROR) {
        status = U_ZERO_ERROR;
        assignArray(fShorterWeekdays, fShorterWeekdaysCount, fShortWeekdays, fShortWeekdaysCount);
    }

    // Stand-alone wide weekdays -> fStandaloneWeekdays
    initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, calendarSink,
              buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesWideTag, status), 1, status);
    if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/wide is not available, use format/wide */
        status = U_ZERO_ERROR;
        assignArray(fStandaloneWeekdays, fStandaloneWeekdaysCount, fWeekdays, fWeekdaysCount);
    }

    // Stand-alone abbreviated weekdays -> fStandaloneShortWeekdays
    initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, calendarSink,
              buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), 1, status);
    if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/abbreviated is not available, use format/abbreviated */
        status = U_ZERO_ERROR;
        assignArray(fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, fShortWeekdays, fShortWeekdaysCount);
    }

    // Stand-alone short weekdays -> fStandaloneShorterWeekdays (fall back to format abbreviated)
    initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, calendarSink,
              buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesShortTag, status), 1, status);
    if (status == U_MISSING_RESOURCE_ERROR) { /* If standalone/short is not available, use format/short */
        status = U_ZERO_ERROR;
        assignArray(fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, fShorterWeekdays, fShorterWeekdaysCount);
    }

    // Format narrow weekdays -> fNarrowWeekdays
    UErrorCode narrowWeeksEC = status;
    initField(&fNarrowWeekdays, fNarrowWeekdaysCount, calendarSink,
              buildResourcePath(path, gDayNamesTag, gNamesFormatTag, gNamesNarrowTag, status), 1, narrowWeeksEC);
    // Stand-alone narrow weekdays -> fStandaloneNarrowWeekdays
    UErrorCode standaloneNarrowWeeksEC = status;
    initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, calendarSink,
              buildResourcePath(path, gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), 1, standaloneNarrowWeeksEC);

    if (narrowWeeksEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowWeeksEC != U_MISSING_RESOURCE_ERROR) {
        // If format/narrow not available, use standalone/narrow
        assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount);
    } else if (narrowWeeksEC != U_MISSING_RESOURCE_ERROR && standaloneNarrowWeeksEC == U_MISSING_RESOURCE_ERROR) {
        // If standalone/narrow not available, use format/narrow
        assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, fNarrowWeekdays, fNarrowWeekdaysCount);
    } else if (narrowWeeksEC == U_MISSING_RESOURCE_ERROR && standaloneNarrowWeeksEC == U_MISSING_RESOURCE_ERROR ) {
        // If neither is available, use format/abbreviated
        assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, fShortWeekdays, fShortWeekdaysCount);
        assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, fShortWeekdays, fShortWeekdaysCount);
    }

    // Last resort fallback in case previous data wasn't loaded
    if (U_FAILURE(status))
    {
        if (useLastResortData)
        {
            // Handle the case in which there is no resource data present.
            // We don't have to generate usable patterns in this situation;
            // we just need to produce something that will be semi-intelligible
            // in most locales.

            status = U_USING_FALLBACK_WARNING;
            //TODO(fabalbon): make sure we are storing las resort data for all fields in here.
            initField(&fEras, fErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
            initField(&fEraNames, fEraNamesCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
            initField(&fNarrowEras, fNarrowErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
            initField(&fMonths, fMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen,  status);
            initField(&fShortMonths, fShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
            initField(&fNarrowMonths, fNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
            initField(&fStandaloneMonths, fStandaloneMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen,  status);
            initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
            initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
            initField(&fWeekdays, fWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fShortWeekdays, fShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fShorterWeekdays, fShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fNarrowWeekdays, fNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fAmPms, fAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);
            initField(&fNarrowAmPms, fNarrowAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);
            initField(&fQuarters, fQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
            initField(&fShortQuarters, fShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
            initField(&fStandaloneQuarters, fStandaloneQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
            initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
            fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);
        }
    }

    // Close resources
    ures_close(cb);
    ures_close(rb);
}

Locale
DateFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
    U_LOCALE_BASED(locBased, *this);
    return locBased.getLocale(type, status);
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
