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