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 <libxml/parser.h>
28 #include <libxml/tree.h>
31 #include <FBaseSysLog.h>
32 #include <FBase_StringConverter.h>
34 #include "FLcl_LocaleImpl.h"
35 #include "FLcl_TimeZoneImpl.h"
36 #include "FLcl_LocaleManagerImpl.h"
39 using namespace Tizen::Base;
40 using namespace Tizen::Base::Utility;
41 using namespace Tizen::Base::Collection;
42 using namespace Tizen::Io;
46 void operator ()(xmlDoc* p)
55 namespace Tizen { namespace Locales
57 static const char* LANGUAGE_LIST_FILE_PATH ="/opt/data/setting/langlist.xml";
58 static const char* TIMEZONE_LIST_FILE_PATH = "/opt/data/setting/tzlist.ini";
59 static const char* CLOCALE_LIST_FILE_PATH = "/opt/usr/etc/clocale.list";
63 _LocaleManagerImpl::GetSystemLocale(void)
66 if (runtime_info_get_value_string(RUNTIME_INFO_KEY_REGION, &pRegionPtr) == RUNTIME_INFO_ERROR_NONE)
68 SetLastResult(E_SUCCESS);
70 Locale ospLoc = _LocaleImpl(pRegionPtr).GetOspLocale();
75 SetLastResult(E_SYSTEM);
76 return Locale(LANGUAGE_INVALID, COUNTRY_INVALID, null);
81 _LocaleManagerImpl::GetAvailableEglibcLocaesN(void)
85 String clocaleFilePath(CLOCALE_LIST_FILE_PATH);
87 std::unique_ptr<HashMap> pClocaleMap(new (std::nothrow) HashMap(SingleObjectDeleter));
88 SysTryReturn(NID_LCL, pClocaleMap, null, E_OUT_OF_MEMORY,
89 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
90 r = file.Construct(clocaleFilePath, "r");
91 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.");
93 pClocaleMap->Construct();
98 r = file.Read(strBuf);
99 if ( r == E_END_OF_FILE)
103 SysTryReturn(NID_LCL, r == E_SUCCESS, null, r, "[%s] It is failed to read the clocale list.", GetErrorMessage(r));
104 std::unique_ptr< String > pClocaleId(new (std::nothrow) String());
105 SysTryReturn(NID_LCL, pClocaleId, null, E_OUT_OF_MEMORY,
106 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
107 r = strBuf.SubString(0, 5, *pClocaleId);
113 if (!pClocaleMap->ContainsKey(*(pClocaleId.get())))
115 std::unique_ptr<String> pDummyValue(new (std::nothrow) String());
116 SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,
117 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
119 r = pClocaleMap->Add(*(pClocaleId.get()), *(pDummyValue.get()));
120 SysTryReturn(NID_LCL, r == E_SUCCESS, null, r,
121 "[%s] It is failed to add the clocale id into the clocale map.", GetErrorMessage(r));
122 pClocaleId.release();
123 pDummyValue.release();
126 return pClocaleMap.release();
130 _LocaleManagerImpl::GetAvailableLocalesN(void)
132 result r = E_SUCCESS;
134 const U_ICU_NAMESPACE::Locale* pIcuLocaleList = U_ICU_NAMESPACE::Locale::getAvailableLocales(count);
135 SysTryReturn(NID_LCL, count > 0, null, E_SYSTEM,
136 "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
138 std::unique_ptr<LinkedList> pAvailableLocaleList(new (std::nothrow) LinkedList(SingleObjectDeleter));
139 SysTryReturn(NID_LCL, pAvailableLocaleList, null, E_OUT_OF_MEMORY,
140 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
142 std::unique_ptr< IMap > pClocaleMap(GetAvailableEglibcLocaesN());
144 for (int i = 0; i < count; i++)
146 const U_ICU_NAMESPACE::Locale* pIcuLocale = (pIcuLocaleList + i);
147 SysTryReturn(NID_LCL, pIcuLocale, null, E_SYSTEM,
148 "[%s] The method cannot proceed due to a severe system error.",GetErrorMessage(E_SYSTEM));
149 Locale ospLocale = _LocaleImpl(*pIcuLocale).GetOspLocale();
150 if (_LocaleImpl::IsSupported(ospLocale))
152 std::unique_ptr< Locale > pLocale(new (std::nothrow) Locale(ospLocale));
153 SysTryReturn(NID_LCL, pLocale, null, E_OUT_OF_MEMORY,
154 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
156 String localeId(pIcuLocale->getLanguage());
157 localeId = localeId + L"_" + String(pIcuLocale->getCountry());
159 if (!pAvailableLocaleList->Contains(*(pLocale.get())) && pClocaleMap->ContainsKey(localeId))
161 r = pAvailableLocaleList->Add(*(pLocale.get()));
162 SysTryReturn(NID_LCL, !IsFailed(r), null, E_SYSTEM, "It is failed to make the locale list");
168 SetLastResult(E_SUCCESS);
169 return pAvailableLocaleList.release();
173 _LocaleManagerImpl::GetSelectedLanguage(void)
177 int ret = runtime_info_get_value_string(RUNTIME_INFO_KEY_LANGUAGE, &pLanguagePtr);
178 SysTryReturn(NID_LCL, ret == RUNTIME_INFO_ERROR_NONE, String(), E_SYSTEM,
179 "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
180 String language(_LocaleImpl(pLanguagePtr).GetLanguageCodeString(false));
187 _LocaleManagerImpl::GetAvailableLanguagesN(void)
189 std::unique_ptr<ArrayList> pAvailableLanguageList(new (std::nothrow) ArrayList(SingleObjectDeleter));
190 SysTryReturn(NID_LCL, pAvailableLanguageList, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
192 xmlNodePtr cur = null;
193 std::unique_ptr< xmlDoc, FreeXmlDoc > pDoc(xmlParseFile(LANGUAGE_LIST_FILE_PATH));
194 SysTryReturn(NID_LCL, pDoc != null, null, E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] It is failed to get the langlist from the resource.");
196 cur = xmlDocGetRootElement(pDoc.get());
197 SysTryReturn(NID_LCL, cur != null, null, E_EMPTY_BODY, "[E_EMPTY_BODY] It is empty document.");
198 SysTryReturn(NID_LCL, xmlStrcmp(cur->name, (const xmlChar *) "langlist") == 0, null, E_INVALID_CONTENT, "[E_INVALID_CONTENT] The document is wrong type");
200 cur = cur->xmlChildrenNode;
202 pAvailableLanguageList->Construct();
204 for (xmlNodePtr cur_node = cur; cur_node; cur_node = cur_node->next)
206 if (cur_node->type == XML_ELEMENT_NODE)
208 std::unique_ptr < char > pLocId((char*)xmlGetProp(cur_node, (const xmlChar *)"id"));
209 Locale loc = _LocaleImpl(pLocId.get()).GetOspLocale();
210 std::unique_ptr<String> pLanguageLocaleID(new (std::nothrow) String(loc.GetLanguageCodeString()));
211 SysTryReturn(NID_LCL, pLanguageLocaleID, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed",GetErrorMessage(E_OUT_OF_MEMORY));
213 if (!pAvailableLanguageList->Contains(*(pLanguageLocaleID.get())))
215 result r = pAvailableLanguageList->Add(pLanguageLocaleID.get());
216 SysTryReturn(NID_LCL, r == E_SUCCESS, null, E_SYSTEM,
217 "[%s] It is failed to add a locale string [%ls].", GetErrorMessage(E_SYSTEM), pLanguageLocaleID->GetPointer());
218 pLanguageLocaleID.release();
223 SetLastResult(E_SUCCESS);
224 return pAvailableLanguageList.release();
229 _LocaleManagerImpl::GetAvailableLanguageLocalesN(void)
231 std::unique_ptr<ArrayList> pAvailableLanguageList(new (std::nothrow) ArrayList(SingleObjectDeleter));
232 SysTryReturn(NID_LCL, pAvailableLanguageList, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
234 xmlNodePtr cur = null;
235 std::unique_ptr< xmlDoc, FreeXmlDoc > pDoc(xmlParseFile(LANGUAGE_LIST_FILE_PATH));
236 SysTryReturn(NID_LCL, pDoc != null, null, E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] It is failed to get the langlist from the resource.");
238 cur = xmlDocGetRootElement(pDoc.get());
239 SysTryReturn(NID_LCL, cur != null, null, E_EMPTY_BODY, "[E_EMPTY_BODY] It is empty document.");
240 SysTryReturn(NID_LCL, xmlStrcmp(cur->name, (const xmlChar *) "langlist") == 0, null, E_INVALID_CONTENT, "[E_INVALID_CONTENT] The document is wrong type");
242 cur = cur->xmlChildrenNode;
244 pAvailableLanguageList->Construct();
246 for (xmlNodePtr cur_node = cur; cur_node; cur_node = cur_node->next)
248 if (cur_node->type == XML_ELEMENT_NODE)
250 std::unique_ptr< char > pLocId((char*)xmlGetProp(cur_node, (const xmlChar *)"id"));
251 Locale loc = _LocaleImpl(pLocId.get()).GetOspLocale();
252 if (_LocaleImpl::IsSupported(loc))
254 std::unique_ptr< Locale > pLocale(new (std::nothrow) Locale(loc));
255 SysTryReturn(NID_LCL, pLocale, null, E_OUT_OF_MEMORY,
256 "[%s] Memory allocation failed",GetErrorMessage(E_OUT_OF_MEMORY));
258 if (!pAvailableLanguageList->Contains(*(pLocale.get())))
260 result r = pAvailableLanguageList->Add(*(pLocale.get()));
261 SysTryReturn(NID_LCL, r == E_SUCCESS, null, E_SYSTEM,
262 "[%s] It is failed to add a locale string [%s].", GetErrorMessage(E_SYSTEM), pLocId.get());
269 SetLastResult(E_SUCCESS);
270 return pAvailableLanguageList.release();
275 _LocaleManagerImpl::GetAvailableTimeZonesN(U_ICU_NAMESPACE::StringEnumeration* pIcuTZStrList)
277 SysTryReturn(NID_LCL, pIcuTZStrList, null, E_SYSTEM,
278 "[%s] The method cannot proceed due to a severe system error.",GetErrorMessage(E_SYSTEM));
280 std::unique_ptr<HashMap> pTimeZoneMap(new (std::nothrow) HashMap(SingleObjectDeleter));
281 SysTryReturn(NID_LCL, pTimeZoneMap, null, E_OUT_OF_MEMORY,
282 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
283 pTimeZoneMap->Construct();
285 result r = E_SUCCESS;
286 int resultLength = -1;
287 UErrorCode ec = U_ZERO_ERROR;
288 const char* pIcuTZStr = pIcuTZStrList->next(&resultLength, ec);
289 std::unique_ptr<IMap> pTZMap(GetAvailableTimeZonesN());
291 SysTryReturn(NID_LCL, pTZMap, null, r, "[%s] Fail to get available time zone list", GetErrorMessage(r));
293 while (pIcuTZStr != null)
295 std::unique_ptr< String > pTimeZone(new (std::nothrow) String(pIcuTZStr));
296 SysTryReturn(NID_LCL, pTimeZone, null, E_OUT_OF_MEMORY,
297 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
298 if (!pTimeZoneMap->ContainsKey(*(pTimeZone.get())) && pTZMap->ContainsKey(*(pTimeZone.get())))
300 std::unique_ptr< String > pDummyValue(new (std::nothrow) String());
301 SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
302 r = pTimeZoneMap->Add(*(pTimeZone.get()), *(pDummyValue.get()));
303 SysTryReturn(NID_LCL, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] It is failed to add a TZ into Map.");
305 pDummyValue.release();
308 pIcuTZStr = pIcuTZStrList->next(&resultLength, ec);
310 SetLastResult(E_SUCCESS);
311 return pTimeZoneMap.release();
316 _LocaleManagerImpl::GetAvailableTimeZonesN(void)
319 String tzFilePath(TIMEZONE_LIST_FILE_PATH);
320 result r = E_SUCCESS;
322 std::unique_ptr<HashMap> pTimeZoneMap(new (std::nothrow) HashMap(SingleObjectDeleter));
323 SysTryReturn(NID_LCL, pTimeZoneMap, null, E_OUT_OF_MEMORY,
324 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
325 r = file.Construct(tzFilePath, "r");
326 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.");
328 pTimeZoneMap->Construct();
332 std::unique_ptr<String> pTimeZone(new (std::nothrow) String());
333 SysTryReturn(NID_LCL, pTimeZone, null, E_OUT_OF_MEMORY,
334 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
335 r = file.Read(*(pTimeZone.get()));
336 if ( r == E_END_OF_FILE)
340 SysTryReturn(NID_LCL, r == E_SUCCESS, null, r, "[%s] It is failed to read the tzlist.", GetErrorMessage(r));
341 pTimeZone->Replace(L"\n", L"\0");
343 if (!pTimeZoneMap->ContainsKey(*(pTimeZone.get())))
345 std::unique_ptr<String> pDummyValue(new (std::nothrow) String());
346 SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,
347 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
349 r = pTimeZoneMap->Add(*(pTimeZone.get()), *(pDummyValue.get()));
350 SysTryReturn(NID_LCL, r == E_SUCCESS, null, r,"[%s] It is failed to make the tz list.", GetErrorMessage(r));
352 pDummyValue.release();
356 SetLastResult(E_SUCCESS);
357 return pTimeZoneMap.release();
362 _LocaleManagerImpl::GetAvailableTimeZonesN(int rawOffset)
364 std::unique_ptr<U_ICU_NAMESPACE::StringEnumeration> pIcuTzList(U_ICU_NAMESPACE::TimeZone::createEnumeration(rawOffset * _TimeZoneImpl::ONE_MIN_IN_MILLISEC));
365 SysTryReturn(NID_LCL, pIcuTzList, null, E_SYSTEM, "[E_SYSTEM] It is failed to get Icu TZ list.");
366 IMap* pTzList = GetAvailableTimeZonesN(pIcuTzList.get());
372 _LocaleManagerImpl::GetSystemTimeZone(void)
374 char tz[PATH_MAX + 1];
375 int len = readlink("/opt/etc/localtime", tz, PATH_MAX);
377 SysTryReturn(NID_LCL, len > 0, TimeZone(-1, ""), E_SYSTEM, "It is failed to get System Time Zone");
379 SysTryReturn(NID_LCL, len > 20, TimeZone(-1, ""), E_SYSTEM, "It is failed to get System Time Zone");
381 String tzId(tz + 20);
382 SysLog(NID_LCL, "System TimeZone id [%ls]", tzId.GetPointer());
386 struct tm* pGmTime = null;
389 pGmTime = gmtime(&currTime);
390 utcTime.SetValue(pGmTime->tm_year + 1900, pGmTime->tm_mon + 1, pGmTime->tm_mday, pGmTime->tm_hour, pGmTime->tm_min, pGmTime->tm_sec);
392 result r = Tizen::Locales::TimeZone::GetTimeZone(tzId, utcTime, timeZone);
393 SysTryReturn(NID_LCL, r == E_SUCCESS, TimeZone(-1, ""), r, "[%s] error occurs.", GetErrorMessage(r));
398 _LocaleManagerImpl::IsSupportedLocale(const Tizen::Locales::Locale& locale, bool& isSupportedLocale)
400 isSupportedLocale = _LocaleImpl::IsSupported(locale);