2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FLcl_LocaleManagerImpl.cpp
19 * @brief This is the implementation file for _LocaleManagerImpl class.
21 #include <unique_ptr.h>
24 #include <runtime_info.h>
25 #include <unicode/calendar.h>
26 #include <unicode/timezone.h>
27 #include <unicode/locid.h>
28 #include <libxml/parser.h>
29 #include <libxml/tree.h>
33 #include <FBaseSysLog.h>
34 #include <FBase_StringConverter.h>
36 #include "FLcl_LocaleImpl.h"
37 #include "FLcl_TimeZoneImpl.h"
38 #include "FLcl_LocaleManagerImpl.h"
41 using namespace Tizen::Base;
42 using namespace Tizen::Base::Utility;
43 using namespace Tizen::Base::Collection;
44 using namespace Tizen::Io;
48 void operator ()(xmlDoc* p)
59 void operator ()(char* p)
68 namespace Tizen { namespace Locales
70 static const char* LANGUAGE_LIST_FILE_PATH ="/opt/usr/data/setting/langlist.xml";
71 static const char* TIMEZONE_LIST_FILE_PATH = "/opt/usr/data/clock/tzlist.ini";
72 static const char* CLOCALE_LIST_FILE_PATH = "/opt/usr/etc/clocale.list";
76 _LocaleManagerImpl::GetSystemLocale(void)
79 if (runtime_info_get_value_string(RUNTIME_INFO_KEY_REGION, &pRegionPtr) == RUNTIME_INFO_ERROR_NONE)
81 SetLastResult(E_SUCCESS);
83 Locale ospLoc = _LocaleImpl(pRegionPtr).GetOspLocale();
88 SetLastResult(E_SYSTEM);
89 return Locale(LANGUAGE_INVALID, COUNTRY_INVALID, null);
92 U_ICU_NAMESPACE::Locale
93 _LocaleManagerImpl::GetSystemIcuLocale(void)
96 if (runtime_info_get_value_string(RUNTIME_INFO_KEY_REGION, &pRegionPtr) == RUNTIME_INFO_ERROR_NONE)
98 SetLastResult(E_SUCCESS);
99 U_ICU_NAMESPACE::Locale locale(pRegionPtr);
104 return U_ICU_NAMESPACE::Locale();
109 _LocaleManagerImpl::GetAvailableEglibcLocaesN(void)
112 result r = E_SUCCESS;
113 String clocaleFilePath(CLOCALE_LIST_FILE_PATH);
115 std::unique_ptr<HashMap> pClocaleMap(new (std::nothrow) HashMap(SingleObjectDeleter));
116 SysTryReturn(NID_LCL, pClocaleMap, null, E_OUT_OF_MEMORY,
117 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
118 r = file.Construct(clocaleFilePath, "r");
119 SysTryReturn(NID_LCL, r == E_SUCCESS, null,E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] It is failed to get the clocale list from the list file.");
121 pClocaleMap->Construct();
126 r = file.Read(strBuf);
127 if ( r == E_END_OF_FILE)
131 SysTryReturn(NID_LCL, r == E_SUCCESS, null, r, "[%s] It is failed to read the clocale list.", GetErrorMessage(r));
132 std::unique_ptr< String > pClocaleId(new (std::nothrow) String());
133 SysTryReturn(NID_LCL, pClocaleId, null, E_OUT_OF_MEMORY,
134 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
135 r = strBuf.SubString(0, 5, *pClocaleId);
141 if (!pClocaleMap->ContainsKey(*(pClocaleId.get())))
143 std::unique_ptr<String> pDummyValue(new (std::nothrow) String());
144 SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,
145 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
147 r = pClocaleMap->Add(pClocaleId.get(), pDummyValue.get());
148 SysTryReturn(NID_LCL, r == E_SUCCESS, null, r,
149 "[%s] It is failed to add the clocale id into the clocale map.", GetErrorMessage(r));
150 pClocaleId.release();
151 pDummyValue.release();
154 return pClocaleMap.release();
158 _LocaleManagerImpl::GetAvailableLocalesN(void)
160 result r = E_SUCCESS;
162 const U_ICU_NAMESPACE::Locale* pIcuLocaleList = U_ICU_NAMESPACE::Locale::getAvailableLocales(count);
163 SysTryReturn(NID_LCL, count > 0, null, E_SYSTEM,
164 "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
166 std::unique_ptr<LinkedList> pAvailableLocaleList(new (std::nothrow) LinkedList(SingleObjectDeleter));
167 SysTryReturn(NID_LCL, pAvailableLocaleList, null, E_OUT_OF_MEMORY,
168 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
170 std::unique_ptr< IMap > pClocaleMap(GetAvailableEglibcLocaesN());
172 for (int i = 0; i < count; i++)
174 const U_ICU_NAMESPACE::Locale* pIcuLocale = (pIcuLocaleList + i);
175 SysTryReturn(NID_LCL, pIcuLocale, null, E_SYSTEM,
176 "[%s] The method cannot proceed due to a severe system error.",GetErrorMessage(E_SYSTEM));
177 Locale ospLocale = _LocaleImpl(*pIcuLocale).GetOspLocale();
178 if (_LocaleImpl::IsSupported(ospLocale))
180 std::unique_ptr< Locale > pLocale(new (std::nothrow) Locale(ospLocale));
181 SysTryReturn(NID_LCL, pLocale, null, E_OUT_OF_MEMORY,
182 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
184 String localeId(pIcuLocale->getLanguage());
185 localeId = localeId + L"_" + String(pIcuLocale->getCountry());
187 if (!pAvailableLocaleList->Contains(*(pLocale.get())) && pClocaleMap->ContainsKey(localeId))
189 r = pAvailableLocaleList->Add(pLocale.get());
190 SysTryReturn(NID_LCL, !IsFailed(r), null, E_SYSTEM, "It is failed to make the locale list");
196 SetLastResult(E_SUCCESS);
197 return pAvailableLocaleList.release();
201 _LocaleManagerImpl::GetSelectedLanguage(void)
205 int ret = runtime_info_get_value_string(RUNTIME_INFO_KEY_LANGUAGE, &pLanguagePtr);
206 SysTryReturn(NID_LCL, ret == RUNTIME_INFO_ERROR_NONE, String(), E_SYSTEM,
207 "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
208 String language(_LocaleImpl(pLanguagePtr).GetLanguageCodeString(false));
214 // FALLBACk should be removed after checking the SLP change.
216 _LocaleManagerImpl::GetAvailableLanguagesFallbackN(void)
218 std::unique_ptr<IList> pLocaleList (GetAvailableLocalesN());
219 std::unique_ptr<HashMap> pLanguageMap(new (std::nothrow) HashMap(SingleObjectDeleter));
220 SysTryReturn(NID_LCL, pLanguageMap, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
222 pLanguageMap->Construct();
224 std::unique_ptr<ArrayList> pAvailableLanguageList(new (std::nothrow) ArrayList(SingleObjectDeleter));
225 SysTryReturn(NID_LCL, pAvailableLanguageList, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
226 pAvailableLanguageList->Construct();
228 for (int i = 0; i < pLocaleList->GetCount() ; i++)
230 Locale* pLocale = (Locale*)pLocaleList->GetAt(i);
231 std::unique_ptr<String> pLanguageCode(new (std::nothrow) String(pLocale->GetLanguageCodeString()));
232 SysTryReturn(NID_LCL, pLanguageCode, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
234 if (!pLanguageMap->ContainsKey(*pLanguageCode))
236 std::unique_ptr<String> pDummyValue(new (std::nothrow) String());
237 SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
239 result r = pLanguageMap->Add(pLanguageCode.get(), pDummyValue.get());
240 SysTryReturn(NID_LCL, !IsFailed(r), null, E_SYSTEM, "It is failed to make a language map.");
242 std::unique_ptr<String> pLangCode(new (std::nothrow) String(*(pLanguageCode.get())));
243 r = pAvailableLanguageList->Add(pLangCode.get());
244 SysTryReturn(NID_LCL, !IsFailed(r), null, E_SYSTEM, "It is failed to make a language list.");
246 pLanguageCode.release();
247 pDummyValue.release();
252 SetLastResult(E_SUCCESS);
253 return pAvailableLanguageList.release();
256 _LocaleManagerImpl::GetAvailableLanguagesN(void)
258 std::unique_ptr<ArrayList> pAvailableLanguageList(new (std::nothrow) ArrayList(SingleObjectDeleter));
259 SysTryReturn(NID_LCL, pAvailableLanguageList, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
261 xmlNodePtr cur = null;
262 std::unique_ptr< xmlDoc, FreeXmlDoc > pDoc(xmlParseFile(LANGUAGE_LIST_FILE_PATH));
265 SysLog(NID_LCL, "[E_FILE_NOT_FOUND] It is failed to get the langlist from the resource.");
266 return GetAvailableLanguagesFallbackN();
268 // SysTryReturn(NID_LCL, pDoc != null, null, E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] It is failed to get the langlist from the resource.");
270 cur = xmlDocGetRootElement(pDoc.get());
271 SysTryReturn(NID_LCL, cur != null, null, E_EMPTY_BODY, "[E_EMPTY_BODY] It is empty document.");
272 SysTryReturn(NID_LCL, xmlStrcmp(cur->name, (const xmlChar *) "langlist") == 0, null, E_INVALID_CONTENT, "[E_INVALID_CONTENT] The document is wrong type");
274 cur = cur->xmlChildrenNode;
276 pAvailableLanguageList->Construct();
278 for (xmlNodePtr cur_node = cur; cur_node; cur_node = cur_node->next)
280 if (cur_node->type == XML_ELEMENT_NODE)
282 std::unique_ptr < char, FreeCharPtr > pLocId((char*)xmlGetProp(cur_node, (const xmlChar *)"id"));
283 Locale loc = _LocaleImpl(pLocId.get()).GetOspLocale();
284 std::unique_ptr<String> pLanguageLocaleID(new (std::nothrow) String(loc.GetLanguageCodeString()));
285 SysTryReturn(NID_LCL, pLanguageLocaleID, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed",GetErrorMessage(E_OUT_OF_MEMORY));
287 if (!pAvailableLanguageList->Contains(*(pLanguageLocaleID.get())))
289 result r = pAvailableLanguageList->Add(pLanguageLocaleID.get());
290 SysTryReturn(NID_LCL, r == E_SUCCESS, null, E_SYSTEM,
291 "[%s] It is failed to add a locale string [%ls].", GetErrorMessage(E_SYSTEM), pLanguageLocaleID->GetPointer());
292 pLanguageLocaleID.release();
297 SetLastResult(E_SUCCESS);
298 return pAvailableLanguageList.release();
302 _LocaleManagerImpl::GetAvailableLanguageLocalesN(void)
304 std::unique_ptr<ArrayList> pAvailableLanguageList(new (std::nothrow) ArrayList(SingleObjectDeleter));
305 SysTryReturn(NID_LCL, pAvailableLanguageList, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
307 xmlNodePtr cur = null;
308 std::unique_ptr< xmlDoc, FreeXmlDoc > pDoc(xmlParseFile(LANGUAGE_LIST_FILE_PATH));
309 SysTryReturn(NID_LCL, pDoc != null, null, E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] It is failed to get the langlist from the resource.");
311 cur = xmlDocGetRootElement(pDoc.get());
312 SysTryReturn(NID_LCL, cur != null, null, E_EMPTY_BODY, "[E_EMPTY_BODY] It is empty document.");
313 SysTryReturn(NID_LCL, xmlStrcmp(cur->name, (const xmlChar *) "langlist") == 0, null, E_INVALID_CONTENT, "[E_INVALID_CONTENT] The document is wrong type");
315 cur = cur->xmlChildrenNode;
317 pAvailableLanguageList->Construct();
319 for (xmlNodePtr cur_node = cur; cur_node; cur_node = cur_node->next)
321 if (cur_node->type == XML_ELEMENT_NODE)
323 std::unique_ptr< char, FreeCharPtr> pLocId((char*)xmlGetProp(cur_node, (const xmlChar *)"id"));
324 Locale loc = _LocaleImpl(pLocId.get()).GetOspLocale();
325 if (_LocaleImpl::IsSupported(loc))
327 std::unique_ptr< Locale > pLocale(new (std::nothrow) Locale(loc));
328 SysTryReturn(NID_LCL, pLocale, null, E_OUT_OF_MEMORY,
329 "[%s] Memory allocation failed",GetErrorMessage(E_OUT_OF_MEMORY));
331 if (!pAvailableLanguageList->Contains(*(pLocale.get())))
333 result r = pAvailableLanguageList->Add(pLocale.get());
334 SysTryReturn(NID_LCL, r == E_SUCCESS, null, E_SYSTEM,
335 "[%s] It is failed to add a locale string [%s].", GetErrorMessage(E_SYSTEM), pLocId.get());
342 SetLastResult(E_SUCCESS);
343 return pAvailableLanguageList.release();
348 _LocaleManagerImpl::GetAvailableTimeZonesN(U_ICU_NAMESPACE::StringEnumeration* pIcuTZStrList)
350 SysTryReturn(NID_LCL, pIcuTZStrList, null, E_SYSTEM,
351 "[%s] The method cannot proceed due to a severe system error.",GetErrorMessage(E_SYSTEM));
353 std::unique_ptr<HashMap> pTimeZoneMap(new (std::nothrow) HashMap(SingleObjectDeleter));
354 SysTryReturn(NID_LCL, pTimeZoneMap, null, E_OUT_OF_MEMORY,
355 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
356 pTimeZoneMap->Construct();
358 result r = E_SUCCESS;
359 int resultLength = -1;
360 UErrorCode ec = U_ZERO_ERROR;
361 const char* pIcuTZStr = pIcuTZStrList->next(&resultLength, ec);
362 std::unique_ptr<IMap> pTZMap(GetAvailableTimeZonesN());
364 SysTryReturn(NID_LCL, pTZMap, null, r, "[%s] Fail to get available time zone list", GetErrorMessage(r));
366 while (pIcuTZStr != null)
368 std::unique_ptr< String > pTimeZone(new (std::nothrow) String(pIcuTZStr));
369 SysTryReturn(NID_LCL, pTimeZone, null, E_OUT_OF_MEMORY,
370 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
371 if (!pTimeZoneMap->ContainsKey(*(pTimeZone.get())) && pTZMap->ContainsKey(*(pTimeZone.get())))
373 std::unique_ptr< String > pDummyValue(new (std::nothrow) String());
374 SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
375 r = pTimeZoneMap->Add(pTimeZone.get(), pDummyValue.get());
376 SysTryReturn(NID_LCL, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] It is failed to add a TZ into Map.");
378 pDummyValue.release();
381 pIcuTZStr = pIcuTZStrList->next(&resultLength, ec);
383 SetLastResult(E_SUCCESS);
384 return pTimeZoneMap.release();
387 static const int TIMEZONE_MAX = 224;
388 static const char* TimeZoneList[TIMEZONE_MAX] =
392 "Africa/Addis_Ababa",
402 "Africa/Dar_es_Salaam",
408 "Africa/Johannesburg",
424 "Africa/Ouagadougou",
429 "America/Argentina/Buenos_Aires",
437 "America/Costa_Rica",
440 "America/El_Salvador",
442 "America/Guadeloupe",
448 "America/Indiana/Indianapolis",
450 "America/Kentucky/Louisville",
453 "America/Los_Angeles",
456 "America/Martinique",
458 "America/Mexico_City",
459 "America/Montevideo",
464 "America/Paramaribo",
466 "America/Port-au-Prince",
467 "America/Puerto_Rico",
471 "America/Santo_Domingo",
475 "America/Tegucigalpa",
538 "Asia/Yekaterinburg",
542 "Atlantic/Reykjavik",
543 "Atlantic/South_Georgia",
544 "Australia/Adelaide",
545 "Australia/Brisbane",
546 "Australia/Canberra",
549 "Australia/Melbourne",
567 "Europe/Kaliningrad",
595 "Indian/Antananarivo",
618 _LocaleManagerImpl::GetAvailableTimeZonesFallbackN(void)
620 std::unique_ptr<HashMap> pTimeZoneMap(new (std::nothrow) HashMap(SingleObjectDeleter));
621 SysTryReturn(NID_LCL, pTimeZoneMap, null, E_OUT_OF_MEMORY,
622 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
624 result r = E_SUCCESS;
627 pTimeZoneMap->Construct();
631 std::unique_ptr< String > pTimeZone(new (std::nothrow) String(TimeZoneList[index++]));
632 SysTryReturn(NID_LCL, pTimeZone, null, E_OUT_OF_MEMORY,
633 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
635 if (!pTimeZoneMap->ContainsKey(*(pTimeZone.get())))
637 std::unique_ptr< String > pDummyValue (new (std::nothrow) String());
638 SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
640 r = pTimeZoneMap->Add(pTimeZone.get(), pDummyValue.get());
641 SysTryReturn(NID_LCL, !IsFailed(r), null, E_SYSTEM, "It is failed to make Timezone list.");
644 pDummyValue.release();
646 }while (index < TIMEZONE_MAX);
648 SetLastResult(E_SUCCESS);
649 return pTimeZoneMap.release();
654 _LocaleManagerImpl::GetAvailableTimeZonesN(void)
657 String tzFilePath(TIMEZONE_LIST_FILE_PATH);
658 result r = E_SUCCESS;
660 std::unique_ptr<HashMap> pTimeZoneMap(new (std::nothrow) HashMap(SingleObjectDeleter));
661 SysTryReturn(NID_LCL, pTimeZoneMap, null, E_OUT_OF_MEMORY,
662 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
663 r = file.Construct(tzFilePath, "r");
666 SysLog(NID_LCL,"[E_FILE_NOT_FOUND] It is failed to get the tzlist from the ini file.");
667 return GetAvailableTimeZonesFallbackN();
669 // SysTryReturn(NID_LCL, r == E_SUCCESS, null,E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] It is failed to get the tzlist from the ini file.");
671 pTimeZoneMap->Construct();
675 std::unique_ptr<String> pTimeZone(new (std::nothrow) String());
676 SysTryReturn(NID_LCL, pTimeZone, null, E_OUT_OF_MEMORY,
677 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
678 r = file.Read(*(pTimeZone.get()));
679 if ( r == E_END_OF_FILE)
683 SysTryReturn(NID_LCL, r == E_SUCCESS, null, r, "[%s] It is failed to read the tzlist.", GetErrorMessage(r));
684 pTimeZone->Replace(L"\n", L"\0");
686 if (!pTimeZoneMap->ContainsKey(*(pTimeZone.get())))
688 std::unique_ptr<String> pDummyValue(new (std::nothrow) String());
689 SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,
690 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
692 r = pTimeZoneMap->Add(pTimeZone.get(), pDummyValue.get());
693 SysTryReturn(NID_LCL, r == E_SUCCESS, null, r,"[%s] It is failed to make the tz list.", GetErrorMessage(r));
695 pDummyValue.release();
699 SetLastResult(E_SUCCESS);
700 return pTimeZoneMap.release();
705 _LocaleManagerImpl::GetAvailableTimeZonesN(int rawOffset)
707 std::unique_ptr<U_ICU_NAMESPACE::StringEnumeration> pIcuTzList(U_ICU_NAMESPACE::TimeZone::createEnumeration(rawOffset * _TimeZoneImpl::ONE_MIN_IN_MILLISEC));
708 SysTryReturn(NID_LCL, pIcuTzList, null, E_SYSTEM, "[E_SYSTEM] It is failed to get Icu TZ list.");
709 IMap* pTzList = GetAvailableTimeZonesN(pIcuTzList.get());
715 _LocaleManagerImpl::GetSystemTimeZone(void)
717 std::unique_ptr< char, FreeCharPtr> tzId(vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID));
718 SysTryReturn(NID_LCL, tzId, TimeZone(-1, ""), E_SYSTEM, "It is failed to get System Time Zone.");
719 SysLog(NID_LCL, "System TimeZone id [%s]", tzId.get());
724 struct tm* pGmTime = null;
725 time_t currTime = time(null);
727 pGmTime = gmtime_r(&currTime, &gmTime);
728 SysTryReturn(NID_LCL, pGmTime, TimeZone(-1, ""), E_SYSTEM, "It is failed to convert the time value to UTC time.");
730 utcTime.SetValue(gmTime.tm_year + 1900, gmTime.tm_mon + 1, gmTime.tm_mday, gmTime.tm_hour, gmTime.tm_min, gmTime.tm_sec);
732 result r = Tizen::Locales::TimeZone::GetTimeZone(String(tzId.get()), utcTime, timeZone);
733 SysTryReturn(NID_LCL, r == E_SUCCESS, TimeZone(-1, ""), r, "[%s] error occurs.", GetErrorMessage(r));
738 _LocaleManagerImpl::IsSupportedLocale(const Tizen::Locales::Locale& locale, bool& isSupportedLocale)
740 isSupportedLocale = _LocaleImpl::IsSupported(locale);