Merge "Fix compilation warnning for locales." into devel_3.0_main
[platform/framework/native/appfw.git] / src / locales / FLcl_LocaleData.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file        FLclLocaleData.cpp
19  * @brief       This is the implementation file for _LocaleData class.
20  */
21
22 // Includes
23 #include <locale.h>
24 #include <memory>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <limits.h>
28 #include <runtime_info.h>
29 #include <unique_ptr.h>
30 #include <FBaseSysLog.h>
31 #include <FSysSettingInfo.h>
32 #include <FLclNumberSymbols.h>
33 #include <FApp_AppInfo.h>
34 #include "FBase_StringConverter.h"
35 #include "FLcl_DateTimeSymbolsImpl.h"
36 #include "FLcl_CalendarImpl.h"
37 #include "FLcl_IcuCalendarImpl.h"
38 #include "FLcl_LocaleData.h"
39 #include "FLcl_LocaleImpl.h"
40
41
42 // Other defines
43 #define LOCALE_DATA_NUM_OF_MILLISEC_IN_HOUR 3600000LL   // number of mili second in a hour
44 #define LOCALE_DATA_NUM_OF_MILLISEC_IN_MINUTE 60000LL   // number of mili second in a minute
45
46 using namespace Tizen::Base;
47 using namespace Tizen::Base::Collection;
48 using namespace Tizen::Base::Utility;
49
50 namespace Tizen { namespace Locales
51 {
52
53 /////////////////////////////////////////////////////////////////////////////////////////////////////
54 // Public Method
55
56 // this function is to convert ICU FieldPosition from OSP _FieldPosition
57 IcuFieldPosition
58 _LocaleData::GetIcuFieldPosition(_FieldPosition pos)
59 {
60         IcuFieldPosition icuPos(pos.GetField());            // Create IcuFieldPosition with field value in pos
61         icuPos.setBeginIndex(pos.GetBeginIndex());          // Set Beginning index
62         icuPos.setEndIndex(pos.GetEndIndex());              // Set End index
63         return icuPos;
64 }
65
66 U_ICU_NAMESPACE::UnicodeString
67 _LocaleData::GetIcuString(const String& ospStr)
68 {
69         IcuUnicodeString icuStr;
70
71         if (!ospStr.IsEmpty())                                                     // if ospStr is not empty
72         {
73                 ByteBuffer* pBuff = null;
74                 pBuff = StringUtil::StringToUtf8N(ospStr);                             // Convert unicode value to UTF8
75                 if (pBuff)
76                 {
77                         icuStr = IcuUnicodeString((const char*) pBuff->GetPointer());        // Create ICU string using UTF8 array
78                         icuStr.setCharAt(0, icuStr.charAt(0));                              // This is to handle ICU copy on write design
79                         delete pBuff;                                                       // delete temporary buffer
80                 }
81         }
82
83       return icuStr;
84 }
85
86 // This function convert ICU string to OSP string
87 String
88 _LocaleData::GetOspString(const IcuUnicodeString& icuStr)
89 {
90         int len = icuStr.length();                                  // get length
91         if (len > 0)                                                    // if icuStr is not empty
92         {
93                 wchar_t wstr[len + 1];
94                 IcuUnicodeString tmpIcuStr(icuStr);
95                 for (int i = 0; i < len ; i++)
96                 {
97                         UChar icuChar;
98                         icuChar = tmpIcuStr.charAt(i);
99                         wstr[i] = (wchar_t)icuChar;
100                 }
101                 wstr[len] = 0;
102                 return String(wstr);
103         }
104         return String("");
105 }
106
107 // This convert OSP string to ICU strings
108 void
109 _LocaleData::GetIcuString(const String& ospStr, IcuUnicodeString& icuStr)
110 {
111         if (!ospStr.IsEmpty())                                                     // if ospStr is not empty
112         {
113                 ByteBuffer* pBuff = null;
114                 pBuff = StringUtil::StringToUtf8N(ospStr);                             // Convert unicode value to UTF8
115                 if (pBuff)
116                 {
117                         icuStr = IcuUnicodeString((const char*) pBuff->GetPointer());        // Create ICU string using UTF8 array
118                         icuStr.setCharAt(0, icuStr.charAt(0));                              // This is to handle ICU copy on write design
119                         delete pBuff;                                                       // delete temporary buffer
120                 }
121         }
122
123 //      return icuStr;
124 }
125
126 // This function return OSP array list of OSP string from ICU string list
127 ArrayList*
128 _LocaleData::ConvertIcuStringArrayToOspArrayN(const IcuUnicodeString* pIcuStrList, int count)
129 {
130         SysTryReturn(NID_LCL, pIcuStrList && count > 0, null, E_INVALID_ARG, "It is invalid argument.");
131         
132         result r = E_SUCCESS;
133         std::unique_ptr< ArrayList> pTempArrayList(new (std::nothrow) ArrayList(SingleObjectDeleter));
134         SysTryReturn(NID_LCL, pTempArrayList, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
135         pTempArrayList->Construct(count);
136         
137         for (int i = 0; i < count; i++)
138         {
139                 std::unique_ptr< String > pString(new (std::nothrow) String(_LocaleData::GetOspString(pIcuStrList[i])));
140                 SysTryReturn(NID_LCL, pString, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
141
142                 if (!pString->IsEmpty())
143                 {
144                         r = pTempArrayList->Add(pString.get());                    // Add OSP string to arraylist if it is not empty
145                         SysTryReturn(NID_LCL, !IsFailed(r), null, E_SYSTEM, "It is failed to add string [%ls]", pString->GetPointer());
146                         pString.release();
147                 }
148         }
149
150         SetLastResult(r);                                                           // Setting last result value
151         return pTempArrayList.release();                                                      // Return array list
152 }
153
154 // this function convert OSP string array list to ICU string array list
155 IcuUnicodeString*
156 _LocaleData::ConvertOspArrayToIcuStringArrayN(const Tizen::Base::Collection::IList* pIcuStrList, int& count)
157 {
158         count = 0;                                                                          // Setting count [Out param] to 0
159         SysTryReturn(NID_LCL, pIcuStrList, null, E_INVALID_ARG, "[%s] Invalid argument is used. pIcuStrList is null.", GetErrorMessage(E_INVALID_ARG));
160
161         count = pIcuStrList->GetCount();
162         if (count > 0)                                                              // if pIcuStrList is not empty
163         {
164                 IcuUnicodeString* pIcuStrArray = new IcuUnicodeString[count];
165                 if (pIcuStrArray)                                                       // if allocation is successful
166                 {
167                         IEnumerator* pEnum = pIcuStrList->GetEnumeratorN();
168                         if (pEnum)                                                           // if pEnum is non null
169                         {
170                                 int i = 0;
171                                 String* pObj = null;
172                                 while (pEnum->MoveNext() == E_SUCCESS)                        // if enum has more value
173                                 {
174                                         pObj = static_cast< String* >(pEnum->GetCurrent());    // Get object and cast it to String
175                                         if (pObj)                                             // if String is non null
176                                         {
177                                                 GetIcuString(*pObj, pIcuStrArray[i]); // Convert it to ICU string and set to array
178                                                 i++;
179                                         }
180                                 }
181
182                                 delete pEnum;                                                   // Delete enumerator
183                                 return pIcuStrArray;                                            // return ICU Array
184                         }
185                         delete[] pIcuStrArray;
186                 }
187         }
188
189         return null;                                                                // return null in case of failure
190 }
191
192
193 IcuLocale
194 _LocaleData::GetIcuLocale(const Locale& ospLocale)
195 {
196         ClearLastResult();
197         String language = ospLocale.GetLanguageCodeString();
198         String country = ospLocale.GetCountryCodeString();
199         String variant = ospLocale.GetVariantCodeString();
200
201         const char* pLangStr = _StringConverter::CopyToCharArrayN(language);
202         const char* pCountryStr = _StringConverter::CopyToCharArrayN(country);
203         const char* pVariantStr = null;
204
205         if (!variant.IsEmpty())
206         {
207                 pVariantStr = _StringConverter::CopyToCharArrayN(variant);
208         }
209
210         IcuLocale icuLocale = IcuLocale(pLangStr, pCountryStr, pVariantStr);
211
212         delete[] pLangStr;
213         delete[] pCountryStr;
214         delete[] pVariantStr;
215
216         if (icuLocale.isBogus())
217         {
218                 SetLastResult(E_SYSTEM);
219         }
220
221         return icuLocale;
222 }
223
224
225 const IcuLocale&
226 _LocaleData::GetIcuLocale(void)
227 {
228         return __icuLocale;
229 }
230
231 bool
232 _LocaleData::IsLocaleSupported(void)
233 {
234         return !__icuLocale.isBogus();
235 }
236
237 result
238 _LocaleData::SetLocale(const Locale& ospLocale)
239 {
240         if (_LocaleImpl::IsSupported(ospLocale))
241     {
242         __icuLocale = GetIcuLocale(ospLocale);
243         return E_SUCCESS;
244     }
245
246         __icuLocale.setToBogus();
247         return (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat()) ? E_UNSUPPORTED_OPERATION : E_INVALID_ARG;
248 }
249
250 result
251 _LocaleData::GetNumberSymbols(const Locale& locale, String symbols[])
252 {
253         UErrorCode status = U_ZERO_ERROR;
254         ;
255         SetLocale(locale);
256
257         SysTryReturnResult(NID_LCL, IsLocaleSupported(), E_SYSTEM, "A System error has been occurred. Locale is not supported");
258
259         IcuDecimalFormatSymbols sym(__icuLocale, status);
260         SysTryReturnResult(NID_LCL, U_SUCCESS(status),  E_SYSTEM, "A System error has been occurred. Unable to get ICU Decimal Format Symbols");
261
262         symbols[NUMBER_SYMBOL_DECIMAL_SEPARATOR] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kDecimalSeparatorSymbol));
263         symbols[NUMBER_SYMBOL_GROUPING_SEPARATOR] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kGroupingSeparatorSymbol));
264         symbols[NUMBER_SYMBOL_PATTERN_SEPARATOR] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kPatternSeparatorSymbol));
265         symbols[NUMBER_SYMBOL_PERCENT] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kPercentSymbol));
266         symbols[NUMBER_SYMBOL_ZERO_DIGIT] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kZeroDigitSymbol));
267         symbols[NUMBER_SYMBOL_DIGIT] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kDigitSymbol));
268         symbols[NUMBER_SYMBOL_CURRENCY] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kCurrencySymbol));
269         symbols[NUMBER_SYMBOL_INTL_CURRENCY] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kIntlCurrencySymbol));
270         symbols[NUMBER_SYMBOL_MONETARY_SEPARATOR] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kMonetarySeparatorSymbol));
271         symbols[NUMBER_SYMBOL_PER_MILL] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kPerMillSymbol));
272         symbols[NUMBER_SYMBOL_EXPONENTIAL] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kExponentialSymbol));
273         symbols[NUMBER_SYMBOL_PLUS_SIGN] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kPlusSignSymbol));
274         symbols[NUMBER_SYMBOL_MINUS_SIGN] = _LocaleData::GetOspString(sym.getSymbol(IcuDecimalFormatSymbols::kMinusSignSymbol));
275
276         return E_SUCCESS;
277 }
278
279 result
280 _LocaleData::SetNumberFormatter(const Locale& locale, NumberFormatterStyle style)
281 {
282         if (__pIcuNumberFormatter)
283         {
284                 delete __pIcuNumberFormatter;
285                 __pIcuNumberFormatter = null;
286         }
287
288         IcuNumberFormat* pNumFmt = null;
289         UErrorCode ec = U_ZERO_ERROR;
290         result r = SetLocale(locale);
291
292         if (!IsFailed(r))
293         {
294                 switch (style)
295                 {
296                 case NUM_FORMATTER_STYLE_NUMBER:
297                 {
298                         pNumFmt = IcuNumberFormat::createInstance(__icuLocale, ec);
299                         break;
300                 }
301
302                 case NUM_FORMATTER_STYLE_CURRENCY:
303                 {
304                         pNumFmt = IcuNumberFormat::createCurrencyInstance(__icuLocale, ec);
305                         break;
306                 }
307
308                 case NUM_FORMATTER_STYLE_PERCENT:
309                 {
310                         pNumFmt = IcuNumberFormat::createPercentInstance(__icuLocale, ec);
311                         break;
312                 }
313
314                 default:
315                 {
316                         r = E_UNSUPPORTED_OPERATION;
317                         break;
318                 }
319                 }
320
321                 if (IsFailed(r))
322                 {
323                         return r;
324                 }
325
326                 if (U_SUCCESS(ec))
327                 {
328                         if (pNumFmt && (pNumFmt->getDynamicClassID() == IcuDecimalFormat::getStaticClassID()))
329                         {
330                                 __pIcuNumberFormatter = dynamic_cast< IcuDecimalFormat* >(pNumFmt);
331                                 if (__pIcuNumberFormatter)
332                                 {
333                                         return E_SUCCESS;
334                                 }
335                         }
336                 }
337         }
338
339         return E_UNSUPPORTED_OPERATION;
340 }
341
342 result
343 _LocaleData::FormatNumber(long number, _FieldPosition& pos, Tizen::Base::String& str)
344 {
345         str = "";
346
347         if (__pIcuNumberFormatter)
348         {
349                 IcuUnicodeString icuStr;
350                 IcuFieldPosition icuPos = GetIcuFieldPosition(pos);
351                 icuStr = __pIcuNumberFormatter->format(static_cast< int32_t >(number), icuStr, icuPos);
352
353                 str = _LocaleData::GetOspString(icuStr);
354                 return E_SUCCESS;
355         }
356
357         return E_SYSTEM;
358 }
359
360 result
361 _LocaleData::FormatNumber(double number, _FieldPosition& pos, Tizen::Base::String& str)
362 {
363         str = "";
364
365         if (__pIcuNumberFormatter)
366         {
367                 IcuUnicodeString icuStr;
368                 IcuFieldPosition icuPos = GetIcuFieldPosition(pos);
369                 icuStr = __pIcuNumberFormatter->format(number, icuStr, icuPos);
370
371                 str = _LocaleData::GetOspString(icuStr);
372                 return E_SUCCESS;
373         }
374
375         return E_SYSTEM;
376 }
377
378 result
379 _LocaleData::ApplyNumberPattern(const Tizen::Base::String& pattern, bool localized)
380 {
381         if (__pIcuNumberFormatter)
382         {
383                 IcuUnicodeString icuPattern;
384                 icuPattern = __pIcuNumberFormatter->toPattern(icuPattern);
385
386                 UErrorCode ec = U_ZERO_ERROR;
387                 IcuUParseError parseError = {0,};
388                 IcuUnicodeString icuNewPatter;
389                 GetIcuString(pattern, icuNewPatter);
390
391                 if (localized)
392                 {
393                         __pIcuNumberFormatter->applyLocalizedPattern(icuNewPatter, parseError, ec);
394                 }
395                 else
396                 {
397                         __pIcuNumberFormatter->applyPattern(icuNewPatter, parseError, ec);
398                 }
399
400                 if (U_SUCCESS(ec))
401                 {
402                         return E_SUCCESS;
403                 }
404                 else
405                 {
406                         SysLog(NID_LCL, "Error [%d -> %s] in setting pattern to %ls at %d:%d",
407                                    ec, u_errorName(ec), pattern.GetPointer(), parseError.line, parseError.offset);
408
409                         __pIcuNumberFormatter->applyPattern(icuPattern, ec);
410                 }
411         }
412
413         return E_INVALID_ARG;
414 }
415
416 String
417 _LocaleData::GetNumberFormatterStringAttributes(NumberFormatterAttributes attrName)
418 {
419         IcuUnicodeString icuRetValue;
420
421         if (__pIcuNumberFormatter)
422         {
423                 switch (attrName)
424                 {
425                 case NUM_FORMATTER_FIELD_CURRENCY:
426                 {
427                         icuRetValue = __pIcuNumberFormatter->getCurrency();
428                         break;
429                 }
430
431                 case NUM_FORMATTER_FIELD_POSITIVE_PREFIX:
432                 {
433                         icuRetValue = __pIcuNumberFormatter->getPositivePrefix(icuRetValue);
434                         break;
435                 }
436
437                 case NUM_FORMATTER_FIELD_NEGATIVE_PREFIX:
438                 {
439                         icuRetValue = __pIcuNumberFormatter->getNegativePrefix(icuRetValue);
440                         break;
441                 }
442
443                 case NUM_FORMATTER_FIELD_POSITIVE_SUFFIX:
444                 {
445                         icuRetValue = __pIcuNumberFormatter->getPositiveSuffix(icuRetValue);
446                         break;
447                 }
448
449                 case NUM_FORMATTER_FIELD_NEGATIVE_SUFFIX:
450                 {
451                         icuRetValue = __pIcuNumberFormatter->getNegativeSuffix(icuRetValue);
452                         break;
453                 }
454
455                 case NUM_FORMATTER_FIELD_PATTERN:
456                 {
457                         icuRetValue = __pIcuNumberFormatter->toPattern(icuRetValue);
458                         break;
459                 }
460
461                 case NUM_FORMATTER_FIELD_LOCALIZED_PATTERN:
462                 {
463                         icuRetValue = __pIcuNumberFormatter->toLocalizedPattern(icuRetValue);
464                         break;
465                 }
466
467                 default:
468                 {
469                         break;
470                 }
471                 }
472
473                 return _LocaleData::GetOspString(icuRetValue);
474         }
475
476         return Tizen::Base::String("");
477 }
478
479 void
480 _LocaleData::SetNumberFormatterAttributes(const String& newValue, NumberFormatterAttributes attrName)
481 {
482         if (__pIcuNumberFormatter)
483         {
484                 IcuUnicodeString icuNewValue;
485                 GetIcuString(newValue, icuNewValue);
486
487                 switch (attrName)
488                 {
489                 case NUM_FORMATTER_FIELD_CURRENCY:
490                 {
491                         __pIcuNumberFormatter->setCurrency(icuNewValue.getTerminatedBuffer());
492                         break;
493                 }
494
495                 case NUM_FORMATTER_FIELD_POSITIVE_PREFIX:
496                 {
497                         __pIcuNumberFormatter->setPositivePrefix(icuNewValue);
498                         break;
499                 }
500
501                 case NUM_FORMATTER_FIELD_NEGATIVE_PREFIX:
502                 {
503                         __pIcuNumberFormatter->setNegativePrefix(icuNewValue);
504                         break;
505                 }
506
507                 case NUM_FORMATTER_FIELD_POSITIVE_SUFFIX:
508                 {
509                         __pIcuNumberFormatter->setPositiveSuffix(icuNewValue);
510                         break;
511                 }
512
513                 case NUM_FORMATTER_FIELD_NEGATIVE_SUFFIX:
514                 {
515                         __pIcuNumberFormatter->setNegativeSuffix(icuNewValue);
516                         break;
517                 }
518
519                 default:
520                 {
521                         break;
522                 }
523                 }
524         }
525 }
526
527 int
528 _LocaleData::GetNumberFormatterIntAttributes(NumberFormatterAttributes attrName)
529 {
530         int res = 0;
531         if (__pIcuNumberFormatter)
532         {
533                 switch (attrName)
534                 {
535                 case NUM_FORMATTER_FIELD_MAX_INTEGER_DIGITS:
536                 {
537                         res = __pIcuNumberFormatter->getMaximumIntegerDigits();
538                         break;
539                 }
540
541                 case NUM_FORMATTER_FIELD_MIN_INTEGER_DIGITS:
542                 {
543                         res = __pIcuNumberFormatter->getMinimumIntegerDigits();
544                         break;
545                 }
546
547                 case NUM_FORMATTER_FIELD_MAX_FRACTION_DIGITS:
548                 {
549                         res = __pIcuNumberFormatter->getMaximumFractionDigits();
550                         break;
551                 }
552
553                 case NUM_FORMATTER_FIELD_MIN_FRACTION_DIGITS:
554                 {
555                         res = __pIcuNumberFormatter->getMinimumFractionDigits();
556                         break;
557                 }
558
559                 case NUM_FORMATTER_FIELD_MIN_EXPONENT_DIGITS:
560                 {
561                         res = __pIcuNumberFormatter->getMinimumExponentDigits();
562                         break;
563                 }
564
565                 case NUM_FORMATTER_FIELD_MULTIPLIER:
566                 {
567                         res = __pIcuNumberFormatter->getMultiplier();
568                         break;
569                 }
570
571                 case NUM_FORMATTER_FIELD_GROUPING_SIZE:
572                 {
573                         res = __pIcuNumberFormatter->getGroupingSize();
574                         break;
575                 }
576
577                 default:
578                 {
579                         res = 0;
580                         break;
581                 }
582                 }
583         }
584
585         return res;
586 }
587
588 void
589 _LocaleData::SetNumberFormatterAttributes(const int newValue, NumberFormatterAttributes attrName)
590 {
591         if (__pIcuNumberFormatter)
592         {
593                 switch (attrName)
594                 {
595                 case NUM_FORMATTER_FIELD_MAX_INTEGER_DIGITS:
596                 {
597                         __pIcuNumberFormatter->setMaximumIntegerDigits(newValue);
598                         break;
599                 }
600
601                 case NUM_FORMATTER_FIELD_MIN_INTEGER_DIGITS:
602                 {
603                         __pIcuNumberFormatter->setMinimumIntegerDigits(newValue);
604                         break;
605                 }
606
607                 case NUM_FORMATTER_FIELD_MAX_FRACTION_DIGITS:
608                 {
609                         __pIcuNumberFormatter->setMaximumFractionDigits(newValue);
610                         break;
611                 }
612
613                 case NUM_FORMATTER_FIELD_MIN_FRACTION_DIGITS:
614                 {
615                         __pIcuNumberFormatter->setMinimumFractionDigits(newValue);
616                         break;
617                 }
618
619                 case NUM_FORMATTER_FIELD_MIN_EXPONENT_DIGITS:
620                 {
621                         __pIcuNumberFormatter->setMinimumExponentDigits(newValue);
622                         break;
623                 }
624
625                 case NUM_FORMATTER_FIELD_MULTIPLIER:
626                 {
627                         __pIcuNumberFormatter->setMultiplier(newValue);
628                         break;
629                 }
630
631                 case NUM_FORMATTER_FIELD_GROUPING_SIZE:
632                 {
633                         __pIcuNumberFormatter->setGroupingSize(newValue);
634                         break;
635                 }
636
637                 default:
638                 {
639                         break;
640                 }
641                 }
642         }
643 }
644
645 bool
646 _LocaleData::GetNumberFormatterBoolAttributes(NumberFormatterAttributes attrName)
647 {
648         bool res = false;
649         if (__pIcuNumberFormatter)
650         {
651                 switch (attrName)
652                 {
653                 case NUM_FORMATTER_FIELD_IS_GROUPING_USED:
654                 {
655                         res = __pIcuNumberFormatter->isGroupingUsed();
656                         break;
657                 }
658
659                 case NUM_FORMATTER_FIELD_IS_DECIMAL_SEPARATOR_ALWAYS_SHOWN:
660                 {
661                         res = __pIcuNumberFormatter->isDecimalSeparatorAlwaysShown();
662                         break;
663                 }
664
665                 case NUM_FORMATTER_FIELD_IS_POSITIVE_SIGN_ALWAYS_SHOWN:
666                 {
667                         IcuUnicodeString ps("+");
668                         IcuUnicodeString pp;
669                         pp = __pIcuNumberFormatter->getPositivePrefix(pp);
670
671                         res = (pp == ps);
672                         break;
673                 }
674
675                 default:
676                 {
677                         res = false;
678                         break;
679                 }
680                 }
681         }
682
683         return res;
684 }
685
686 void
687 _LocaleData::SetNumberFormatterAttributes(const bool newValue, NumberFormatterAttributes attrName)
688 {
689         if (__pIcuNumberFormatter)
690         {
691                 switch (attrName)
692                 {
693                 case NUM_FORMATTER_FIELD_IS_GROUPING_USED:
694                 {
695                         __pIcuNumberFormatter->setGroupingUsed(newValue);
696                         break;
697                 }
698
699                 case NUM_FORMATTER_FIELD_IS_DECIMAL_SEPARATOR_ALWAYS_SHOWN:
700                 {
701                         __pIcuNumberFormatter->setDecimalSeparatorAlwaysShown(newValue);
702                         break;
703                 }
704
705                 case NUM_FORMATTER_FIELD_IS_POSITIVE_SIGN_ALWAYS_SHOWN:
706                 {
707                         IcuUnicodeString ps("+");
708                         IcuUnicodeString pp;
709                         pp = __pIcuNumberFormatter->getPositivePrefix(pp);
710
711                         if (newValue)
712                         {
713                                 __pIcuNumberFormatter->setPositivePrefix(ps);
714                         }
715                         else
716                         {
717                                 if (pp == ps)
718                                 {
719                                         __pIcuNumberFormatter->setPositivePrefix("");
720                                 }
721                         }
722                         break;
723                 }
724
725                 default:
726                 {
727                         break;
728                 }
729                 }
730         }
731 }
732
733 result
734 _LocaleData::SetDateFormatSymbols(const Locale& locale)
735 {
736         if (__pIcuDateFormatSymbols)
737         {
738                 delete __pIcuDateFormatSymbols;
739                 __pIcuDateFormatSymbols = null;
740         }
741
742         UErrorCode ec = U_ZERO_ERROR;
743         result r = SetLocale(locale);
744
745         if (!IsFailed(r))
746         {
747                 __pIcuDateFormatSymbols = new IcuDateFormatSymbols(__icuLocale, ec);
748
749                 if (__pIcuDateFormatSymbols && U_SUCCESS(ec))
750                 {
751                         return E_SUCCESS;
752                 }
753         }
754
755         delete __pIcuDateFormatSymbols;
756         __pIcuDateFormatSymbols = null;
757
758         return r;
759 }
760
761 IList*
762 _LocaleData::GetDateFormatSymbolAttrArrayN(DateFormatSymbolsAttributes attrName)
763 {
764         if (__pIcuDateFormatSymbols)
765         {
766                 ClearLastResult();
767                 int count = 0;
768                 const IcuUnicodeString* pIcuList = null;
769
770                 switch (attrName)
771                 {
772                 case DATE_FORMAT_SYM_ERA_LIST:
773                 {
774                         pIcuList = __pIcuDateFormatSymbols->getEras(count);
775                         break;
776                 }
777
778                 case DATE_FORMAT_SYM_MONTH_LIST:
779                 {
780                         pIcuList = __pIcuDateFormatSymbols->getMonths(count);
781                         break;
782                 }
783
784                 case DATE_FORMAT_SYM_SHORT_MONTH_LIST:
785                 {
786                         pIcuList = __pIcuDateFormatSymbols->getShortMonths(count);
787                         break;
788                 }
789
790                 case DATE_FORMAT_SYM_WEEKDAY_LIST:
791                 {
792                         pIcuList = __pIcuDateFormatSymbols->getWeekdays(count);
793                         break;
794                 }
795
796                 case DATE_FORMAT_SYM_SHORT_WEEKDAY_LIST:
797                 {
798                         pIcuList = __pIcuDateFormatSymbols->getShortWeekdays(count);
799                         break;
800                 }
801
802                 case DATE_FORMAT_SYM_AM_PM_LIST:
803                 {
804                         pIcuList = __pIcuDateFormatSymbols->getAmPmStrings(count);
805                         break;
806                 }
807
808                 default:
809                 {
810                         SetLastResult(E_UNSUPPORTED_OPERATION);
811                         break;
812                 }
813                 }
814
815                 if (pIcuList)
816                 {
817                         return ConvertIcuStringArrayToOspArrayN(pIcuList, count);
818                 }
819         }
820
821         SetLastResult(E_INVALID_STATE);
822         return null;
823 }
824
825
826 IcuUDate
827 _LocaleData::GetIcuDate(DateTime date)
828 {
829         DateTime icuBaseTime;
830         icuBaseTime.SetValue(1970, 1, 1);
831         DateTime ospBaseTime = DateTime::GetMinValue();
832
833         result r = icuBaseTime.Subtract(ospBaseTime.GetTime());
834         if (r != E_SUCCESS)
835         {
836                 SysLogException(NID_LCL, r, "[%s] Propagated.", GetErrorMessage(r));
837         }
838
839         TimeSpan tsIcu = icuBaseTime.GetTime();
840         TimeSpan tsOsp = date.GetTime();
841         TimeSpan diff = tsOsp - tsIcu;
842
843         IcuUDate icuDate = diff.GetTicks();
844         return icuDate;
845 }
846
847 result
848 _LocaleData::SetDateTimeFormatter(DateTimeStyle dateStyle, DateTimeStyle timeStyle, const Locale& locale)
849 {
850         IcuDateFormat* pIcuDateFormat = null;
851
852         result r = SetLocale(locale);
853         SysTryReturnResult(NID_LCL, !IsFailed(r), E_INVALID_ARG, "Locale setting failed.");
854
855         U_ICU_NAMESPACE::DateFormat::EStyle icuDateStyle = (U_ICU_NAMESPACE::DateFormat::EStyle) dateStyle;
856         U_ICU_NAMESPACE::DateFormat::EStyle icuTimeStyle = (U_ICU_NAMESPACE::DateFormat::EStyle) timeStyle;
857
858         if (dateStyle == DATE_TIME_STYLE_NONE)
859         {
860                 if (timeStyle != DATE_TIME_STYLE_NONE)
861                 {
862                         pIcuDateFormat = IcuDateFormat::createTimeInstance(icuTimeStyle, __icuLocale);
863                 }
864         }
865         else
866         {
867                 if (timeStyle == DATE_TIME_STYLE_NONE)
868                 {
869                         pIcuDateFormat = IcuDateFormat::createDateInstance(icuDateStyle, __icuLocale);
870                 }
871                 else
872                 {
873                         pIcuDateFormat = IcuDateFormat::createDateTimeInstance(icuDateStyle, icuTimeStyle, __icuLocale);
874                 }
875         }
876
877         if (pIcuDateFormat)
878         {
879                 if (__pIcuDateFormat)
880                 {
881                         delete __pIcuDateFormat;
882                         __pIcuDateFormat = null;
883                 }
884                 __pIcuDateFormat = dynamic_cast< IcuSimpleDateFormat* >(pIcuDateFormat);
885
886                 if (__pIcuDateFormat)
887                 {
888                         if (__pIcuDateFormatSymbols)
889                         {
890                                 delete __pIcuDateFormatSymbols;
891                                 __pIcuDateFormatSymbols = null;
892                         }
893
894                         const IcuDateFormatSymbols* pDateTimeFormatSym = __pIcuDateFormat->getDateFormatSymbols();
895
896                         if (pDateTimeFormatSym)
897                         {
898                                 __pIcuDateFormatSymbols = new IcuDateFormatSymbols(*pDateTimeFormatSym);
899                         }
900
901                         return E_SUCCESS;
902                 }
903         }
904
905         delete pIcuDateFormat;
906         return E_INVALID_ARG;
907 }
908
909 result
910 _LocaleData::SetStartTimeRule(IcuSimpleTimeZone& zone, const TimeRule* pOspTimeRule)
911 {
912         if (pOspTimeRule)
913         {
914                 UErrorCode status = U_ZERO_ERROR;
915                 IcuDateTimeRule::TimeRuleType icuTimeRuleType;
916
917                 DstRuleMode ospRuleMode = static_cast< DstRuleMode >(pOspTimeRule->GetRuleMode());
918                 Tizen::System::TimeMode ospTimeMode = pOspTimeRule->GetTimeMode();
919
920                 switch (ospTimeMode)
921                 {
922                 case Tizen::System::UTC_TIME:
923                 {
924                         icuTimeRuleType = IcuDateTimeRule::UTC_TIME;
925                         break;
926                 }
927
928                 case Tizen::System::STANDARD_TIME:
929                 {
930                         icuTimeRuleType = IcuDateTimeRule::STANDARD_TIME;
931                         break;
932                 }
933
934                 case Tizen::System::WALL_TIME:
935                 default:
936                 {
937                         icuTimeRuleType = IcuDateTimeRule::WALL_TIME;
938                         break;
939                 }
940                 }
941
942                 int time = ((pOspTimeRule->GetHour() * 60) + pOspTimeRule->GetMinute()) * 60 * 1000;
943
944                 switch (ospRuleMode)
945                 {
946                 case EXACT_DAY:
947                 {
948                         zone.setStartRule(
949                                 pOspTimeRule->GetMonth(),
950                                 pOspTimeRule->GetDay(),
951                                 time,
952                                 icuTimeRuleType,
953                                 status);
954                         break;
955                 }
956
957                 case DAY_OF_WEEK_IN_MONTH:
958                 {
959                         zone.setStartRule(
960                                 pOspTimeRule->GetMonth(),
961                                 pOspTimeRule->GetWeek(),
962                                 pOspTimeRule->GetDayOfWeek(),
963                                 time,
964                                 icuTimeRuleType,
965                                 status);
966                         break;
967                 }
968
969                 case AFTER_THE_SPECIFIED_DAY:
970                 {
971                         zone.setStartRule(
972                                 pOspTimeRule->GetMonth(),
973                                 pOspTimeRule->GetDay(),
974                                 pOspTimeRule->GetDayOfWeek(),
975                                 time,
976                                 icuTimeRuleType,
977                                 status);
978                         break;
979                 }
980
981                 case BEFORE_THE_SPECIFIED_DAY:
982                 {
983                         zone.setStartRule(
984                                 pOspTimeRule->GetMonth(),
985                                 pOspTimeRule->GetDay(),
986                                 -pOspTimeRule->GetDayOfWeek(),
987                                 time,
988                                 icuTimeRuleType,
989                                 status);
990                         break;
991                 }
992
993                 case BACKWARD_FROM_END_OF_MONTH:
994                 {
995                         zone.setStartRule(
996                                 pOspTimeRule->GetMonth(),
997                                 pOspTimeRule->GetWeek() * -1,
998                                 0,
999                                 time,
1000                                 icuTimeRuleType,
1001                                 status);
1002                         break;
1003                 }
1004                 }
1005                 return U_SUCCESS(status) ? E_SUCCESS : E_SYSTEM;
1006         }
1007         return E_INVALID_ARG;
1008 }
1009
1010 result
1011 _LocaleData::SetEndTimeRule(IcuSimpleTimeZone& zone, const TimeRule* pOspTimeRule)
1012 {
1013         if (pOspTimeRule)
1014         {
1015                 UErrorCode status = U_ZERO_ERROR;
1016                 IcuDateTimeRule::TimeRuleType icuTimeRuleType;
1017
1018                 DstRuleMode ospRuleMode = static_cast< DstRuleMode >(pOspTimeRule->GetRuleMode());
1019                 Tizen::System::TimeMode ospTimeMode = pOspTimeRule->GetTimeMode();
1020
1021                 switch (ospTimeMode)
1022                 {
1023                 case Tizen::System::UTC_TIME:
1024                 {
1025                         icuTimeRuleType = IcuDateTimeRule::UTC_TIME;
1026                         break;
1027                 }
1028
1029                 case Tizen::System::STANDARD_TIME:
1030                 {
1031                         icuTimeRuleType = IcuDateTimeRule::STANDARD_TIME;
1032                         break;
1033                 }
1034
1035                 case Tizen::System::WALL_TIME:
1036                 default:
1037                 {
1038                         icuTimeRuleType = IcuDateTimeRule::WALL_TIME;
1039                         break;
1040                 }
1041                 }
1042
1043                 int time = ((pOspTimeRule->GetHour() * 60) + pOspTimeRule->GetMinute()) * 60 * 1000;
1044
1045                 switch (ospRuleMode)
1046                 {
1047                 case EXACT_DAY:
1048                 {
1049                         zone.setEndRule(
1050                                 pOspTimeRule->GetMonth(),
1051                                 pOspTimeRule->GetDay(),
1052                                 time,
1053                                 icuTimeRuleType,
1054                                 status);
1055                         break;
1056                 }
1057
1058                 case DAY_OF_WEEK_IN_MONTH:
1059                 {
1060                         zone.setEndRule(
1061                                 pOspTimeRule->GetMonth(),
1062                                 pOspTimeRule->GetWeek(),
1063                                 pOspTimeRule->GetDayOfWeek(),
1064                                 time,
1065                                 icuTimeRuleType,
1066                                 status);
1067                         break;
1068                 }
1069
1070                 case AFTER_THE_SPECIFIED_DAY:
1071                 {
1072                         zone.setEndRule(
1073                                 pOspTimeRule->GetMonth(),
1074                                 pOspTimeRule->GetDay(),
1075                                 pOspTimeRule->GetDayOfWeek(),
1076                                 time,
1077                                 icuTimeRuleType,
1078                                 status);
1079                         break;
1080                 }
1081
1082                 case BEFORE_THE_SPECIFIED_DAY:
1083                 {
1084                         zone.setEndRule(
1085                                 pOspTimeRule->GetMonth(),
1086                                 pOspTimeRule->GetDay(),
1087                                 -pOspTimeRule->GetDayOfWeek(),
1088                                 time,
1089                                 icuTimeRuleType,
1090                                 status);
1091                         break;
1092                 }
1093
1094                 case BACKWARD_FROM_END_OF_MONTH:
1095                 {
1096                         zone.setEndRule(
1097                                 pOspTimeRule->GetMonth(),
1098                                 pOspTimeRule->GetWeek() * -1,
1099                                 0,
1100                                 time,
1101                                 icuTimeRuleType,
1102                                 status);
1103                         break;
1104                 }
1105                 }
1106                 return U_SUCCESS(status) ? E_SUCCESS : E_SYSTEM;
1107         }
1108         return E_INVALID_ARG;
1109 }
1110
1111 result
1112 _LocaleData::FormatDateTime(const DateTime& date, String& str)
1113 {
1114         std::auto_ptr <Calendar> pCal(Calendar::CreateInstanceN());
1115         SysTryReturnResult(NID_LCL, pCal.get(), E_OUT_OF_MEMORY, "Memory allocation failed");
1116
1117         result r = pCal->SetTime(date);
1118         SysTryReturn(NID_LCL, r == E_SUCCESS, r, r, "[%s] Unable to set date time in default calendar");
1119
1120         r = pCal->Clear(TIME_FIELD_MILLISECOND);
1121         SysTryReturn(NID_LCL, r == E_SUCCESS, r, r, "[%s] Unable to set date time in default calendar");
1122
1123         return FormatDateTime(*pCal, str);
1124 }
1125
1126 result
1127 _LocaleData::FormatDateTime(const Calendar& calendar, Tizen::Base::String& str)
1128 {
1129         SysTryReturnResult(NID_LCL, __pIcuDateFormat, E_INVALID_STATE, "This instance is not constructed");
1130         ClearLastResult();
1131
1132         const _IcuCalendarImpl* _pIcuCalendarImpl = _CalendarImpl::GetImpl(calendar);
1133         if (_pIcuCalendarImpl)
1134         {
1135                 IcuCalendar* pIcuCal = _pIcuCalendarImpl->GetIcuCalendarCloneN();
1136                 if (pIcuCal)
1137                 {
1138                         IcuFieldPosition icuFp;
1139                         IcuUnicodeString icuStr;
1140
1141                         GetIcuString(str,icuStr);
1142                         icuStr = __pIcuDateFormat->format(*pIcuCal, icuStr, icuFp);
1143                         str = _LocaleData::GetOspString(icuStr);
1144
1145                         delete pIcuCal;
1146                         return GetLastResult();
1147                 }
1148         }
1149
1150         return E_SYSTEM;
1151 }
1152
1153 String
1154 _LocaleData::GetDateTimePattern()
1155 {
1156         SysTryReturn(NID_LCL, __pIcuDateFormat, String(""), E_INVALID_STATE, "This instance is not constructed");
1157         IcuUnicodeString icuPattern;
1158
1159         icuPattern = __pIcuDateFormat->toPattern(icuPattern);
1160         return _LocaleData::GetOspString(icuPattern);
1161 }
1162
1163 result
1164 _LocaleData::SetDateTimePattern(const String& pattern)
1165 {
1166         SysTryReturnResult(NID_LCL, __pIcuDateFormat, E_INVALID_STATE, "This instance is not constructed");
1167         IcuUnicodeString icuStr;
1168
1169         GetIcuString(pattern, icuStr);
1170
1171         __pIcuDateFormat->applyPattern(icuStr);
1172
1173         return E_SUCCESS;
1174 }
1175 DateTimeSymbols*
1176 _LocaleData::GetDateTimeSymbolsN(DateTimeSymbols* pDateTimeSymbols)
1177 {
1178         SysTryReturn(NID_LCL, __pIcuDateFormatSymbols, null, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not constructed");
1179         SysTryReturn(NID_LCL, pDateTimeSymbols, null, E_INVALID_ARG, "[%s] Invalid argument is used. pDateTimeSymbols is null.", GetErrorMessage(E_INVALID_ARG));
1180
1181         _DateTimeSymbolsImpl* pDateTimeSymbolsImpl = _DateTimeSymbolsImpl::GetDateTimeSymbolsImpl(pDateTimeSymbols);
1182
1183         if (pDateTimeSymbolsImpl)
1184         {
1185                 pDateTimeSymbolsImpl->ReleaseAll();
1186
1187                 pDateTimeSymbolsImpl->__pErasList = GetDateFormatSymbolAttrArrayN(DATE_FORMAT_SYM_ERA_LIST);
1188                 pDateTimeSymbolsImpl->__pMonthsList = GetDateFormatSymbolAttrArrayN(DATE_FORMAT_SYM_MONTH_LIST);
1189                 pDateTimeSymbolsImpl->__pShortMonthsList = GetDateFormatSymbolAttrArrayN(DATE_FORMAT_SYM_SHORT_MONTH_LIST);
1190                 pDateTimeSymbolsImpl->__pWeekdaysList = GetDateFormatSymbolAttrArrayN(DATE_FORMAT_SYM_WEEKDAY_LIST);
1191                 pDateTimeSymbolsImpl->__pShortWeekdaysList = GetDateFormatSymbolAttrArrayN(DATE_FORMAT_SYM_SHORT_WEEKDAY_LIST);
1192                 pDateTimeSymbolsImpl->__pAmPmList = GetDateFormatSymbolAttrArrayN(DATE_FORMAT_SYM_AM_PM_LIST);
1193
1194                 return pDateTimeSymbols;
1195         }
1196
1197         return null;
1198 }
1199
1200 // This function convert and set ICU DateTime symbols from OSP DateTimeSymbols
1201 result
1202 _LocaleData::SetDateTimeSymbols(const DateTimeSymbols& newValue)
1203 {
1204         UErrorCode ec = U_ZERO_ERROR;
1205
1206         if (!__pIcuDateFormatSymbols)
1207         {
1208                 __pIcuDateFormatSymbols = new IcuDateFormatSymbols(ec);
1209         }
1210
1211         IcuUnicodeString* pIcuArray = null;
1212         int count = 0;
1213
1214         if (U_SUCCESS(ec) && __pIcuDateFormatSymbols != null)
1215         {
1216                 pIcuArray = ConvertOspArrayToIcuStringArrayN(newValue.GetEras(), count);
1217                 __pIcuDateFormatSymbols->setEras(pIcuArray, count);
1218                 delete[] pIcuArray;
1219
1220                 pIcuArray = ConvertOspArrayToIcuStringArrayN(newValue.GetMonths(), count);
1221                 __pIcuDateFormatSymbols->setMonths(pIcuArray, count);
1222                 delete[] pIcuArray;
1223
1224                 pIcuArray = ConvertOspArrayToIcuStringArrayN(newValue.GetShortMonths(), count);
1225                 __pIcuDateFormatSymbols->setShortMonths(pIcuArray, count);
1226                 delete[] pIcuArray;
1227
1228                 pIcuArray = ConvertOspArrayToIcuStringArrayN(newValue.GetWeekdays(), count);
1229                 __pIcuDateFormatSymbols->setWeekdays(pIcuArray, count);
1230                 delete[] pIcuArray;
1231
1232                 pIcuArray = ConvertOspArrayToIcuStringArrayN(newValue.GetShortWeekdays(), count);
1233                 __pIcuDateFormatSymbols->setShortWeekdays(pIcuArray, count);
1234                 delete[] pIcuArray;
1235
1236                 pIcuArray = ConvertOspArrayToIcuStringArrayN(newValue.GetAmPm(), count);
1237                 __pIcuDateFormatSymbols->setAmPmStrings(pIcuArray, count);
1238                 delete[] pIcuArray;
1239
1240 // From ICU Docs: SimpleDateFormat no longer use the zone strings stored in a DateFormatSymbols. Therefore, the time zone strings
1241 // set by this method have no effects in an instance of SimpleDateFormat for formatting time zones.
1242 //        __pIcuDateFormatSymbols->setZoneStrings();
1243
1244                 __pIcuDateFormat->setDateFormatSymbols(*__pIcuDateFormatSymbols);
1245                 return E_SUCCESS;
1246         }
1247
1248         return E_UNSUPPORTED_OPERATION;
1249 }
1250
1251 void
1252 _LocaleData::SetGregorianWeekCountData(const Locale& ospLocale, DayOfWeek& firstDayOfWeek, short& minDaysInFirstWeek)
1253 {
1254         UErrorCode success = U_ZERO_ERROR;
1255         IcuLocale icuLocale;
1256
1257         icuLocale = GetIcuLocale(ospLocale);
1258         result r = GetLastResult();
1259         SysAssert(r == E_SUCCESS);
1260
1261         GregorianCalendar gc(icuLocale, success);
1262         SysAssert(U_SUCCESS(success));
1263
1264         firstDayOfWeek = (DayOfWeek) gc.getFirstDayOfWeek();                  // Set __firstDayOfWeek from ICU data
1265         minDaysInFirstWeek = 1;                          // To align with 2.0 version
1266 //    minDaysInFirstWeek = (short) gc.getMinimalDaysInFirstWeek();       // Set __minDaysInFirstWeek from ICU data
1267 }
1268
1269 _LocaleData::_LocaleData(void)
1270         : __icuLocale()
1271         ,                                                                           // default ICU locale
1272         __pIcuNumberFormatter(null)
1273         , __pIcuDateFormatSymbols(null)
1274         , __pIcuDateFormat(null)
1275 {
1276 }
1277
1278
1279 _LocaleData::~_LocaleData(void)
1280 {
1281         if (__pIcuNumberFormatter)                                                     // Delete __pIcuNumberFormatter and set to null
1282         {
1283                 delete __pIcuNumberFormatter;
1284                 __pIcuNumberFormatter = null;
1285         }
1286
1287         if (__pIcuDateFormatSymbols)                                                   // Delete __pIcuDateFormatSymbols and set to null
1288         {
1289                 delete __pIcuDateFormatSymbols;
1290                 __pIcuDateFormatSymbols = null;
1291         }
1292
1293         if (__pIcuDateFormat)                                                          // Delete __pIcuDateFormat and set to null
1294         {
1295                 delete __pIcuDateFormat;
1296                 __pIcuDateFormat = null;
1297         }
1298 }
1299
1300
1301 };
1302 };      // Tizen::Locales
1303