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