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 FText_IcuEncodingCore.cpp
19 * @brief This is the implementation file for _IcuEncodingCore class.
23 #include<unique_ptr.h>
24 #include <unicode/ustring.h>
26 #include <FBaseSysLog.h>
27 #include "FText_IcuEncodingCore.h"
29 using namespace Tizen::Base;
30 using namespace Tizen::Base::Collection;
31 using namespace Tizen::Base::Utility;
33 namespace Tizen { namespace Text
36 _IcuEncodingCore::_IcuEncodingCore(void)
41 _IcuEncodingCore::~_IcuEncodingCore(void)
45 ucnv_close(__pEncoder);
51 _IcuEncodingCore::__Encode(const wchar_t* pSrc, int srcLength, byte* pDst, int dstLength, int& retLength)
53 SysTryReturnResult(NID_TEXT, pSrc, E_INVALID_ARG,
54 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
55 SysTryReturnResult(NID_TEXT, srcLength >= 0, E_INVALID_ARG,
56 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
58 UErrorCode err = U_ZERO_ERROR;
60 int icuStrLen = srcLength * 2;
62 result r = E_OUT_OF_MEMORY;
63 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
66 IcuUChar* pIcuStr1 = u_strFromWCS(pIcuStr, icuStrLen, &outLen, pSrc, srcLength, &err);
71 retLength = ucnv_fromUChars(__pEncoder, (char*) pDst, dstLength, pIcuStr1, outLen, &err);
75 retLength = ucnv_fromUChars(__pEncoder, null, 0, pIcuStr1, outLen, &err);
76 if (err == U_BUFFER_OVERFLOW_ERROR)
87 r = GetResultFromIcuErrorCode(err);
95 _IcuEncodingCore::__Decode(const byte* pSrc, int srcLength, wchar_t* pDst, int dstLength, int& retLength)
97 SysTryReturnResult(NID_TEXT, pSrc, E_INVALID_ARG,
98 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
99 SysTryReturnResult(NID_TEXT, srcLength >= 0, E_INVALID_ARG,
100 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
102 bool isCallForCharCount = (pDst == null);
103 if (isCallForCharCount)
105 dstLength = srcLength * 2;
106 pDst = new (std::nothrow) wchar_t[dstLength];
107 SysTryReturnResult(NID_TEXT, pDst, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
110 UErrorCode err = U_ZERO_ERROR;
111 int icuStrLen = dstLength * 2;
112 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
115 retLength = ucnv_toUChars(__pEncoder, pIcuStr, icuStrLen, (const char*) pSrc, srcLength, &err);
118 pDst = u_strToWCS(pDst, dstLength, &retLength, pIcuStr, retLength, &err);
123 if (isCallForCharCount)
134 return GetResultFromIcuErrorCode(err);
138 _IcuEncodingCore::EncodeExN(const wchar_t* pSrc, int srcLength, int& retLength, bool flush)
140 SysTryReturn(NID_TEXT, pSrc, null, E_INVALID_ARG,
141 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
142 SysTryReturn(NID_TEXT, srcLength >= 0, null, E_INVALID_ARG,
143 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
145 result r = E_SUCCESS;
146 UErrorCode err = U_ZERO_ERROR;
150 int icuStrLen = srcLength * 2;
151 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
152 SysTryCatch(NID_TEXT, pIcuStr, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
154 pIcuStr = u_strFromWCS(pIcuStr, icuStrLen, &outLen, pSrc, srcLength, &err);
155 r = GetResultFromIcuErrorCode(err);
158 int maxDestLen = UCNV_GET_MAX_BYTES_FOR_STRING(outLen, ucnv_getMaxCharSize(__pEncoder));
159 pDst = new (std::nothrow) byte[maxDestLen];
162 char* pDstArray = (char*) pDst;
163 const char* pDstLimit = pDstArray + maxDestLen;
164 const IcuUChar* pSrcArray = pIcuStr;
165 const IcuUChar* pSrcLimit = pIcuStr + outLen;
168 ucnv_fromUnicode(__pEncoder, &pDstArray, pDstLimit, &pSrcArray, pSrcLimit, null, flush, &err);
169 r = GetResultFromIcuErrorCode(err);
172 retLength = (byte*) pDstArray - pDst;
175 SetLastResult(E_SUCCESS);
190 _IcuEncodingCore::DecodeExN(const byte* pSrc, int srcLength, int& retLength, bool flush)
192 SysTryReturn(NID_TEXT, pSrc, null, E_INVALID_ARG,
193 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
194 SysTryReturn(NID_TEXT, srcLength >= 0, null, E_INVALID_ARG,
195 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
197 UErrorCode err = U_ZERO_ERROR;
198 int icuStrLen = srcLength * 2;
199 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
200 SysTryReturn(NID_TEXT, pIcuStr, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
202 IcuUChar* pDstArray = pIcuStr;
203 const IcuUChar* pDstLimit = pIcuStr + icuStrLen;
204 const char* pSrcArray = (const char*) pSrc;
205 const char* pSrcLimit = pSrcArray + srcLength;
207 result r = E_SUCCESS;
208 wchar_t* pDst = null;
211 ucnv_toUnicode(__pEncoder, &pDstArray, pDstLimit, &pSrcArray, pSrcLimit, null, flush, &err);
212 r = GetResultFromIcuErrorCode(err);
216 int dstLength = pDstArray - pIcuStr;
217 pDst = new (std::nothrow) wchar_t[dstLength + 1];
218 SysTryCatch(NID_TEXT, pDst, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
219 pDst[dstLength] = '\0';
221 pDst = u_strToWCS(pDst, dstLength, &retLength, pIcuStr, dstLength, &err);
222 r = GetResultFromIcuErrorCode(err);
223 SysTryCatch(NID_TEXT, !IsFailed(r), , r, "Decoding failed");
226 SetLastResult(E_SUCCESS);
239 _IcuEncodingCore::GetEncodingCoreImplN(const Tizen::Base::String& encodingFrom, const Tizen::Base::String& encodingTo)
241 result r = E_SUCCESS;
242 UErrorCode err = U_ZERO_ERROR;
243 std::unique_ptr<_IcuEncodingCore> pEncodingCore(null);
245 int lenEncoding = encodingFrom.GetLength();
246 std::unique_ptr<char[]> pEncoding(new (std::nothrow) char[lenEncoding + 2]);
247 SysTryReturn(NID_TEXT, (pEncoding != null), null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
249 size_t retLength = wcstombs(pEncoding.get(), encodingFrom.GetPointer(), lenEncoding);
250 SysTryReturn(NID_TEXT, (retLength > 0), null, E_SYSTEM, "[%s] Unable to convert encoding string to multi byte char array", GetErrorMessage(E_SYSTEM));
252 *(pEncoding.get() + retLength) = '\0';
254 pEncodingCore.reset(new (std::nothrow) _IcuEncodingCore);
255 SysTryReturn(NID_TEXT, (pEncodingCore != null), null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
257 pEncodingCore->__pEncoder = ucnv_open(pEncoding.get(), &err);
260 String subsEncoding(encodingFrom);
261 subsEncoding.ToUpper();
262 if (subsEncoding.StartsWith("UCS", 0))
264 r = subsEncoding.Replace("UCS", "UTF");
265 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to open ICU converter", GetErrorMessage(r));
267 r = subsEncoding.Replace("4", "32");
268 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to open ICU converter", GetErrorMessage(r));
270 size_t retLength = wcstombs(pEncoding.get(), subsEncoding.GetPointer(), subsEncoding.GetLength());
271 SysTryReturn(NID_TEXT, (retLength > 0), null, E_SYSTEM, "[%s] Unable to convert encoding string to multi byte char array", GetErrorMessage(E_SYSTEM));
273 pEncoding[retLength] = '\0';
275 pEncodingCore->__pEncoder = ucnv_open(pEncoding.get(), &err);
279 r = pEncodingCore->GetResultFromIcuErrorCode(err);
280 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to open ICU converter", GetErrorMessage(r));
282 ucnv_setFromUCallBack(pEncodingCore->__pEncoder, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, &err);
283 ucnv_setToUCallBack(pEncodingCore->__pEncoder, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, NULL, &err);
285 pEncodingCore->_encodingFrom = encodingFrom;
286 pEncodingCore->_encodingTo = L"WCHAR_T";
288 SetLastResult(E_SUCCESS);
289 return pEncodingCore.release();
293 _IcuEncodingCore::GetName(void)
295 UErrorCode err = U_ZERO_ERROR;
296 const char* pName = ucnv_getName(__pEncoder, &err);
299 return String(pName);
306 _IcuEncodingCore::GetByteCount(const wchar_t* pSrc, int srcLength, int& retLength)
308 return __Encode(pSrc, srcLength, null, 0, retLength);
312 _IcuEncodingCore::GetCharCount(const byte* pSrc, int srcLength, int& retLength)
314 return __Decode(pSrc, srcLength, null, 0, retLength);
318 _IcuEncodingCore::EncodeN(const wchar_t* pSrc, int srcLength, int& retLength)
320 int maxDestLen = UCNV_GET_MAX_BYTES_FOR_STRING(srcLength * 2, ucnv_getMaxCharSize(__pEncoder));
321 std::unique_ptr<byte[]> pByte(new (std::nothrow) byte[maxDestLen]);
322 SysTryReturn(NID_TEXT, pByte, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
324 result r = __Encode(pSrc, srcLength, pByte.get(), maxDestLen, retLength);
325 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Encode operation failed", GetErrorMessage(r));
327 SetLastResult(E_SUCCESS);
328 return pByte.release();
332 _IcuEncodingCore::DecodeN(const byte* pSrc, int srcLength, int& retLength)
334 int maxDestLen = srcLength * 2;
335 std::unique_ptr<wchar_t[]> pWchar(new (std::nothrow) wchar_t[maxDestLen]);
336 SysTryReturn(NID_TEXT, pWchar, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
338 result r = __Decode(pSrc, srcLength, pWchar.get(), maxDestLen, retLength);
339 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Encode operation failed", GetErrorMessage(r));
341 SetLastResult(E_SUCCESS);
342 return pWchar.release();
346 _IcuEncodingCore::GetMaxByteCount(int charCount) const
348 return charCount * (ucnv_getMaxCharSize(__pEncoder));
352 _IcuEncodingCore::GetMaxCharCount(int byteCount) const
354 return byteCount / (ucnv_getMinCharSize(__pEncoder));
359 _IcuEncodingCore::GetResultFromIcuErrorCode(UErrorCode& err)
361 result r = E_SUCCESS;
366 case U_MEMORY_ALLOCATION_ERROR:
372 case U_INDEX_OUTOFBOUNDS_ERROR:
378 case U_TRUNCATED_CHAR_FOUND:
379 // fall through to U_INVALID_CHAR_FOUND
380 case U_INVALID_CHAR_FOUND:
381 // fall through to U_ILLEGAL_CHAR_FOUND
382 case U_ILLEGAL_CHAR_FOUND:
384 r = E_INVALID_ENCODING_RANGE;
388 case U_INVALID_TABLE_FORMAT:
394 case U_BUFFER_OVERFLOW_ERROR:
400 case U_STRING_NOT_TERMINATED_WARNING:
406 case U_ILLEGAL_ARGUMENT_ERROR:
412 case U_FILE_ACCESS_ERROR:
413 // fall through to U_AMBIGUOUS_ALIAS_WARNING
414 case U_AMBIGUOUS_ALIAS_WARNING:
416 r = E_UNSUPPORTED_TYPE;
431 _IcuEncodingCore::GetIcuUcharN(const Tizen::Base::String& ospString, result& r)
433 UErrorCode err = U_ZERO_ERROR;
435 int srcLength = ospString.GetLength();
436 std::unique_ptr<IcuUChar> pIcuStr(new (std::nothrow) IcuUChar(srcLength + 2));
437 SysTryReturn(NID_TEXT, pIcuStr != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
439 pIcuStr.reset(u_strFromWCS(
443 ospString.GetPointer(),
448 r = GetResultFromIcuErrorCode(err);
449 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Error in converting osp string to ICU UChar", GetErrorMessage(r));
451 return pIcuStr.release();