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