Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / icu / source / i18n / udat.cpp
index 758a6a7..1af1450 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *******************************************************************************
-*   Copyright (C) 1996-2010, International Business Machines
+*   Copyright (C) 1996-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 */
 #include "unicode/numfmt.h"
 #include "unicode/dtfmtsym.h"
 #include "unicode/ustring.h"
+#include "unicode/udisplaycontext.h"
 #include "cpputils.h"
 #include "reldtfmt.h"
+#include "umutex.h"
 
 U_NAMESPACE_USE
 
@@ -73,7 +75,8 @@ static UCalendarDateFields gDateFieldMapping[] = {
     UCAL_MONTH,                // UDAT_QUARTER_FIELD = 27
     UCAL_MONTH,                // UDAT_STANDALONE_QUARTER_FIELD = 28
     UCAL_ZONE_OFFSET,          // UDAT_TIMEZONE_SPECIAL_FIELD = 29
-    UCAL_FIELD_COUNT,          // UDAT_FIELD_COUNT = 30
+    UCAL_YEAR,                 // UDAT_YEAR_NAME_FIELD = 30
+    UCAL_FIELD_COUNT,          // UDAT_FIELD_COUNT = 31
     // UCAL_IS_LEAP_MONTH is not the target of a mapping
 };
 
@@ -82,6 +85,40 @@ udat_toCalendarDateField(UDateFormatField field) {
   return gDateFieldMapping[field];
 }
 
