Resolve the "Klocwork" detected defect and add debug feature.
[platform/framework/native/appfw.git] / src / locales / FLcl_DateTimeFormatterImpl.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        FLclDateTimeFormatter.cpp
19  * @brief       This is the implementation file for DateTimeFormatter class.
20  */
21
22 // Includes
23 #include <unique_ptr.h>
24 #include <unicode/dtfmtsym.h>
25 #include <unicode/smpdtfmt.h>
26 #include <unicode/calendar.h>
27
28 #include <FBaseSysLog.h>
29 #include <FApp_AppInfo.h>
30 #include <FLclDateTimeFormatter.h>
31 #include "FLcl_DateTimeFormatterImpl.h"
32 #include "FLcl_LocaleData.h"
33 #include "FLcl_LocaleManagerImpl.h"
34 #include "FLcl_CalendarImpl.h"
35 #include "FLcl_IcuCalendarImpl.h"
36 #include "FLcl_DateTimeSymbolsImpl.h"
37
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Collection;
40 using namespace Tizen::Base::Utility;
41
42 namespace Tizen { namespace Locales
43 {
44
45 _DateTimeFormatterImpl::_DateTimeFormatterImpl(void)
46         : __pSymbols(null)
47         , __pIcuDateFormatter(null)
48         , __pLocale(null)
49 {
50 }
51
52 _DateTimeFormatterImpl::~_DateTimeFormatterImpl(void)
53 {
54         delete __pSymbols;
55         delete __pIcuDateFormatter;
56         delete __pLocale;
57 }
58
59 // The DateTimeFormatter always use System Locale if not provided by the user.
60 // System locale may be different for default ICU locale.
61 DateTimeFormatter*
62 _DateTimeFormatterImpl::CreateInstanceN(DateTimeStyle dateStyle, DateTimeStyle timeStyle)
63 {
64         result r = E_INVALID_ARG;
65
66         if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
67         {
68                 r = E_UNSUPPORTED_OPERATION;
69         }
70
71         SysTryReturn(NID_LCL, ValidateDateTimeStyle(dateStyle), null, r, "[%s] Invalid argument is used. dateStyle is invalid", GetErrorMessage(r));
72         SysTryReturn(NID_LCL, ValidateDateTimeStyle(timeStyle), null, r, "[%s] Invalid argument is used. timeStyle is invalid", GetErrorMessage(r));
73
74         // using system locale, may be different from ICU default locale
75         DateTimeFormatter* pDateTimeFormatter = CreateInstanceN(_LocaleManagerImpl::GetSystemLocale(), dateStyle, timeStyle);
76
77         if (GetLastResult() == E_INVALID_ARG)
78         {
79                 SetLastResult(E_UNSUPPORTED_OPERATION);
80         }
81         return pDateTimeFormatter;
82 }
83
84 DateTimeFormatter*
85 _DateTimeFormatterImpl::CreateInstanceN(const Locale& locale, DateTimeStyle dateStyle, DateTimeStyle timeStyle)
86 {
87         result r = (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat()) ? E_UNSUPPORTED_OPERATION : E_INVALID_ARG;
88
89         SysTryReturn(NID_LCL, locale.GetLanguageCode() != LANGUAGE_INVALID && locale.GetCountryCode() != COUNTRY_INVALID, null, r, "It is the invalid locale.");
90         SysTryReturn(NID_LCL, ValidateDateTimeStyle(dateStyle), null, r, "[%s] Invalid argument is used. dateStyle is invalid", GetErrorMessage(r));
91         SysTryReturn(NID_LCL, ValidateDateTimeStyle(timeStyle), null, r, "[%s] Invalid argument is used. timeStyle is invalid", GetErrorMessage(r));
92
93         ClearLastResult();
94
95         std::unique_ptr<DateTimeFormatter> pDateTimeFormatter(new (std::nothrow) DateTimeFormatter());
96         SysTryReturn(NID_LCL, pDateTimeFormatter, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
97
98         std::unique_ptr<_DateTimeFormatterImpl> pDateTimeFormatterImpl(new (std::nothrow) _DateTimeFormatterImpl);
99         SysTryReturn(NID_LCL,pDateTimeFormatterImpl, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
100
101         std::unique_ptr< U_ICU_NAMESPACE::SimpleDateFormat> pIcuDateFormatter(pDateTimeFormatterImpl->GetIcuDateFormatterN(locale, dateStyle, timeStyle));
102         SysTryReturn(NID_LCL, pIcuDateFormatter, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
103
104         pDateTimeFormatterImpl->__pLocale = new (std::nothrow) Locale(locale);
105         SysTryReturn(NID_LCL, pDateTimeFormatterImpl->__pLocale, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
106         pDateTimeFormatterImpl->__pIcuDateFormatter = pIcuDateFormatter.release();
107         pDateTimeFormatter->__pDateTimeFormatterImpl = pDateTimeFormatterImpl.release();
108         return pDateTimeFormatter.release();      // Here as LastResult is already cleared, no need to set it to E_SUCCESS
109 }
110
111 U_ICU_NAMESPACE::SimpleDateFormat*
112 _DateTimeFormatterImpl::GetIcuDateFormatterN(const Locale& locale, DateTimeStyle dateStyle, DateTimeStyle timeStyle)
113 {
114         SysTryReturn(NID_LCL, dateStyle != DATE_TIME_STYLE_NONE || timeStyle != DATE_TIME_STYLE_NONE, null, E_INVALID_ARG, "It is an invalid argument.");
115
116         U_ICU_NAMESPACE::DateFormat* pIcuDateFormat = null;
117         U_ICU_NAMESPACE::DateFormat::EStyle icuDateStyle = (U_ICU_NAMESPACE::DateFormat::EStyle) dateStyle;
118         U_ICU_NAMESPACE::DateFormat::EStyle icuTimeStyle = (U_ICU_NAMESPACE::DateFormat::EStyle) timeStyle;
119         U_ICU_NAMESPACE::Locale icuLocale = _LocaleData::GetIcuLocale(locale);
120
121         if (dateStyle != DATE_TIME_STYLE_NONE && timeStyle != DATE_TIME_STYLE_NONE)
122         {
123                 pIcuDateFormat = U_ICU_NAMESPACE::DateFormat::createDateTimeInstance(icuDateStyle, icuTimeStyle, icuLocale);
124         }
125         else if (dateStyle != DATE_TIME_STYLE_NONE && timeStyle == DATE_TIME_STYLE_NONE)
126         {
127                 pIcuDateFormat = U_ICU_NAMESPACE::DateFormat::createDateInstance(icuDateStyle, icuLocale);
128         }
129         else if (dateStyle == DATE_TIME_STYLE_NONE && timeStyle != DATE_TIME_STYLE_NONE)
130         {
131                 pIcuDateFormat = U_ICU_NAMESPACE::DateFormat::createTimeInstance(icuTimeStyle, icuLocale);
132         }
133
134         return dynamic_cast< U_ICU_NAMESPACE::SimpleDateFormat* >(pIcuDateFormat);
135 }
136
137
138 // This function will not have TimeZone informations and always print time zone as GMT+00:00
139 result
140 _DateTimeFormatterImpl::Format(const DateTime& date, String& strBuf) const
141 {
142         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
143
144         std::unique_ptr< Calendar > pCal(Calendar::CreateInstanceN());
145         SysTryReturnResult(NID_LCL, pCal, E_OUT_OF_MEMORY, "Memory allocation failed");
146
147         result r = pCal->SetTime(date);
148         SysTryReturn(NID_LCL, r == E_SUCCESS, r, r, "[%s] Unable to set date time in default calendar", GetErrorMessage(r));
149
150         r = pCal->Clear(TIME_FIELD_MILLISECOND);
151         SysTryReturn(NID_LCL, r == E_SUCCESS, r, r, "[%s] Unable to set date time in default calendar", GetErrorMessage(r));
152
153         return Format(*(pCal.get()), strBuf);
154 }
155
156 result
157 _DateTimeFormatterImpl::Format(const Calendar& calendar, String& strBuf) const
158 {
159         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
160
161         const _IcuCalendarImpl* pIcuCalendarImpl = _CalendarImpl::GetImpl(calendar);
162         SysTryReturnResult(NID_LCL, pIcuCalendarImpl, E_SYSTEM, "It is failed to get icu calendar.");
163
164         IcuCalendar* pIcuCal = pIcuCalendarImpl->GetIcuCalendarCloneN();
165         SysTryReturnResult(NID_LCL, pIcuCal, E_SYSTEM, "It is failed to get icu calendar.");
166
167         IcuFieldPosition icuFp;
168         IcuUnicodeString icuStr = _LocaleData::GetIcuString(strBuf);
169         icuStr = __pIcuDateFormatter->format(*pIcuCal, icuStr, icuFp);
170         strBuf = _LocaleData::GetOspString(icuStr);
171         delete pIcuCal;
172
173         return E_SUCCESS;
174 }
175
176 result
177 _DateTimeFormatterImpl::ApplyPattern(const String& pattern)
178 {
179         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
180         U_ICU_NAMESPACE::UnicodeString icuStr = _LocaleData::GetIcuString(pattern);
181         __pIcuDateFormatter->applyPattern(icuStr);
182         return E_SUCCESS;
183 }
184
185 String
186 _DateTimeFormatterImpl::GetPattern(void) const
187 {
188         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
189         IcuUnicodeString icuPattern;
190         icuPattern = __pIcuDateFormatter->toPattern(icuPattern);
191         return _LocaleData::GetOspString(icuPattern);
192 }
193
194 const DateTimeSymbols*
195 _DateTimeFormatterImpl::GetDateTimeSymbols(void)
196 {
197         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
198         if (__pSymbols == null)
199         {
200                 std::unique_ptr< DateTimeSymbols > pSymbols(new (std::nothrow) DateTimeSymbols);
201                 SysTryReturn(NID_LCL, pSymbols, null, E_OUT_OF_MEMORY, "It is not enough memory.");
202                 pSymbols->Construct(*__pLocale);
203                 __pSymbols = pSymbols.release();
204         }
205         return __pSymbols;
206 }
207
208 void
209 _DateTimeFormatterImpl::SetDateTimeSymbols(const DateTimeSymbols& newSymbols)
210 {
211         SysAssertf(__pIcuDateFormatter != null, "Not yet constructed! Construct() should be called before use.");
212
213         std::unique_ptr< DateTimeSymbols > pSymbols(new (std::nothrow) DateTimeSymbols);
214         SysTryReturn(NID_LCL, pSymbols, , E_OUT_OF_MEMORY, "It is not enough memory.");
215         result r = pSymbols->Construct(newSymbols);
216         SysTryReturn(NID_LCL, r == E_SUCCESS, , r, "[%s] occured.", GetErrorMessage(r));
217
218         _DateTimeSymbolsImpl* pDateTimeSymbolsImpl = _DateTimeSymbolsImpl::GetDateTimeSymbolsImpl(pSymbols.get());
219         const U_ICU_NAMESPACE::DateFormatSymbols* pIcuSymbols = pDateTimeSymbolsImpl->GetIcuSymbols();
220
221         __pIcuDateFormatter->setDateFormatSymbols(*pIcuSymbols);
222
223         if (__pSymbols)
224         {
225                 delete __pSymbols;
226         }
227         __pSymbols = pSymbols.release();
228 }
229
230 bool
231 _DateTimeFormatterImpl::ValidateDateTimeStyle(DateTimeStyle dateTimeStyle)
232 {
233         return (dateTimeStyle < DATE_TIME_STYLE_NONE || dateTimeStyle > DATE_TIME_STYLE_SHORT) ? false : true;
234 }
235
236 };
237 };      // Tizen::Locales