home *** CD-ROM | disk | FTP | other *** search
- /*
- *******************************************************************************
- * *
- * COPYRIGHT: *
- * (C) Copyright Taligent, Inc., 1997 *
- * (C) Copyright International Business Machines Corporation, 1997-1998 *
- * Licensed Material - Program-Property of IBM - All Rights Reserved. *
- * US Government Users Restricted Rights - Use, duplication, or disclosure *
- * restricted by GSA ADP Schedule Contract with IBM Corp. *
- * *
- *******************************************************************************
- *
- * 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
- *******************************************************************************
- */
-
- #include "dtfmtsym.h"
- #include "resbund.h"
- #include "smpdtfmt.h"
- #include "mutex.h"
-
- // *****************************************************************************
- // class DateFormatSymbols
- // *****************************************************************************
-
- // generic date-format pattern symbols. For their meanings, see class docs
- // for SimpleDateFormat
- UnicodeString DateFormatSymbols::fgPatternChars = "GyMdkHmsSEDFwWahKz";
-
- //------------------------------------------------------
- // Strings of last resort. These are only used if we have no resource
- // files. They aren't designed for actual use, just for backup.
-
- //============================================================
- // To make the VC++ compiler happy these must occur before the
- // sizeof operations on the arrays occur below.
- //============================================================
-
- // These are the month names and abbreviations of last resort.
- const UnicodeString DateFormatSymbols::fgLastResortMonthNames[] =
- {
- "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13"
- };
-
- // These are the weekday names and abbreviations of last resort.
- const UnicodeString DateFormatSymbols::fgLastResortDayNames[] =
- {
- "", "1", "2", "3", "4", "5", "6", "7"
- };
-
- // These are the am/pm and BC/AD markers of last resort.
- const UnicodeString DateFormatSymbols::fgLastResortAmPmMarkers[] =
- {
- "AM", "PM"
- };
-
- const UnicodeString DateFormatSymbols::fgLastResortEras[] =
- {
- "BC", "AD"
- };
-
- // These are the zone strings of last resort.
- UnicodeString** DateFormatSymbols::fgLastResortZoneStringsH = 0;
-
- const UnicodeString DateFormatSymbols::fgLastResortZoneStrings[] =
- {
- "GMT", "GMT", "GMT", "GMT", "GMT"
- };
-
- //------------------------------------------------------
-
- DateFormatSymbols::DateFormatSymbols(const Locale& locale,
- UErrorCode& status)
- {
- initializeData(locale, status);
- }
-
- DateFormatSymbols::DateFormatSymbols(UErrorCode& status)
- {
- initializeData(Locale::getDefault(), status, TRUE);
- }
-
- DateFormatSymbols::DateFormatSymbols(const DateFormatSymbols& other)
- {
- fIsOwned = 0; // We own nothing (ignore existing pointers)
- *this = other;
- }
-
- void
- DateFormatSymbols::assignArray(UnicodeString*& dstArray,
- int32_t& dstCount,
- const UnicodeString* srcArray,
- int32_t srcCount,
- const DateFormatSymbols& other,
- int32_t which)
- {
- // duplicates or aliases the source array, depending on the status of
- // the appropriate isOwned flag
- bool_t owned = other.isOwned(which);
- setIsOwned(which, owned);
- dstCount = srcCount;
- if (owned)
- {
- dstArray = new UnicodeString[srcCount];
- icu_arrayCopy(srcArray, dstArray, srcCount);
- }
- else
- {
- dstArray = (UnicodeString*)srcArray; // Compiler requires cast
- }
- }
-
- /**
- * Create a copy, in fZoneStrings, of the given zone strings array. The
- * member variables fZoneStringsRowCount and fZoneStringsColCount should
- * be set already by the caller. The fIsOwned flags are not checked or set
- * by this method; that is the caller's responsibility.
- */
- void
- DateFormatSymbols::createZoneStrings(const UnicodeString *const * otherStrings)
- {
- fZoneStrings = new UnicodeString*[fZoneStringsRowCount];
- for (int32_t row=0; row<fZoneStringsRowCount; ++row)
- {
- fZoneStrings[row] = new UnicodeString[fZoneStringsColCount];
- icu_arrayCopy(otherStrings[row], fZoneStrings[row], fZoneStringsColCount);
- }
- }
-
- /**
- * Assignment operator. A bit messy because the other object may or may not
- * own each of its arrays. We then alias or copy those arrays as appropriate.
- * Arrays that aren't owned are assumed to be permanently "around," which is
- * true, since they are owned by the ResourceBundle cache.
- */
- DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)
- {
- dispose();
- assignArray(fEras, fErasCount, other.fEras, other.fErasCount, other, kEras);
- assignArray(fMonths, fMonthsCount, other.fMonths, other.fMonthsCount, other, kMonths);
- assignArray(fShortMonths, fShortMonthsCount, other.fShortMonths, other.fShortMonthsCount, other, kShortMonths);
- assignArray(fWeekdays, fWeekdaysCount, other.fWeekdays, other.fWeekdaysCount, other, kWeekdays);
- assignArray(fShortWeekdays, fShortWeekdaysCount, other.fShortWeekdays, other.fShortWeekdaysCount, other, kShortWeekdays);
- assignArray(fAmPms, fAmPmsCount, other.fAmPms, other.fAmPmsCount, other, kAmPms);
-
- bool_t owned = other.isOwned(kZoneStrings);
- setIsOwned(kZoneStrings, owned);
- fZoneStringsRowCount = other.fZoneStringsRowCount;
- fZoneStringsColCount = other.fZoneStringsColCount;
- if (owned) createZoneStrings((const UnicodeString**)other.fZoneStrings);
- else fZoneStrings = other.fZoneStrings;
-
- fLocalPatternChars = other.fLocalPatternChars;
- return *this;
- }
-
- DateFormatSymbols::~DateFormatSymbols()
- {
- dispose();
- }
-
- void DateFormatSymbols::dispose()
- {
- // Delete those items which we have marked as owned
-
- if (isOwned(kEras)) delete[] fEras;
- if (isOwned(kMonths)) delete[] fMonths;
- if (isOwned(kShortMonths)) delete[] fShortMonths;
- if (isOwned(kWeekdays)) delete[] fWeekdays;
- if (isOwned(kShortWeekdays)) delete[] fShortWeekdays;
- if (isOwned(kAmPms)) delete[] fAmPms;
-
- disposeZoneStrings();
-
- fIsOwned = 0; // Indicate that we no longer need to delete anything
- }
-
- void DateFormatSymbols::disposeZoneStrings()
- {
- if (isOwned(kZoneStrings))
- {
- for (int32_t row=0; row<fZoneStringsRowCount; ++row)
- delete[] fZoneStrings[row];
- delete[] fZoneStrings;
- }
- }
-
- bool_t
- 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;
- }
-
- bool_t
- DateFormatSymbols::operator==(const DateFormatSymbols& other) const
- {
- // First do cheap comparisons
- if (fErasCount == other.fErasCount &&
- fMonthsCount == other.fMonthsCount &&
- fShortMonthsCount == other.fShortMonthsCount &&
- fWeekdaysCount == other.fWeekdaysCount &&
- fShortWeekdaysCount == other.fShortWeekdaysCount &&
- fAmPmsCount == other.fAmPmsCount &&
- fZoneStringsRowCount == other.fZoneStringsRowCount &&
- fZoneStringsColCount == other.fZoneStringsColCount)
- {
- // Now compare the arrays themselves
- if (arrayCompare(fEras, other.fEras, fErasCount) &&
- arrayCompare(fMonths, other.fMonths, fMonthsCount) &&
- arrayCompare(fShortMonths, other.fShortMonths, fShortMonthsCount) &&
- arrayCompare(fWeekdays, other.fWeekdays, fWeekdaysCount) &&
- arrayCompare(fShortWeekdays, other.fShortWeekdays, fShortWeekdaysCount) &&
- arrayCompare(fAmPms, other.fAmPms, fAmPmsCount))
- {
- if (fZoneStrings == other.fZoneStrings) return TRUE;
-
- for (int32_t row=0; row<fZoneStringsRowCount; ++row)
- {
- if (!arrayCompare(fZoneStrings[row], other.fZoneStrings[row], fZoneStringsColCount))
- return FALSE;
- }
- return TRUE;
- }
- }
- return FALSE;
- }
-
- //------------------------------------------------------
-
- const UnicodeString*
- DateFormatSymbols::getEras(int32_t &count) const
- {
- count = fErasCount;
- return fEras;
- }
-
- 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::getWeekdays(int32_t &count) const
- {
- count = fWeekdaysCount;
- return fWeekdays;
- }
-
- const UnicodeString*
- DateFormatSymbols::getShortWeekdays(int32_t &count) const
- {
- count = fShortWeekdaysCount;
- return fShortWeekdays;
- }
-
- const UnicodeString*
- DateFormatSymbols::getAmPmStrings(int32_t &count) const
- {
- count = fAmPmsCount;
- return fAmPms;
- }
-
- //------------------------------------------------------
-
- void
- DateFormatSymbols::setEras(const UnicodeString* erasArray, int32_t count)
- {
- // delete the old list if we own it
- if (isOwned(kEras)) delete[] fEras;
-
- // we always own the new list, which we create here (we duplicate rather
- // than adopting the list passed in)
- setIsOwned(kEras, TRUE);
- fEras = new UnicodeString[count];
- icu_arrayCopy(erasArray,fEras, count);
- fErasCount = count;
- }
-
- void
- DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count)
- {
- // delete the old list if we own it
- if (isOwned(kMonths)) delete[] fMonths;
-
- // we always own the new list, which we create here (we duplicate rather
- // than adopting the list passed in)
- setIsOwned(kMonths, TRUE);
- fMonths = new UnicodeString[count];
- icu_arrayCopy( monthsArray,fMonths,count);
- fMonthsCount = count;
- }
-
- void
- DateFormatSymbols::setShortMonths(const UnicodeString* shortMonthsArray, int32_t count)
- {
- // delete the old list if we own it
- if (isOwned(kShortMonths)) delete[] fShortMonths;
-
- // we always own the new list, which we create here (we duplicate rather
- // than adopting the list passed in)
- setIsOwned(kShortMonths, TRUE);
- fShortMonths = new UnicodeString[count];
- icu_arrayCopy(shortMonthsArray,fShortMonths, count);
- fShortMonthsCount = count;
- }
-
- void DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count)
- {
- // delete the old list if we own it
- if (isOwned(kWeekdays)) delete[] fWeekdays;
-
- // we always own the new list, which we create here (we duplicate rather
- // than adopting the list passed in)
- setIsOwned(kWeekdays, TRUE);
- fWeekdays = new UnicodeString[count];
- icu_arrayCopy(weekdaysArray,fWeekdays,count);
- fWeekdaysCount = count;
- }
-
- void
- DateFormatSymbols::setShortWeekdays(const UnicodeString* shortWeekdaysArray, int32_t count)
- {
- // delete the old list if we own it
- if (isOwned(kShortWeekdays)) delete[] fShortWeekdays;
-
- // we always own the new list, which we create here (we duplicate rather
- // than adopting the list passed in)
- setIsOwned(kShortWeekdays, TRUE);
- fShortWeekdays = new UnicodeString[count];
- icu_arrayCopy( shortWeekdaysArray,fShortWeekdays,count);
- fShortWeekdaysCount = count;
- }
-
- void
- DateFormatSymbols::setAmPmStrings(const UnicodeString* amPmsArray, int32_t count)
- {
- // delete the old list if we own it
- if (isOwned(kAmPms)) delete[] fAmPms;
-
- // we always own the new list, which we create here (we duplicate rather
- // than adopting the list passed in)
- setIsOwned(kAmPms, TRUE);
- fAmPms = new UnicodeString[count];
- icu_arrayCopy(amPmsArray,fAmPms,count);
- fAmPmsCount = count;
- }
-
- //------------------------------------------------------
-
- const UnicodeString**
- DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const
- {
- rowCount = fZoneStringsRowCount;
- columnCount = fZoneStringsColCount;
- return (const UnicodeString**)fZoneStrings; // Compiler requires cast
- }
-
- 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)
- setIsOwned(kZoneStrings, TRUE);
- fZoneStringsRowCount = rowCount;
- fZoneStringsColCount = columnCount;
- createZoneStrings((const UnicodeString**)strings);
- }
-
- //------------------------------------------------------
-
- UnicodeString&
- DateFormatSymbols::getLocalPatternChars(UnicodeString& result) const
- {
- result = fLocalPatternChars;
- return result;
- }
-
- //------------------------------------------------------
-
- void
- DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChars)
- {
- fLocalPatternChars = newLocalPatternChars;
- }
-
- //------------------------------------------------------
-
- void
- DateFormatSymbols::initializeData(const Locale& locale, UErrorCode& status, bool_t useLastResortData)
- {
- if (U_FAILURE(status)) return;
-
- fIsOwned = 0; // Nothing is owned
-
- /**
- * Retrieve the string arrays we need from the resource bundle file.
- * We cast away const here, but that's okay; we won't delete any of
- * these.
- */
- ResourceBundle resource(Locale::getDataDirectory(), locale, status);
- 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_ERROR;
-
- fEras = (UnicodeString*)fgLastResortEras;
- fErasCount = sizeof(fgLastResortEras[0]) / sizeof(fgLastResortEras[0]);
- fMonths = fShortMonths = (UnicodeString*)fgLastResortMonthNames;
- fMonthsCount = fShortMonthsCount = sizeof(fgLastResortMonthNames) / sizeof(fgLastResortMonthNames[0]);
- fWeekdays = fShortWeekdays = (UnicodeString*)fgLastResortDayNames;
- fWeekdaysCount = fShortWeekdaysCount = sizeof(fgLastResortDayNames) / sizeof(fgLastResortDayNames[0]);
- fAmPms = (UnicodeString*)fgLastResortAmPmMarkers;
- fAmPmsCount = sizeof(fgLastResortAmPmMarkers) / sizeof(fgLastResortAmPmMarkers[0]);
- if (fgLastResortZoneStringsH == 0)
- {
- // Initialize this -- the compiler doesn't like to do so at static init time
- UnicodeString **tempH = fgLastResortZoneStringsH = new UnicodeString*[1];
-
- Mutex lock; // This could be optimized but it's not worth it -- exceptional case
- *fgLastResortZoneStringsH = (UnicodeString*)fgLastResortZoneStrings;
- }
- fZoneStrings = fgLastResortZoneStringsH;
- fZoneStringsRowCount = 1;
- fZoneStringsColCount = sizeof(fgLastResortZoneStrings);
- fLocalPatternChars = fgPatternChars;
- }
- return;
- }
-
- // 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 stoerd in a separate file
- fEras = (UnicodeString*)resource.getStringArray(SimpleDateFormat::fgErasTag, fErasCount, status);
- fMonths = (UnicodeString*)resource.getStringArray(SimpleDateFormat::fgMonthNamesTag, fMonthsCount, status);
- fShortMonths = (UnicodeString*)resource.getStringArray(SimpleDateFormat::fgMonthAbbreviationsTag, fShortMonthsCount, status);
- // {sfb} fixed to handle 1-based weekdays
- UnicodeString *lWeekdays = (UnicodeString*)resource.getStringArray(SimpleDateFormat::fgDayNamesTag, fWeekdaysCount, status);
- fWeekdays = new UnicodeString [8];
- fWeekdays[0] = UnicodeString("");
- icu_arrayCopy(lWeekdays, 0, fWeekdays, 1, 7);
- setIsOwned(kWeekdays, TRUE);
- //fWeekdays = (UnicodeString*)resource.getStringArray(SimpleDateFormat::fgDayNamesTag, fWeekdaysCount, status);
-
- UnicodeString *lSWeekdays = (UnicodeString*)resource.getStringArray(SimpleDateFormat::fgDayAbbreviationsTag, fShortWeekdaysCount, status);
- fShortWeekdays = new UnicodeString [8];
- fShortWeekdays[0] = UnicodeString("");
- icu_arrayCopy(lSWeekdays, 0, fShortWeekdays, 1, 7);
- setIsOwned(kShortWeekdays, TRUE);
- //fShortWeekdays = (UnicodeString*)resource.getStringArray(SimpleDateFormat::fgDayAbbreviationsTag, fShortWeekdaysCount, status);
-
- fWeekdaysCount = fShortWeekdaysCount = 8;
-
- fAmPms = (UnicodeString*)resource.getStringArray(SimpleDateFormat::fgAmPmMarkersTag, fAmPmsCount, status);
-
- /**
- * Retrieve the data we need from the time zone data file.
- * We cast away const here, but that's okay; we won't delete any of
- * these.
- */
- ResourceBundle zoneResource(Locale::getDataDirectory(), locale, status);
- fZoneStrings = (UnicodeString**)zoneResource.get2dArray(SimpleDateFormat::fgZoneStringsTag, fZoneStringsRowCount, fZoneStringsColCount, status);
- zoneResource.getString(SimpleDateFormat::fgLocalPatternCharsTag, fLocalPatternChars, status);
- }
-
- /**
- * Package private: used by SimpleDateFormat
- * Gets the index for the given time zone ID to obtain the timezone
- * strings for formatting. The time zone ID is just for programmatic
- * lookup. NOT LOCALIZED!!!
- * @param ID the given time zone ID.
- * @return the index of the given time zone ID. Returns -1 if
- * the given time zone ID can't be located in the DateFormatSymbols object.
- * @see java.util.SimpleTimeZone
- */
- int32_t DateFormatSymbols::getZoneIndex(const UnicodeString& ID) const
- {
- // {sfb} kludge to support case-insensitive comparison
- UnicodeString lcaseID(ID);
- lcaseID.toLower();
-
- for(int32_t index = 0; index < fZoneStringsRowCount; index++) {
- UnicodeString lcase(fZoneStrings[index][0]);
- lcase.toLower();
- if (lcaseID == lcase)
- return index;
- }
-
- return -1;
- }
-
- //eof
-