+/* For now- one opener. */
+static UDateFormatOpener gOpener = NULL;
+
+U_INTERNAL void U_EXPORT2
+udat_registerOpener(UDateFormatOpener opener, UErrorCode *status)
+{
+  if(U_FAILURE(*status)) return;
+  umtx_lock(NULL);
+  if(gOpener==NULL) {
+    gOpener = opener;
+  } else {
+    *status = U_ILLEGAL_ARGUMENT_ERROR;
+  }
+  umtx_unlock(NULL);
+}
+
+U_INTERNAL UDateFormatOpener U_EXPORT2
+udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status)
+{
+  if(U_FAILURE(*status)) return NULL;
+  UDateFormatOpener oldOpener = NULL;
+  umtx_lock(NULL);
+  if(gOpener==NULL || gOpener!=opener) {
+    *status = U_ILLEGAL_ARGUMENT_ERROR;
+  } else {
+    oldOpener=gOpener;
+    gOpener=NULL;
+  }
+  umtx_unlock(NULL);
+  return oldOpener;
+}
+
+
+
 U_CAPI UDateFormat* U_EXPORT2
 udat_open(UDateFormatStyle  timeStyle,
           UDateFormatStyle  dateStyle,
@@ -96,7 +133,13 @@ udat_open(UDateFormatStyle  timeStyle,
     if(U_FAILURE(*status)) {
         return 0;
     }
-    if(timeStyle != UDAT_IGNORE) {
+    if(gOpener!=NULL) { // if it's registered
+      fmt = (DateFormat*) (*gOpener)(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status);
+      if(fmt!=NULL) {
+        return (UDateFormat*)fmt;
+      } // else fall through.
+    }
+    if(timeStyle != UDAT_PATTERN) {
         if(locale == 0) {
             fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
                 (DateFormat::EStyle)timeStyle);
@@ -385,11 +428,16 @@ udat_getSymbols(const   UDateFormat     *fmt,
                 int32_t                 resultLength,
                 UErrorCode              *status)
 {
-    verifyIsSimpleDateFormat(fmt, status);
-    if(U_FAILURE(*status)) return -1;
-
-    const DateFormatSymbols *syms = 
-        ((SimpleDateFormat*)fmt)->getDateFormatSymbols();
+    const DateFormatSymbols *syms;
+    const SimpleDateFormat* sdtfmt;
+    const RelativeDateFormat* rdtfmt;
+    if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
+        syms = sdtfmt->getDateFormatSymbols();
+    } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
+        syms = rdtfmt->getDateFormatSymbols();
+    } else {
+        return -1;
+    }
     int32_t count;
     const UnicodeString *res = NULL;
 
@@ -438,6 +486,10 @@ udat_getSymbols(const   UDateFormat     *fmt,
         res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
         break;
 
+    case UDAT_SHORTER_WEEKDAYS:
+        res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
+        break;
+
     case UDAT_NARROW_WEEKDAYS:
         res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
         break;
@@ -462,6 +514,10 @@ udat_getSymbols(const   UDateFormat     *fmt,
         res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
         break;
 
+    case UDAT_STANDALONE_SHORTER_WEEKDAYS:
+        res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
+        break;
+
     case UDAT_STANDALONE_NARROW_WEEKDAYS:
         res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
         break;
@@ -495,15 +551,16 @@ U_CAPI int32_t U_EXPORT2
 udat_countSymbols(    const    UDateFormat                *fmt,
             UDateFormatSymbolType    type)
 {
-    UErrorCode status = U_ZERO_ERROR;
-    
-    verifyIsSimpleDateFormat(fmt, &status);
-    if(U_FAILURE(status)) {
+    const DateFormatSymbols *syms;
+    const SimpleDateFormat* sdtfmt;
+    const RelativeDateFormat* rdtfmt;
+    if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
+        syms = sdtfmt->getDateFormatSymbols();
+    } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
+        syms = rdtfmt->getDateFormatSymbols();
+    } else {
         return 0;
     }
-
-    const DateFormatSymbols *syms = 
-        ((SimpleDateFormat*)fmt)->getDateFormatSymbols();
     int32_t count = 0;
 
     switch(type) {
@@ -543,6 +600,10 @@ udat_countSymbols(    const    UDateFormat                *fmt,
         syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
         break;
 
+    case UDAT_SHORTER_WEEKDAYS:
+        syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
+        break;
+
     case UDAT_NARROW_WEEKDAYS:
         syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
         break;
@@ -567,6 +628,10 @@ udat_countSymbols(    const    UDateFormat                *fmt,
         syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
         break;
 
+    case UDAT_STANDALONE_SHORTER_WEEKDAYS:
+        syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
+        break;
+
     case UDAT_STANDALONE_NARROW_WEEKDAYS:
         syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
         break;
@@ -706,6 +771,13 @@ public:
     }
 
     static void
+        setShorterWeekday(DateFormatSymbols *syms, int32_t index,
+        const UChar *value, int32_t valueLength, UErrorCode &errorCode)
+    {
+        setSymbol(syms->fShorterWeekdays, syms->fShorterWeekdaysCount, index, value, valueLength, errorCode);
+    }
+
+    static void
         setNarrowWeekday(DateFormatSymbols *syms, int32_t index,
         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
     {
@@ -727,6 +799,13 @@ public:
     }
 
     static void
+        setStandaloneShorterWeekday(DateFormatSymbols *syms, int32_t index,
+        const UChar *value, int32_t valueLength, UErrorCode &errorCode)
+    {
+        setSymbol(syms->fStandaloneShorterWeekdays, syms->fStandaloneShorterWeekdaysCount, index, value, valueLength, errorCode);
+    }
+
+    static void
         setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index,
         const UChar *value, int32_t valueLength, UErrorCode &errorCode)
     {
@@ -832,6 +911,10 @@ udat_setSymbols(    UDateFormat             *format,
         DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status);
         break;
 
+    case UDAT_SHORTER_WEEKDAYS:
+        DateFormatSymbolsSingleSetter::setShorterWeekday(syms, index, value, valueLength, *status);
+        break;
+
     case UDAT_NARROW_WEEKDAYS:
         DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status);
         break;
@@ -844,6 +927,10 @@ udat_setSymbols(    UDateFormat             *format,
         DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status);
         break;
 
+    case UDAT_STANDALONE_SHORTER_WEEKDAYS:
+        DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms, index, value, valueLength, *status);
+        break;
+
     case UDAT_STANDALONE_NARROW_WEEKDAYS:
         DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status);
         break;
@@ -893,6 +980,28 @@ udat_getLocaleByType(const UDateFormat *fmt,
     return ((Format*)fmt)->getLocaleID(type, *status);
 }
 
+
+U_CAPI void U_EXPORT2
+udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status)
+{
+    verifyIsSimpleDateFormat(fmt, status);
+    if (U_FAILURE(*status)) {
+        return;
+    }
+    ((SimpleDateFormat*)fmt)->setContext(value, *status);
+}
+
+U_CAPI UDisplayContext U_EXPORT2
+udat_getContext(UDateFormat* fmt, UDisplayContextType type, UErrorCode* status)
+{
+    verifyIsSimpleDateFormat(fmt, status);
+    if (U_FAILURE(*status)) {
+        return (UDisplayContext)0;
+    }
+    return ((SimpleDateFormat*)fmt)->getContext(type, *status);
+}
+
+
 /**
  * Verify that fmt is a RelativeDateFormat. Invalid error if not.
  * @param fmt the UDateFormat, definitely a DateFormat, maybe something else