intl/icu/source/i18n/udat.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /*
     2 *******************************************************************************
     3 *   Copyright (C) 1996-2013, International Business Machines
     4 *   Corporation and others.  All Rights Reserved.
     5 *******************************************************************************
     6 */
     8 #include "unicode/utypes.h"
    10 #if !UCONFIG_NO_FORMATTING
    12 #include "unicode/udat.h"
    14 #include "unicode/uloc.h"
    15 #include "unicode/datefmt.h"
    16 #include "unicode/timezone.h"
    17 #include "unicode/smpdtfmt.h"
    18 #include "unicode/fieldpos.h"
    19 #include "unicode/parsepos.h"
    20 #include "unicode/calendar.h"
    21 #include "unicode/numfmt.h"
    22 #include "unicode/dtfmtsym.h"
    23 #include "unicode/ustring.h"
    24 #include "unicode/udisplaycontext.h"
    25 #include "cpputils.h"
    26 #include "reldtfmt.h"
    27 #include "umutex.h"
    29 U_NAMESPACE_USE
    31 /**
    32  * Verify that fmt is a SimpleDateFormat. Invalid error if not.
    33  * @param fmt the UDateFormat, definitely a DateFormat, maybe something else
    34  * @param status error code, will be set to failure if there is a familure or the fmt is NULL.
    35  */
    36 static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) {
    37    if(U_SUCCESS(*status) &&
    38        dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) {
    39        *status = U_ILLEGAL_ARGUMENT_ERROR;
    40    }
    41 }
    43 // This mirrors the correspondence between the
    44 // SimpleDateFormat::fgPatternIndexToDateFormatField and
    45 // SimpleDateFormat::fgPatternIndexToCalendarField arrays.
    46 static UCalendarDateFields gDateFieldMapping[] = {
    47     UCAL_ERA,                  // UDAT_ERA_FIELD = 0
    48     UCAL_YEAR,                 // UDAT_YEAR_FIELD = 1
    49     UCAL_MONTH,                // UDAT_MONTH_FIELD = 2
    50     UCAL_DATE,                 // UDAT_DATE_FIELD = 3
    51     UCAL_HOUR_OF_DAY,          // UDAT_HOUR_OF_DAY1_FIELD = 4
    52     UCAL_HOUR_OF_DAY,          // UDAT_HOUR_OF_DAY0_FIELD = 5
    53     UCAL_MINUTE,               // UDAT_MINUTE_FIELD = 6
    54     UCAL_SECOND,               // UDAT_SECOND_FIELD = 7
    55     UCAL_MILLISECOND,          // UDAT_FRACTIONAL_SECOND_FIELD = 8
    56     UCAL_DAY_OF_WEEK,          // UDAT_DAY_OF_WEEK_FIELD = 9
    57     UCAL_DAY_OF_YEAR,          // UDAT_DAY_OF_YEAR_FIELD = 10
    58     UCAL_DAY_OF_WEEK_IN_MONTH, // UDAT_DAY_OF_WEEK_IN_MONTH_FIELD = 11
    59     UCAL_WEEK_OF_YEAR,         // UDAT_WEEK_OF_YEAR_FIELD = 12
    60     UCAL_WEEK_OF_MONTH,        // UDAT_WEEK_OF_MONTH_FIELD = 13
    61     UCAL_AM_PM,                // UDAT_AM_PM_FIELD = 14
    62     UCAL_HOUR,                 // UDAT_HOUR1_FIELD = 15
    63     UCAL_HOUR,                 // UDAT_HOUR0_FIELD = 16
    64     UCAL_ZONE_OFFSET,          // UDAT_TIMEZONE_FIELD = 17
    65     UCAL_YEAR_WOY,             // UDAT_YEAR_WOY_FIELD = 18
    66     UCAL_DOW_LOCAL,            // UDAT_DOW_LOCAL_FIELD = 19
    67     UCAL_EXTENDED_YEAR,        // UDAT_EXTENDED_YEAR_FIELD = 20
    68     UCAL_JULIAN_DAY,           // UDAT_JULIAN_DAY_FIELD = 21
    69     UCAL_MILLISECONDS_IN_DAY,  // UDAT_MILLISECONDS_IN_DAY_FIELD = 22
    70     UCAL_ZONE_OFFSET,          // UDAT_TIMEZONE_RFC_FIELD = 23
    71     // UCAL_DST_OFFSET also
    72     UCAL_ZONE_OFFSET,          // UDAT_TIMEZONE_GENERIC_FIELD = 24
    73     UCAL_DOW_LOCAL,            // UDAT_STANDALONE_DAY_FIELD = 25
    74     UCAL_MONTH,                // UDAT_STANDALONE_MONTH_FIELD = 26
    75     UCAL_MONTH,                // UDAT_QUARTER_FIELD = 27
    76     UCAL_MONTH,                // UDAT_STANDALONE_QUARTER_FIELD = 28
    77     UCAL_ZONE_OFFSET,          // UDAT_TIMEZONE_SPECIAL_FIELD = 29
    78     UCAL_YEAR,                 // UDAT_YEAR_NAME_FIELD = 30
    79     UCAL_FIELD_COUNT,          // UDAT_FIELD_COUNT = 31
    80     // UCAL_IS_LEAP_MONTH is not the target of a mapping
    81 };
    83 U_CAPI UCalendarDateFields U_EXPORT2
    84 udat_toCalendarDateField(UDateFormatField field) {
    85   return gDateFieldMapping[field];
    86 }
    88 /* For now- one opener. */
    89 static UDateFormatOpener gOpener = NULL;
    91 U_INTERNAL void U_EXPORT2
    92 udat_registerOpener(UDateFormatOpener opener, UErrorCode *status)
    93 {
    94   if(U_FAILURE(*status)) return;
    95   umtx_lock(NULL);
    96   if(gOpener==NULL) {
    97     gOpener = opener;
    98   } else {
    99     *status = U_ILLEGAL_ARGUMENT_ERROR;
   100   }
   101   umtx_unlock(NULL);
   102 }
   104 U_INTERNAL UDateFormatOpener U_EXPORT2
   105 udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status)
   106 {
   107   if(U_FAILURE(*status)) return NULL;
   108   UDateFormatOpener oldOpener = NULL;
   109   umtx_lock(NULL);
   110   if(gOpener==NULL || gOpener!=opener) {
   111     *status = U_ILLEGAL_ARGUMENT_ERROR;
   112   } else {
   113     oldOpener=gOpener;
   114     gOpener=NULL;
   115   }
   116   umtx_unlock(NULL);
   117   return oldOpener;
   118 }
   122 U_CAPI UDateFormat* U_EXPORT2
   123 udat_open(UDateFormatStyle  timeStyle,
   124           UDateFormatStyle  dateStyle,
   125           const char        *locale,
   126           const UChar       *tzID,
   127           int32_t           tzIDLength,
   128           const UChar       *pattern,
   129           int32_t           patternLength,
   130           UErrorCode        *status)
   131 {
   132     DateFormat *fmt;
   133     if(U_FAILURE(*status)) {
   134         return 0;
   135     }
   136     if(gOpener!=NULL) { // if it's registered
   137       fmt = (DateFormat*) (*gOpener)(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status);
   138       if(fmt!=NULL) {
   139         return (UDateFormat*)fmt;
   140       } // else fall through.
   141     }
   142     if(timeStyle != UDAT_PATTERN) {
   143         if(locale == 0) {
   144             fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
   145                 (DateFormat::EStyle)timeStyle);
   146         }
   147         else {
   148             fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
   149                 (DateFormat::EStyle)timeStyle,
   150                 Locale(locale));
   151         }
   152     }
   153     else {
   154         UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
   156         if(locale == 0) {
   157             fmt = new SimpleDateFormat(pat, *status);
   158         }
   159         else {
   160             fmt = new SimpleDateFormat(pat, Locale(locale), *status);
   161         }
   162     }
   164     if(fmt == 0) {
   165         *status = U_MEMORY_ALLOCATION_ERROR;
   166         return 0;
   167     }
   169     if(tzID != 0) {
   170         TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength));
   171         if(zone == 0) {
   172             *status = U_MEMORY_ALLOCATION_ERROR;
   173             delete fmt;
   174             return 0;
   175         }
   176         fmt->adoptTimeZone(zone);
   177     }
   179     return (UDateFormat*)fmt;
   180 }
   183 U_CAPI void U_EXPORT2
   184 udat_close(UDateFormat* format)
   185 {
   186     delete (DateFormat*)format;
   187 }
   189 U_CAPI UDateFormat* U_EXPORT2
   190 udat_clone(const UDateFormat *fmt,
   191        UErrorCode *status)
   192 {
   193     if(U_FAILURE(*status)) return 0;
   195     Format *res = ((DateFormat*)fmt)->clone();
   197     if(res == 0) {
   198         *status = U_MEMORY_ALLOCATION_ERROR;
   199         return 0;
   200     }
   202     return (UDateFormat*) res;
   203 }
   205 U_CAPI int32_t U_EXPORT2
   206 udat_format(    const    UDateFormat*    format,
   207         UDate           dateToFormat,
   208         UChar*          result,
   209         int32_t         resultLength,
   210         UFieldPosition* position,
   211         UErrorCode*     status)
   212 {
   213     if(U_FAILURE(*status)) return -1;
   215     UnicodeString res;
   216     if(!(result==NULL && resultLength==0)) {
   217         // NULL destination for pure preflighting: empty dummy string
   218         // otherwise, alias the destination buffer
   219         res.setTo(result, 0, resultLength);
   220     }
   222     FieldPosition fp;
   224     if(position != 0)
   225         fp.setField(position->field);
   227     ((DateFormat*)format)->format(dateToFormat, res, fp);
   229     if(position != 0) {
   230         position->beginIndex = fp.getBeginIndex();
   231         position->endIndex = fp.getEndIndex();
   232     }
   234     return res.extract(result, resultLength, *status);
   235 }
   237 U_CAPI UDate U_EXPORT2
   238 udat_parse(    const    UDateFormat*        format,
   239         const    UChar*          text,
   240         int32_t         textLength,
   241         int32_t         *parsePos,
   242         UErrorCode      *status)
   243 {
   244     if(U_FAILURE(*status)) return (UDate)0;
   246     const UnicodeString src((UBool)(textLength == -1), text, textLength);
   247     ParsePosition pp;
   248     int32_t stackParsePos = 0;
   249     UDate res;
   251     if(parsePos == NULL) {
   252         parsePos = &stackParsePos;
   253     }
   255     pp.setIndex(*parsePos);
   257     res = ((DateFormat*)format)->parse(src, pp);
   259     if(pp.getErrorIndex() == -1)
   260         *parsePos = pp.getIndex();
   261     else {
   262         *parsePos = pp.getErrorIndex();
   263         *status = U_PARSE_ERROR;
   264     }
   266     return res;
   267 }
   269 U_CAPI void U_EXPORT2
   270 udat_parseCalendar(const    UDateFormat*    format,
   271                             UCalendar*      calendar,
   272                    const    UChar*          text,
   273                             int32_t         textLength,
   274                             int32_t         *parsePos,
   275                             UErrorCode      *status)
   276 {
   277     if(U_FAILURE(*status)) return;
   279     const UnicodeString src((UBool)(textLength == -1), text, textLength);
   280     ParsePosition pp;
   282     if(parsePos != 0)
   283         pp.setIndex(*parsePos);
   285     ((DateFormat*)format)->parse(src, *(Calendar*)calendar, pp);
   287     if(parsePos != 0) {
   288         if(pp.getErrorIndex() == -1)
   289             *parsePos = pp.getIndex();
   290         else {
   291             *parsePos = pp.getErrorIndex();
   292             *status = U_PARSE_ERROR;
   293         }
   294     }
   295 }
   297 U_CAPI UBool U_EXPORT2
   298 udat_isLenient(const UDateFormat* fmt)
   299 {
   300     return ((DateFormat*)fmt)->isLenient();
   301 }
   303 U_CAPI void U_EXPORT2
   304 udat_setLenient(    UDateFormat*    fmt,
   305             UBool          isLenient)
   306 {
   307     ((DateFormat*)fmt)->setLenient(isLenient);
   308 }
   310 U_CAPI const UCalendar* U_EXPORT2
   311 udat_getCalendar(const UDateFormat* fmt)
   312 {
   313     return (const UCalendar*) ((DateFormat*)fmt)->getCalendar();
   314 }
   316 U_CAPI void U_EXPORT2
   317 udat_setCalendar(UDateFormat*    fmt,
   318                  const   UCalendar*      calendarToSet)
   319 {
   320     ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet));
   321 }
   323 U_CAPI const UNumberFormat* U_EXPORT2
   324 udat_getNumberFormat(const UDateFormat* fmt)
   325 {
   326     return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat();
   327 }
   329 U_CAPI void U_EXPORT2
   330 udat_setNumberFormat(UDateFormat*    fmt,
   331                      const   UNumberFormat*  numberFormatToSet)
   332 {
   333     ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet));
   334 }
   336 U_CAPI const char* U_EXPORT2
   337 udat_getAvailable(int32_t index)
   338 {
   339     return uloc_getAvailable(index);
   340 }
   342 U_CAPI int32_t U_EXPORT2
   343 udat_countAvailable()
   344 {
   345     return uloc_countAvailable();
   346 }
   348 U_CAPI UDate U_EXPORT2
   349 udat_get2DigitYearStart(    const   UDateFormat     *fmt,
   350                         UErrorCode      *status)
   351 {
   352     verifyIsSimpleDateFormat(fmt, status);
   353     if(U_FAILURE(*status)) return (UDate)0;
   354     return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status);
   355 }
   357 U_CAPI void U_EXPORT2
   358 udat_set2DigitYearStart(    UDateFormat     *fmt,
   359                         UDate           d,
   360                         UErrorCode      *status)
   361 {
   362     verifyIsSimpleDateFormat(fmt, status);
   363     if(U_FAILURE(*status)) return;
   364     ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status);
   365 }
   367 U_CAPI int32_t U_EXPORT2
   368 udat_toPattern(    const   UDateFormat     *fmt,
   369         UBool          localized,
   370         UChar           *result,
   371         int32_t         resultLength,
   372         UErrorCode      *status)
   373 {
   374     if(U_FAILURE(*status)) return -1;
   376     UnicodeString res;
   377     if(!(result==NULL && resultLength==0)) {
   378         // NULL destination for pure preflighting: empty dummy string
   379         // otherwise, alias the destination buffer
   380         res.setTo(result, 0, resultLength);
   381     }
   383     const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt);
   384     const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df);
   385     const RelativeDateFormat *reldtfmt;
   386     if (sdtfmt!=NULL) {
   387         if(localized)
   388             sdtfmt->toLocalizedPattern(res, *status);
   389         else
   390             sdtfmt->toPattern(res);
   391     } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=NULL) {
   392         reldtfmt->toPattern(res, *status);
   393     } else {
   394         *status = U_ILLEGAL_ARGUMENT_ERROR;
   395         return -1;
   396     }
   398     return res.extract(result, resultLength, *status);
   399 }
   401 // TODO: should this take an UErrorCode?
   402 // A: Yes. Of course.
   403 U_CAPI void U_EXPORT2
   404 udat_applyPattern(  UDateFormat     *format,
   405                     UBool          localized,
   406                     const   UChar           *pattern,
   407                     int32_t         patternLength)
   408 {
   409     const UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
   410     UErrorCode status = U_ZERO_ERROR;
   412     verifyIsSimpleDateFormat(format, &status);
   413     if(U_FAILURE(status)) {
   414         return;
   415     }
   417     if(localized)
   418         ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status);
   419     else
   420         ((SimpleDateFormat*)format)->applyPattern(pat);
   421 }
   423 U_CAPI int32_t U_EXPORT2
   424 udat_getSymbols(const   UDateFormat     *fmt,
   425                 UDateFormatSymbolType   type,
   426                 int32_t                 index,
   427                 UChar                   *result,
   428                 int32_t                 resultLength,
   429                 UErrorCode              *status)
   430 {
   431     const DateFormatSymbols *syms;
   432     const SimpleDateFormat* sdtfmt;
   433     const RelativeDateFormat* rdtfmt;
   434     if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
   435         syms = sdtfmt->getDateFormatSymbols();
   436     } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
   437         syms = rdtfmt->getDateFormatSymbols();
   438     } else {
   439         return -1;
   440     }
   441     int32_t count;
   442     const UnicodeString *res = NULL;
   444     switch(type) {
   445     case UDAT_ERAS:
   446         res = syms->getEras(count);
   447         break;
   449     case UDAT_ERA_NAMES:
   450         res = syms->getEraNames(count);
   451         break;
   453     case UDAT_MONTHS:
   454         res = syms->getMonths(count);
   455         break;
   457     case UDAT_SHORT_MONTHS:
   458         res = syms->getShortMonths(count);
   459         break;
   461     case UDAT_WEEKDAYS:
   462         res = syms->getWeekdays(count);
   463         break;
   465     case UDAT_SHORT_WEEKDAYS:
   466         res = syms->getShortWeekdays(count);
   467         break;
   469     case UDAT_AM_PMS:
   470         res = syms->getAmPmStrings(count);
   471         break;
   473     case UDAT_LOCALIZED_CHARS:
   474         {
   475             UnicodeString res1;
   476             if(!(result==NULL && resultLength==0)) {
   477                 // NULL destination for pure preflighting: empty dummy string
   478                 // otherwise, alias the destination buffer
   479                 res1.setTo(result, 0, resultLength);
   480             }
   481             syms->getLocalPatternChars(res1);
   482             return res1.extract(result, resultLength, *status);
   483         }
   485     case UDAT_NARROW_MONTHS:
   486         res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
   487         break;
   489     case UDAT_SHORTER_WEEKDAYS:
   490         res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
   491         break;
   493     case UDAT_NARROW_WEEKDAYS:
   494         res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
   495         break;
   497     case UDAT_STANDALONE_MONTHS:
   498         res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
   499         break;
   501     case UDAT_STANDALONE_SHORT_MONTHS:
   502         res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
   503         break;
   505     case UDAT_STANDALONE_NARROW_MONTHS:
   506         res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
   507         break;
   509     case UDAT_STANDALONE_WEEKDAYS:
   510         res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
   511         break;
   513     case UDAT_STANDALONE_SHORT_WEEKDAYS:
   514         res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
   515         break;
   517     case UDAT_STANDALONE_SHORTER_WEEKDAYS:
   518         res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
   519         break;
   521     case UDAT_STANDALONE_NARROW_WEEKDAYS:
   522         res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
   523         break;
   525     case UDAT_QUARTERS:
   526         res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
   527         break;
   529     case UDAT_SHORT_QUARTERS:
   530         res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
   531         break;
   533     case UDAT_STANDALONE_QUARTERS:
   534         res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
   535         break;
   537     case UDAT_STANDALONE_SHORT_QUARTERS:
   538         res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
   539         break;
   541     }
   543     if(index < count) {
   544         return res[index].extract(result, resultLength, *status);
   545     }
   546     return 0;
   547 }
   549 // TODO: also needs an errorCode.
   550 U_CAPI int32_t U_EXPORT2
   551 udat_countSymbols(    const    UDateFormat                *fmt,
   552             UDateFormatSymbolType    type)
   553 {
   554     const DateFormatSymbols *syms;
   555     const SimpleDateFormat* sdtfmt;
   556     const RelativeDateFormat* rdtfmt;
   557     if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
   558         syms = sdtfmt->getDateFormatSymbols();
   559     } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
   560         syms = rdtfmt->getDateFormatSymbols();
   561     } else {
   562         return 0;
   563     }
   564     int32_t count = 0;
   566     switch(type) {
   567     case UDAT_ERAS:
   568         syms->getEras(count);
   569         break;
   571     case UDAT_MONTHS:
   572         syms->getMonths(count);
   573         break;
   575     case UDAT_SHORT_MONTHS:
   576         syms->getShortMonths(count);
   577         break;
   579     case UDAT_WEEKDAYS:
   580         syms->getWeekdays(count);
   581         break;
   583     case UDAT_SHORT_WEEKDAYS:
   584         syms->getShortWeekdays(count);
   585         break;
   587     case UDAT_AM_PMS:
   588         syms->getAmPmStrings(count);
   589         break;
   591     case UDAT_LOCALIZED_CHARS:
   592         count = 1;
   593         break;
   595     case UDAT_ERA_NAMES:
   596         syms->getEraNames(count);
   597         break;
   599     case UDAT_NARROW_MONTHS:
   600         syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
   601         break;
   603     case UDAT_SHORTER_WEEKDAYS:
   604         syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
   605         break;
   607     case UDAT_NARROW_WEEKDAYS:
   608         syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
   609         break;
   611     case UDAT_STANDALONE_MONTHS:
   612         syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
   613         break;
   615     case UDAT_STANDALONE_SHORT_MONTHS:
   616         syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
   617         break;
   619     case UDAT_STANDALONE_NARROW_MONTHS:
   620         syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
   621         break;
   623     case UDAT_STANDALONE_WEEKDAYS:
   624         syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
   625         break;
   627     case UDAT_STANDALONE_SHORT_WEEKDAYS:
   628         syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
   629         break;
   631     case UDAT_STANDALONE_SHORTER_WEEKDAYS:
   632         syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
   633         break;
   635     case UDAT_STANDALONE_NARROW_WEEKDAYS:
   636         syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
   637         break;
   639     case UDAT_QUARTERS:
   640         syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
   641         break;
   643     case UDAT_SHORT_QUARTERS:
   644         syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
   645         break;
   647     case UDAT_STANDALONE_QUARTERS:
   648         syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
   649         break;
   651     case UDAT_STANDALONE_SHORT_QUARTERS:
   652         syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
   653         break;
   655     }
   657     return count;
   658 }
   660 U_NAMESPACE_BEGIN
   662 /*
   663  * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols
   664  * solely for the purpose of avoiding to clone the array of strings
   665  * just to modify one of them and then setting all of them back.
   666  * For example, the old code looked like this:
   667  *  case UDAT_MONTHS:
   668  *    res = syms->getMonths(count);
   669  *    array = new UnicodeString[count];
   670  *    if(array == 0) {
   671  *      *status = U_MEMORY_ALLOCATION_ERROR;
   672  *      return;
   673  *    }
   674  *    uprv_arrayCopy(res, array, count);
   675  *    if(index < count)
   676  *      array[index] = val;
   677  *    syms->setMonths(array, count);
   678  *    break;
   679  *
   680  * Even worse, the old code actually cloned the entire DateFormatSymbols object,
   681  * cloned one value array, changed one value, and then made the SimpleDateFormat
   682  * replace its DateFormatSymbols object with the new one.
   683  *
   684  * markus 2002-oct-14
   685  */
   686 class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ {
   687 public:
   688     static void
   689         setSymbol(UnicodeString *array, int32_t count, int32_t index,
   690         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   691     {
   692         if(array!=NULL) {
   693             if(index>=count) {
   694                 errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
   695             } else if(value==NULL) {
   696                 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
   697             } else {
   698                 array[index].setTo(value, valueLength);
   699             }
   700         }
   701     }
   703     static void
   704         setEra(DateFormatSymbols *syms, int32_t index,
   705         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   706     {
   707         setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode);
   708     }
   710     static void
   711         setEraName(DateFormatSymbols *syms, int32_t index,
   712         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   713     {
   714         setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode);
   715     }
   717     static void
   718         setMonth(DateFormatSymbols *syms, int32_t index,
   719         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   720     {
   721         setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode);
   722     }
   724     static void
   725         setShortMonth(DateFormatSymbols *syms, int32_t index,
   726         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   727     {
   728         setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode);
   729     }
   731     static void
   732         setNarrowMonth(DateFormatSymbols *syms, int32_t index,
   733         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   734     {
   735         setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode);
   736     }
   738     static void
   739         setStandaloneMonth(DateFormatSymbols *syms, int32_t index,
   740         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   741     {
   742         setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode);
   743     }
   745     static void
   746         setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index,
   747         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   748     {
   749         setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode);
   750     }
   752     static void
   753         setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index,
   754         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   755     {
   756         setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode);
   757     }
   759     static void
   760         setWeekday(DateFormatSymbols *syms, int32_t index,
   761         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   762     {
   763         setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode);
   764     }
   766     static void
   767         setShortWeekday(DateFormatSymbols *syms, int32_t index,
   768         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   769     {
   770         setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode);
   771     }
   773     static void
   774         setShorterWeekday(DateFormatSymbols *syms, int32_t index,
   775         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   776     {
   777         setSymbol(syms->fShorterWeekdays, syms->fShorterWeekdaysCount, index, value, valueLength, errorCode);
   778     }
   780     static void
   781         setNarrowWeekday(DateFormatSymbols *syms, int32_t index,
   782         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   783     {
   784         setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode);
   785     }
   787     static void
   788         setStandaloneWeekday(DateFormatSymbols *syms, int32_t index,
   789         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   790     {
   791         setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode);
   792     }
   794     static void
   795         setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index,
   796         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   797     {
   798         setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode);
   799     }
   801     static void
   802         setStandaloneShorterWeekday(DateFormatSymbols *syms, int32_t index,
   803         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   804     {
   805         setSymbol(syms->fStandaloneShorterWeekdays, syms->fStandaloneShorterWeekdaysCount, index, value, valueLength, errorCode);
   806     }
   808     static void
   809         setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index,
   810         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   811     {
   812         setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode);
   813     }
   815     static void
   816         setQuarter(DateFormatSymbols *syms, int32_t index,
   817         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   818     {
   819         setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode);
   820     }
   822     static void
   823         setShortQuarter(DateFormatSymbols *syms, int32_t index,
   824         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   825     {
   826         setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode);
   827     }
   829     static void
   830         setStandaloneQuarter(DateFormatSymbols *syms, int32_t index,
   831         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   832     {
   833         setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode);
   834     }
   836     static void
   837         setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index,
   838         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   839     {
   840         setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode);
   841     }
   843     static void
   844         setAmPm(DateFormatSymbols *syms, int32_t index,
   845         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   846     {
   847         setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode);
   848     }
   850     static void
   851         setLocalPatternChars(DateFormatSymbols *syms,
   852         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
   853     {
   854         setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode);
   855     }
   856 };
   858 U_NAMESPACE_END
   860 U_CAPI void U_EXPORT2
   861 udat_setSymbols(    UDateFormat             *format,
   862             UDateFormatSymbolType   type,
   863             int32_t                 index,
   864             UChar                   *value,
   865             int32_t                 valueLength,
   866             UErrorCode              *status)
   867 {
   868     verifyIsSimpleDateFormat(format, status);
   869     if(U_FAILURE(*status)) return;
   871     DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols();
   873     switch(type) {
   874     case UDAT_ERAS:
   875         DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status);
   876         break;
   878     case UDAT_ERA_NAMES:
   879         DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status);
   880         break;
   882     case UDAT_MONTHS:
   883         DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status);
   884         break;
   886     case UDAT_SHORT_MONTHS:
   887         DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status);
   888         break;
   890     case UDAT_NARROW_MONTHS:
   891         DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status);
   892         break;
   894     case UDAT_STANDALONE_MONTHS:
   895         DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status);
   896         break;
   898     case UDAT_STANDALONE_SHORT_MONTHS:
   899         DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status);
   900         break;
   902     case UDAT_STANDALONE_NARROW_MONTHS:
   903         DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status);
   904         break;
   906     case UDAT_WEEKDAYS:
   907         DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status);
   908         break;
   910     case UDAT_SHORT_WEEKDAYS:
   911         DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status);
   912         break;
   914     case UDAT_SHORTER_WEEKDAYS:
   915         DateFormatSymbolsSingleSetter::setShorterWeekday(syms, index, value, valueLength, *status);
   916         break;
   918     case UDAT_NARROW_WEEKDAYS:
   919         DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status);
   920         break;
   922     case UDAT_STANDALONE_WEEKDAYS:
   923         DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status);
   924         break;
   926     case UDAT_STANDALONE_SHORT_WEEKDAYS:
   927         DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status);
   928         break;
   930     case UDAT_STANDALONE_SHORTER_WEEKDAYS:
   931         DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms, index, value, valueLength, *status);
   932         break;
   934     case UDAT_STANDALONE_NARROW_WEEKDAYS:
   935         DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status);
   936         break;
   938     case UDAT_QUARTERS:
   939         DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status);
   940         break;
   942     case UDAT_SHORT_QUARTERS:
   943         DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status);
   944         break;
   946     case UDAT_STANDALONE_QUARTERS:
   947         DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status);
   948         break;
   950     case UDAT_STANDALONE_SHORT_QUARTERS:
   951         DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status);
   952         break;
   954     case UDAT_AM_PMS:
   955         DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status);
   956         break;
   958     case UDAT_LOCALIZED_CHARS:
   959         DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status);
   960         break;
   962     default:
   963         *status = U_UNSUPPORTED_ERROR;
   964         break;
   966     }
   967 }
   969 U_CAPI const char* U_EXPORT2
   970 udat_getLocaleByType(const UDateFormat *fmt,
   971                      ULocDataLocaleType type,
   972                      UErrorCode* status)
   973 {
   974     if (fmt == NULL) {
   975         if (U_SUCCESS(*status)) {
   976             *status = U_ILLEGAL_ARGUMENT_ERROR;
   977         }
   978         return NULL;
   979     }
   980     return ((Format*)fmt)->getLocaleID(type, *status);
   981 }
   984 U_CAPI void U_EXPORT2
   985 udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status)
   986 {
   987     verifyIsSimpleDateFormat(fmt, status);
   988     if (U_FAILURE(*status)) {
   989         return;
   990     }
   991     ((SimpleDateFormat*)fmt)->setContext(value, *status);
   992 }
   994 U_CAPI UDisplayContext U_EXPORT2
   995 udat_getContext(UDateFormat* fmt, UDisplayContextType type, UErrorCode* status)
   996 {
   997     verifyIsSimpleDateFormat(fmt, status);
   998     if (U_FAILURE(*status)) {
   999         return (UDisplayContext)0;
  1001     return ((SimpleDateFormat*)fmt)->getContext(type, *status);
  1005 /**
  1006  * Verify that fmt is a RelativeDateFormat. Invalid error if not.
  1007  * @param fmt the UDateFormat, definitely a DateFormat, maybe something else
  1008  * @param status error code, will be set to failure if there is a familure or the fmt is NULL.
  1009  */
  1010 static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) {
  1011    if(U_SUCCESS(*status) &&
  1012        dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) {
  1013        *status = U_ILLEGAL_ARGUMENT_ERROR;
  1018 U_CAPI int32_t U_EXPORT2 
  1019 udat_toPatternRelativeDate(const UDateFormat *fmt,
  1020                            UChar             *result,
  1021                            int32_t           resultLength,
  1022                            UErrorCode        *status)
  1024     verifyIsRelativeDateFormat(fmt, status);
  1025     if(U_FAILURE(*status)) return -1;
  1027     UnicodeString datePattern;
  1028     if(!(result==NULL && resultLength==0)) {
  1029         // NULL destination for pure preflighting: empty dummy string
  1030         // otherwise, alias the destination buffer
  1031         datePattern.setTo(result, 0, resultLength);
  1033     ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status);
  1034     return datePattern.extract(result, resultLength, *status);
  1037 U_CAPI int32_t U_EXPORT2 
  1038 udat_toPatternRelativeTime(const UDateFormat *fmt,
  1039                            UChar             *result,
  1040                            int32_t           resultLength,
  1041                            UErrorCode        *status)
  1043     verifyIsRelativeDateFormat(fmt, status);
  1044     if(U_FAILURE(*status)) return -1;
  1046     UnicodeString timePattern;
  1047     if(!(result==NULL && resultLength==0)) {
  1048         // NULL destination for pure preflighting: empty dummy string
  1049         // otherwise, alias the destination buffer
  1050         timePattern.setTo(result, 0, resultLength);
  1052     ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status);
  1053     return timePattern.extract(result, resultLength, *status);
  1056 U_CAPI void U_EXPORT2 
  1057 udat_applyPatternRelative(UDateFormat *format,
  1058                           const UChar *datePattern,
  1059                           int32_t     datePatternLength,
  1060                           const UChar *timePattern,
  1061                           int32_t     timePatternLength,
  1062                           UErrorCode  *status)
  1064     verifyIsRelativeDateFormat(format, status);
  1065     if(U_FAILURE(*status)) return;
  1066     const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, datePatternLength);
  1067     const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, timePatternLength);
  1068     ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status);
  1071 #endif /* #if !UCONFIG_NO_FORMATTING */

mercurial