Merge "Update deprecated libprivilege-control API functions." into tizen
[platform/framework/native/appfw.git] / src / base / utility / FBaseUtil_IcuConverter.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        :       FBaseUtil_ICUConverter.cpp
19  * @brief       :   Implementation for _ICUConverter Class
20  */
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <wchar.h>
24 #include <string.h>
25 #include <new>
26 #include <unique_ptr.h>
27 #include <unicode/ustring.h>
28 #include <FBaseResult.h>
29 #include "FBase_StringConverter.h"
30 #include "FBase_NativeError.h"
31 #include <FBaseSysLog.h>
32 #include "FBaseUtil_IcuConverter.h"
33
34 namespace Tizen { namespace Base { namespace Utility
35 {
36 _ICUConverter::_ICUConverter(void)
37         : __pConverter(null)
38 {
39
40 }
41 _ICUConverter::~_ICUConverter(void)
42 {
43         if (__pConverter)
44         {
45                 ucnv_close(__pConverter);
46                 __pConverter = null;
47         }
48 }
49
50 bool
51 _ICUConverter::OpenConverter(const Tizen::Base::String& encodingScheme)
52 {
53         std::unique_ptr< char[] > pConverterName(_StringConverter::CopyToCharArrayN(encodingScheme));
54         SysTryReturn(NID_BASE_UTIL, pConverterName != null, false, E_INVALID_ARG, "[%s] Invalid coding scheme.", GetErrorMessage(E_INVALID_ARG));
55         UErrorCode err = U_ZERO_ERROR;
56
57         if (!encodingScheme.CompareTo("UCS-2"))
58         {
59                 __pConverter = ucnv_open("UTF-16LE", &err);
60         }
61         else
62         {
63                 __pConverter = ucnv_open(pConverterName.get(), &err);
64         }
65
66         result r = GetResultFromIcuErrorCode(err);
67         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, false, r, "[%s] The err must be U_ZERO_ERROR.", GetErrorMessage(r));
68
69         SetLastResult(E_SUCCESS);
70         return true;
71 }
72
73 void
74 _ICUConverter::CloseConverter(void)
75 {
76         if (__pConverter)
77         {
78                 ucnv_close(__pConverter);
79                 __pConverter = null;
80         }
81 }
82
83 char*
84 _ICUConverter::ConvertFromUcharN(const wchar_t* pSrc, int srcLength, int& retLength)
85 {
86         UErrorCode errorCode = U_ZERO_ERROR;
87         result r = E_SUCCESS;
88         char* pOutBuf = null;
89         ucnv_setFromUCallBack(__pConverter, UCNV_FROM_U_CALLBACK_STOP, null, null, null, &errorCode);
90
91         int outLen = 0;
92         int icuStrLen = srcLength * 2;
93         UChar* pIcuStr = new (std::nothrow) UChar[icuStrLen];
94         SysTryReturn(NID_BASE_UTIL, pIcuStr != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
95         UChar* pResultStr = u_strFromWCS(pIcuStr, icuStrLen, &outLen, pSrc, srcLength, &errorCode);
96         if (U_SUCCESS(errorCode))
97         {
98                 char* pTmpOut = null;
99                 int outBytesLeftOut = srcLength * 4;
100                 pOutBuf = new (std::nothrow) char[outBytesLeftOut + 1];
101                 SysTryCatch(NID_BASE_UTIL, pOutBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
102
103                 pTmpOut = pOutBuf;
104                 memset(pOutBuf, 0, (outBytesLeftOut + 1));
105                 retLength = ucnv_fromUChars(__pConverter, pTmpOut, outBytesLeftOut, pResultStr, outLen, &errorCode);
106                 r = GetResultFromIcuErrorCode(errorCode);
107                 if (IsFailed(r))
108                 {
109                         delete[] pOutBuf;
110                         pOutBuf = null;
111                 }
112         }
113
114 CATCH:
115         delete[] pIcuStr;
116         pIcuStr = null;
117         SetLastResult(r);
118         return pOutBuf;
119 }
120
121 wchar_t*
122 _ICUConverter::ConvertToUcharN(const char* src, int srcLength)
123 {
124         UErrorCode errorCode = U_ZERO_ERROR;
125         ucnv_setToUCallBack(__pConverter, UCNV_TO_U_CALLBACK_STOP, null, null, null, &errorCode);
126         wchar_t* pDst = null;
127         wchar_t* pResultStr = null;
128         const char* pTmpIn = src;
129         int icuStrLen = (srcLength + 1);
130         UChar* pIcuStr = new (std::nothrow) UChar[icuStrLen];
131         SysTryReturn(NID_BASE_UTIL, pIcuStr != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
132         memset(pIcuStr, 0, sizeof(UChar) * (icuStrLen));
133
134         signed int retLength = ucnv_toUChars(__pConverter, pIcuStr, icuStrLen, pTmpIn, srcLength, &errorCode);
135         result r = GetResultFromIcuErrorCode(errorCode);
136         if (U_SUCCESS(errorCode))
137         {
138                 pDst = new (std::nothrow) wchar_t[retLength + 1];
139                 SysTryCatch(NID_BASE_UTIL, pDst != null, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
140                 memset(pDst, 0, sizeof(wchar_t) * (retLength + 1));
141                 pResultStr = u_strToWCS(pDst, retLength, &retLength, pIcuStr, retLength, &errorCode);
142                 r = GetResultFromIcuErrorCode(errorCode);
143                 if (IsFailed(r))
144                 {
145                         delete[] pDst;
146                         pDst = null;
147                 }
148         }
149
150 CATCH:
151         SetLastResult(r);
152         delete[] pIcuStr;
153         pIcuStr = null;
154         return pResultStr;
155 }
156
157 result
158 _ICUConverter::GetResultFromIcuErrorCode(UErrorCode& err)
159 {
160         if (U_FAILURE(err))
161         {
162                 switch (err)
163                 {
164                 case U_ZERO_ERROR:
165                         return E_SUCCESS;
166
167                 case U_MEMORY_ALLOCATION_ERROR:
168                         return E_OUT_OF_MEMORY;
169
170                 case U_INDEX_OUTOFBOUNDS_ERROR:
171                         return E_INVALID_ARG;
172
173                 case U_TRUNCATED_CHAR_FOUND:
174                 // fall through to U_INVALID_CHAR_FOUND
175                 case U_INVALID_CHAR_FOUND:
176                 // fall through to U_ILLEGAL_CHAR_FOUND
177                 case U_ILLEGAL_CHAR_FOUND:
178                         return E_INVALID_ENCODING_RANGE;
179
180                 case U_INVALID_TABLE_FORMAT:
181                         return E_SYSTEM;
182
183                 case U_BUFFER_OVERFLOW_ERROR:
184                         return E_OVERFLOW;
185
186                 case U_STRING_NOT_TERMINATED_WARNING:
187                         return E_INVALID_ARG;
188
189                 case U_ILLEGAL_ARGUMENT_ERROR:
190                         return E_INVALID_ARG;
191
192                 case U_FILE_ACCESS_ERROR:
193                 case U_AMBIGUOUS_ALIAS_WARNING:
194                         return E_UNSUPPORTED_TYPE;
195
196                 default:
197                         return E_SYSTEM;
198                 }
199         }
200
201         return E_SUCCESS;
202 }
203
204 struct UConverterDeleter
205 {
206         void operator ()(UConverter* pConverter)
207         {
208                 if (pConverter)
209                 {
210                         ucnv_close(pConverter);
211                 }
212         }
213 };
214
215 char*
216 WcharToUtf8N(const wchar_t* pValue)
217 {
218         SysTryReturn(NID_BASE_UTIL, pValue != null, null, E_INVALID_ARG, "[%s] Invalid argument is used. The pValue is null.", GetErrorMessage(E_INVALID_ARG));
219
220         int len = wcslen(pValue);
221         if (len == 0)
222         {
223                 char* pRet = new (std::nothrow) char[1];
224                 SysTryReturn(NID_BASE_UTIL, pRet != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
225                 pRet[0] = '\0';
226                 return pRet;
227         }
228
229         UErrorCode err = U_ZERO_ERROR;
230         std::unique_ptr< UConverter, UConverterDeleter > pConverter(ucnv_open("UTF-8", &err));
231         SysTryReturn(NID_BASE_UTIL, pConverter, null, E_OUT_OF_MEMORY, "[%s] ucnv_open() failed. pConverter is null.", GetErrorMessage(E_OUT_OF_MEMORY));
232         SysTryReturn(NID_BASE_UTIL, U_SUCCESS(err), null, E_INVALID_ARG, "[%s] ucnv_open() failed. The err must be U_ZERO_ERROR.", GetErrorMessage(E_INVALID_ARG));
233
234         ucnv_setFromUCallBack(pConverter.get(), UCNV_FROM_U_CALLBACK_STOP, null, null, null, &err);
235
236         int icuStrCapacity = len * 2 + 1;
237         std::unique_ptr< UChar[] > pIcuStr(new (std::nothrow) UChar[icuStrCapacity]);
238         SysTryReturn(NID_BASE_UTIL, pIcuStr != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
239
240         int outLen = 0;
241         UChar* pResultStr = u_strFromWCS(pIcuStr.get(), icuStrCapacity, &outLen, pValue, len, &err);
242         SysTryReturn(NID_BASE_UTIL, U_SUCCESS(err), null, E_INVALID_ARG, "[%s] u_strFromWCS() failed. pValue is %ls.", GetErrorMessage(E_INVALID_ARG), pValue);
243
244         int destCapacity = len * 4 + 1;
245         std::unique_ptr< char[] > pDst(new (std::nothrow) char[destCapacity]);
246         SysTryReturn(NID_BASE_UTIL, pDst != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
247
248         ucnv_fromUChars(pConverter.get(), pDst.get(), destCapacity, pResultStr, outLen, &err);
249         SysTryReturn(NID_BASE_UTIL, U_SUCCESS(err), null, E_INVALID_ARG, "[%s] ucnv_fromUChars() failed. pValue is %ls.", GetErrorMessage(E_INVALID_ARG), pValue);
250
251         return pDst.release();
252 }
253
254 wchar_t*
255 Utf8ToWcharN(const char* pValue)
256 {
257         SysTryReturn(NID_BASE_UTIL, pValue != null, null, E_INVALID_ARG, "[%s] Invalid argument is used. The pValue is null.", GetErrorMessage(E_INVALID_ARG));
258
259         UErrorCode err = U_ZERO_ERROR;
260         std::unique_ptr< UConverter, UConverterDeleter > pConverter(ucnv_open("UTF-8", &err));
261         SysTryReturn(NID_BASE_UTIL, pConverter, null, E_OUT_OF_MEMORY, "[%s] ucnv_open() failed. pConverter is null.", GetErrorMessage(E_OUT_OF_MEMORY));
262         SysTryReturn(NID_BASE_UTIL, U_SUCCESS(err), null, E_INVALID_ARG, "[%s] ucnv_open() failed. The err must be U_ZERO_ERROR.", GetErrorMessage(E_INVALID_ARG));
263
264         ucnv_setFromUCallBack(pConverter.get(), UCNV_FROM_U_CALLBACK_STOP, null, null, null, &err);
265
266         int len = strlen(pValue);
267         int icuStrCapacity = len + 1;
268         std::unique_ptr< UChar[] > pIcuStr(new (std::nothrow) UChar[icuStrCapacity]);
269         SysTryReturn(NID_BASE_UTIL, pIcuStr != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
270
271         signed int retLength = ucnv_toUChars(pConverter.get(), pIcuStr.get(), icuStrCapacity, pValue, len, &err);
272         SysTryReturn(NID_BASE_UTIL, U_SUCCESS(err), null, E_INVALID_ARG, "[%s] ucnv_toUChars() failed. pValue is %s.", GetErrorMessage(E_INVALID_ARG), pValue);
273
274         int destCapacity = retLength + String::DEFAULT_CAPACITY + 1;
275         std::unique_ptr< wchar_t[] > pDst(new (std::nothrow) wchar_t[destCapacity]);
276         SysTryReturn(NID_BASE_UTIL, pDst != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
277
278         u_strToWCS(pDst.get(), destCapacity, &retLength, pIcuStr.get(), retLength, &err);
279         SysTryReturn(NID_BASE_UTIL, U_SUCCESS(err), null, E_INVALID_ARG, "[%s] u_strToWCS() failed. pValue is %s.", GetErrorMessage(E_INVALID_ARG), pValue);
280
281         return pDst.release();
282 }
283 }}} // Tizen::Base::Utility