2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FText_IcuEncodingCore.cpp
20 * @brief This is the implementation file for _IcuEncodingCore class.
24 #include<unique_ptr.h>
25 #include <unicode/ustring.h>
27 #include <FBaseSysLog.h>
28 #include "FText_IcuEncodingCore.h"
30 using namespace Tizen::Base;
31 using namespace Tizen::Base::Collection;
32 using namespace Tizen::Base::Utility;
34 #define EXTRA_ENCODINGS_LENGTH 3
35 static String extraEncodings[] = {
36 "UCS4", "UCS4BE", "UCS4LE"
39 namespace Tizen { namespace Text
42 _IcuEncodingCore::_IcuEncodingCore(void)
47 _IcuEncodingCore::~_IcuEncodingCore(void)
51 ucnv_close(__pEncoder);
57 _IcuEncodingCore::__Encode(const wchar_t* pSrc, int srcLength, byte* pDst, int dstLength, int& retLength)
59 SysTryReturnResult(NID_TEXT, pSrc, E_INVALID_ARG,
60 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
61 SysTryReturnResult(NID_TEXT, srcLength >= 0, E_INVALID_ARG,
62 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
64 UErrorCode err = U_ZERO_ERROR;
66 int icuStrLen = srcLength * 2;
68 result r = E_OUT_OF_MEMORY;
69 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
72 IcuUChar* pIcuStr1 = u_strFromWCS(pIcuStr, icuStrLen, &outLen, pSrc, srcLength, &err);
77 retLength = ucnv_fromUChars(__pEncoder, (char*) pDst, dstLength, pIcuStr1, outLen, &err);
81 retLength = ucnv_fromUChars(__pEncoder, null, 0, pIcuStr1, outLen, &err);
82 if (err == U_BUFFER_OVERFLOW_ERROR)
93 r = GetResultFromIcuErrorCode(err);
101 _IcuEncodingCore::__Decode(const byte* pSrc, int srcLength, wchar_t* pDst, int dstLength, int& retLength)
103 SysTryReturnResult(NID_TEXT, pSrc, E_INVALID_ARG,
104 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
105 SysTryReturnResult(NID_TEXT, srcLength >= 0, E_INVALID_ARG,
106 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
108 bool isCallForCharCount = (pDst == null);
109 if (isCallForCharCount)
111 dstLength = srcLength * 2;
112 pDst = new (std::nothrow) wchar_t[dstLength];
113 SysTryReturnResult(NID_TEXT, pDst, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
116 UErrorCode err = U_ZERO_ERROR;
117 int icuStrLen = dstLength * 2;
118 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
121 retLength = ucnv_toUChars(__pEncoder, pIcuStr, icuStrLen, (const char*) pSrc, srcLength, &err);
124 pDst = u_strToWCS(pDst, dstLength, &retLength, pIcuStr, retLength, &err);
129 if (isCallForCharCount)
140 return GetResultFromIcuErrorCode(err);
144 _IcuEncodingCore::EncodeExN(const wchar_t* pSrc, int srcLength, int& retLength, bool flush)
146 SysTryReturn(NID_TEXT, pSrc, null, E_INVALID_ARG,
147 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
148 SysTryReturn(NID_TEXT, srcLength >= 0, null, E_INVALID_ARG,
149 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
151 result r = E_SUCCESS;
152 UErrorCode err = U_ZERO_ERROR;
156 int icuStrLen = srcLength * 2;
157 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
158 SysTryCatch(NID_TEXT, pIcuStr, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
160 pIcuStr = u_strFromWCS(pIcuStr, icuStrLen, &outLen, pSrc, srcLength, &err);
161 r = GetResultFromIcuErrorCode(err);
164 int maxDestLen = UCNV_GET_MAX_BYTES_FOR_STRING(outLen, ucnv_getMaxCharSize(__pEncoder));
165 pDst = new (std::nothrow) byte[maxDestLen];
168 char* pDstArray = (char*) pDst;
169 const char* pDstLimit = pDstArray + maxDestLen;
170 const IcuUChar* pSrcArray = pIcuStr;
171 const IcuUChar* pSrcLimit = pIcuStr + outLen;
174 ucnv_fromUnicode(__pEncoder, &pDstArray, pDstLimit, &pSrcArray, pSrcLimit, null, flush, &err);
175 r = GetResultFromIcuErrorCode(err);
178 retLength = (byte*) pDstArray - pDst;
181 SetLastResult(E_SUCCESS);
196 _IcuEncodingCore::DecodeExN(const byte* pSrc, int srcLength, int& retLength, bool flush)
198 SysTryReturn(NID_TEXT, pSrc, null, E_INVALID_ARG,
199 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
200 SysTryReturn(NID_TEXT, srcLength >= 0, null, E_INVALID_ARG,
201 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
203 UErrorCode err = U_ZERO_ERROR;
204 int icuStrLen = srcLength * 2;
205 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
206 SysTryReturn(NID_TEXT, pIcuStr, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
208 IcuUChar* pDstArray = pIcuStr;
209 const IcuUChar* pDstLimit = pIcuStr + icuStrLen;
210 const char* pSrcArray = (const char*) pSrc;
211 const char* pSrcLimit = pSrcArray + srcLength;
213 result r = E_SUCCESS;
214 wchar_t* pDst = null;
217 ucnv_toUnicode(__pEncoder, &pDstArray, pDstLimit, &pSrcArray, pSrcLimit, null, flush, &err);
218 r = GetResultFromIcuErrorCode(err);
222 int dstLength = pDstArray - pIcuStr;
223 pDst = new (std::nothrow) wchar_t[dstLength + 1];
224 SysTryCatch(NID_TEXT, pDst, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
225 pDst[dstLength] = '\0';
227 pDst = u_strToWCS(pDst, dstLength, &retLength, pIcuStr, dstLength, &err);
228 r = GetResultFromIcuErrorCode(err);
229 SysTryCatch(NID_TEXT, !IsFailed(r), , r, "Decoding failed");
232 SetLastResult(E_SUCCESS);
245 _IcuEncodingCore::GetEncodingCoreImplN(const Tizen::Base::String& encodingFrom, const Tizen::Base::String& encodingTo)
247 result r = E_SUCCESS;
248 UErrorCode err = U_ZERO_ERROR;
249 std::unique_ptr<_IcuEncodingCore> pEncodingCore(null);
251 int lenEncoding = encodingFrom.GetLength();
252 std::unique_ptr<char[]> pEncoding(new (std::nothrow) char[lenEncoding + 2]);
253 SysTryReturn(NID_TEXT, (pEncoding != null), null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
255 size_t retLength = wcstombs(pEncoding.get(), encodingFrom.GetPointer(), lenEncoding);
256 SysTryReturn(NID_TEXT, (retLength > 0), null, E_SYSTEM, "[%s] Unable to convert encoding string to multi byte char array", GetErrorMessage(E_SYSTEM));
258 *(pEncoding.get() + retLength) = '\0';
260 pEncodingCore.reset(new (std::nothrow) _IcuEncodingCore);
261 SysTryReturn(NID_TEXT, (pEncodingCore != null), null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
263 pEncodingCore->__pEncoder = ucnv_open(pEncoding.get(), &err);
266 String subsEncoding(encodingFrom);
267 subsEncoding.ToUpper();
268 if (subsEncoding.StartsWith("UCS", 0))
270 r = subsEncoding.Replace("UCS", "UTF");
271 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to open ICU converter", GetErrorMessage(r));
273 r = subsEncoding.Replace("4", "32");
274 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to open ICU converter", GetErrorMessage(r));
276 size_t retLength = wcstombs(pEncoding.get(), subsEncoding.GetPointer(), subsEncoding.GetLength());
277 SysTryReturn(NID_TEXT, (retLength > 0), null, E_SYSTEM, "[%s] Unable to convert encoding string to multi byte char array", GetErrorMessage(E_SYSTEM));
279 pEncoding[retLength] = '\0';
281 pEncodingCore->__pEncoder = ucnv_open(pEncoding.get(), &err);
285 r = pEncodingCore->GetResultFromIcuErrorCode(err);
286 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to open ICU converter", GetErrorMessage(r));
288 ucnv_setFromUCallBack(pEncodingCore->__pEncoder, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, &err);
289 ucnv_setToUCallBack(pEncodingCore->__pEncoder, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, NULL, &err);
291 pEncodingCore->_encodingFrom = encodingFrom;
292 pEncodingCore->_encodingTo = L"WCHAR_T";
294 SetLastResult(E_SUCCESS);
295 return pEncodingCore.release();
299 _IcuEncodingCore::GetName(void)
301 UErrorCode err = U_ZERO_ERROR;
302 const char* pName = ucnv_getName(__pEncoder, &err);
305 return String(pName);
312 _IcuEncodingCore::GetByteCount(const wchar_t* pSrc, int srcLength, int& retLength)
314 return __Encode(pSrc, srcLength, null, 0, retLength);
318 _IcuEncodingCore::GetCharCount(const byte* pSrc, int srcLength, int& retLength)
320 return __Decode(pSrc, srcLength, null, 0, retLength);
324 _IcuEncodingCore::EncodeN(const wchar_t* pSrc, int srcLength, int& retLength)
326 int maxDestLen = UCNV_GET_MAX_BYTES_FOR_STRING(srcLength * 2, ucnv_getMaxCharSize(__pEncoder));
327 std::unique_ptr<byte[]> pByte(new (std::nothrow) byte[maxDestLen]);
328 SysTryReturn(NID_TEXT, pByte, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
330 result r = __Encode(pSrc, srcLength, pByte.get(), maxDestLen, retLength);
331 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Encode operation failed", GetErrorMessage(r));
333 SetLastResult(E_SUCCESS);
334 return pByte.release();
338 _IcuEncodingCore::DecodeN(const byte* pSrc, int srcLength, int& retLength)
340 int maxDestLen = srcLength * 2;
341 std::unique_ptr<wchar_t[]> pWchar(new (std::nothrow) wchar_t[maxDestLen]);
342 SysTryReturn(NID_TEXT, pWchar, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
344 result r = __Decode(pSrc, srcLength, pWchar.get(), maxDestLen, retLength);
345 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Encode operation failed", GetErrorMessage(r));
347 SetLastResult(E_SUCCESS);
348 return pWchar.release();
352 _IcuEncodingCore::GetMaxByteCount(int charCount) const
354 return charCount * (ucnv_getMaxCharSize(__pEncoder));
358 _IcuEncodingCore::GetMaxCharCount(int byteCount) const
360 return byteCount / (ucnv_getMinCharSize(__pEncoder));
364 _IcuEncodingCore::GetAvailableEncodingsN(IList* pEncodingList)
366 SysTryReturnResult(NID_TEXT, pEncodingList, E_INVALID_ARG, "[%s] Invalid argument is used.Input encoding list is null", GetErrorMessage(E_INVALID_ARG));
368 result r = E_SUCCESS;
369 int count = ucnv_countAvailable();
370 SysTryReturnResult(NID_TEXT, count > 0, E_SYSTEM, "[%s] Unable to get available encoding list count.", GetErrorMessage(E_SYSTEM));
372 String* pEncodingStr = null;
373 for (int i = 0; i < count; i++)
375 pEncodingStr = new (std::nothrow) String(ucnv_getAvailableName(i));
376 SysTryReturnResult(NID_TEXT, pEncodingStr, E_OUT_OF_MEMORY, "[%s] Memory allocationfailed", GetErrorMessage(E_OUT_OF_MEMORY));
378 r = pEncodingList->Add(*pEncodingStr);
386 for (int i = 0; i < EXTRA_ENCODINGS_LENGTH; i++)
388 pEncodingStr = new (std::nothrow) String(extraEncodings[i]);
389 SysTryReturnResult(NID_TEXT, pEncodingStr, E_OUT_OF_MEMORY, "[%s] Memory allocationfailed", GetErrorMessage(E_OUT_OF_MEMORY));
391 r = pEncodingList->Add(*pEncodingStr);
403 _IcuEncodingCore::GetResultFromIcuErrorCode(UErrorCode& err)
405 result r = E_SUCCESS;
410 case U_MEMORY_ALLOCATION_ERROR:
416 case U_INDEX_OUTOFBOUNDS_ERROR:
422 case U_TRUNCATED_CHAR_FOUND:
423 // fall through to U_INVALID_CHAR_FOUND
424 case U_INVALID_CHAR_FOUND:
425 // fall through to U_ILLEGAL_CHAR_FOUND
426 case U_ILLEGAL_CHAR_FOUND:
428 r = E_INVALID_ENCODING_RANGE;
432 case U_INVALID_TABLE_FORMAT:
438 case U_BUFFER_OVERFLOW_ERROR:
444 case U_STRING_NOT_TERMINATED_WARNING:
450 case U_ILLEGAL_ARGUMENT_ERROR:
456 case U_FILE_ACCESS_ERROR:
457 // fall through to U_AMBIGUOUS_ALIAS_WARNING
458 case U_AMBIGUOUS_ALIAS_WARNING:
460 r = E_UNSUPPORTED_TYPE;
475 _IcuEncodingCore::GetIcuUcharN(const Tizen::Base::String& ospString, result& r)
477 UErrorCode err = U_ZERO_ERROR;
479 int srcLength = ospString.GetLength();
480 std::unique_ptr<IcuUChar> pIcuStr(new (std::nothrow) IcuUChar(srcLength + 2));
481 SysTryReturn(NID_TEXT, pIcuStr != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
483 pIcuStr.reset(u_strFromWCS(
487 ospString.GetPointer(),
492 r = GetResultFromIcuErrorCode(err);
493 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Error in converting osp string to ICU UChar", GetErrorMessage(r));
495 return pIcuStr.release();