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 #define EXTRA_ENCODINGS_LENGTH 3
34 static String extraEncodings[] = {
35 "UCS4", "UCS4BE", "UCS4LE"
38 namespace Tizen { namespace Text
41 _IcuEncodingCore::_IcuEncodingCore(void)
46 _IcuEncodingCore::~_IcuEncodingCore(void)
50 ucnv_close(__pEncoder);
56 _IcuEncodingCore::__Encode(const wchar_t* pSrc, int srcLength, byte* pDst, int dstLength, int& retLength)
58 SysTryReturnResult(NID_TEXT, pSrc, E_INVALID_ARG,
59 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
60 SysTryReturnResult(NID_TEXT, srcLength >= 0, E_INVALID_ARG,
61 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
63 UErrorCode err = U_ZERO_ERROR;
65 int icuStrLen = srcLength * 2;
67 result r = E_OUT_OF_MEMORY;
68 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
71 IcuUChar* pIcuStr1 = u_strFromWCS(pIcuStr, icuStrLen, &outLen, pSrc, srcLength, &err);
76 retLength = ucnv_fromUChars(__pEncoder, (char*) pDst, dstLength, pIcuStr1, outLen, &err);
80 retLength = ucnv_fromUChars(__pEncoder, null, 0, pIcuStr1, outLen, &err);
81 if (err == U_BUFFER_OVERFLOW_ERROR)
92 r = GetResultFromIcuErrorCode(err);
100 _IcuEncodingCore::__Decode(const byte* pSrc, int srcLength, wchar_t* pDst, int dstLength, int& retLength)
102 SysTryReturnResult(NID_TEXT, pSrc, E_INVALID_ARG,
103 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
104 SysTryReturnResult(NID_TEXT, srcLength >= 0, E_INVALID_ARG,
105 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
107 bool isCallForCharCount = (pDst == null);
108 if (isCallForCharCount)
110 dstLength = srcLength * 2;
111 pDst = new (std::nothrow) wchar_t[dstLength];
112 SysTryReturnResult(NID_TEXT, pDst, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
115 UErrorCode err = U_ZERO_ERROR;
116 int icuStrLen = dstLength * 2;
117 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
120 retLength = ucnv_toUChars(__pEncoder, pIcuStr, icuStrLen, (const char*) pSrc, srcLength, &err);
123 pDst = u_strToWCS(pDst, dstLength, &retLength, pIcuStr, retLength, &err);
128 if (isCallForCharCount)
139 return GetResultFromIcuErrorCode(err);
143 _IcuEncodingCore::EncodeExN(const wchar_t* pSrc, int srcLength, int& retLength, bool flush)
145 SysTryReturn(NID_TEXT, pSrc, null, E_INVALID_ARG,
146 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
147 SysTryReturn(NID_TEXT, srcLength >= 0, null, E_INVALID_ARG,
148 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
150 result r = E_SUCCESS;
151 UErrorCode err = U_ZERO_ERROR;
155 int icuStrLen = srcLength * 2;
156 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
157 SysTryCatch(NID_TEXT, pIcuStr, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
159 pIcuStr = u_strFromWCS(pIcuStr, icuStrLen, &outLen, pSrc, srcLength, &err);
160 r = GetResultFromIcuErrorCode(err);
163 int maxDestLen = UCNV_GET_MAX_BYTES_FOR_STRING(outLen, ucnv_getMaxCharSize(__pEncoder));
164 pDst = new (std::nothrow) byte[maxDestLen];
167 char* pDstArray = (char*) pDst;
168 const char* pDstLimit = pDstArray + maxDestLen;
169 const IcuUChar* pSrcArray = pIcuStr;
170 const IcuUChar* pSrcLimit = pIcuStr + outLen;
173 ucnv_fromUnicode(__pEncoder, &pDstArray, pDstLimit, &pSrcArray, pSrcLimit, null, flush, &err);
174 r = GetResultFromIcuErrorCode(err);
177 retLength = (byte*) pDstArray - pDst;
180 SetLastResult(E_SUCCESS);
195 _IcuEncodingCore::DecodeExN(const byte* pSrc, int srcLength, int& retLength, bool flush)
197 SysTryReturn(NID_TEXT, pSrc, null, E_INVALID_ARG,
198 "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
199 SysTryReturn(NID_TEXT, srcLength >= 0, null, E_INVALID_ARG,
200 "[%s] Invalid argument is used. srcLength(%d) can not be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
202 UErrorCode err = U_ZERO_ERROR;
203 int icuStrLen = srcLength * 2;
204 IcuUChar* pIcuStr = new (std::nothrow) IcuUChar[icuStrLen];
205 SysTryReturn(NID_TEXT, pIcuStr, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
207 IcuUChar* pDstArray = pIcuStr;
208 const IcuUChar* pDstLimit = pIcuStr + icuStrLen;
209 const char* pSrcArray = (const char*) pSrc;
210 const char* pSrcLimit = pSrcArray + srcLength;
212 result r = E_SUCCESS;
213 wchar_t* pDst = null;
216 ucnv_toUnicode(__pEncoder, &pDstArray, pDstLimit, &pSrcArray, pSrcLimit, null, flush, &err);
217 r = GetResultFromIcuErrorCode(err);
221 int dstLength = pDstArray - pIcuStr;
222 pDst = new (std::nothrow) wchar_t[dstLength + 1];
223 SysTryCatch(NID_TEXT, pDst, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
224 pDst[dstLength] = '\0';
226 pDst = u_strToWCS(pDst, dstLength, &retLength, pIcuStr, dstLength, &err);
227 r = GetResultFromIcuErrorCode(err);
228 SysTryCatch(NID_TEXT, !IsFailed(r), , r, "Decoding failed");
231 SetLastResult(E_SUCCESS);
244 _IcuEncodingCore::GetEncodingCoreImplN(const Tizen::Base::String& encodingFrom, const Tizen::Base::String& encodingTo)
246 result r = E_SUCCESS;
247 UErrorCode err = U_ZERO_ERROR;
248 std::unique_ptr<_IcuEncodingCore> pEncodingCore(null);
250 int lenEncoding = encodingFrom.GetLength();
251 std::unique_ptr<char[]> pEncoding(new (std::nothrow) char[lenEncoding + 2]);
252 SysTryReturn(NID_TEXT, (pEncoding != null), null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
254 size_t retLength = wcstombs(pEncoding.get(), encodingFrom.GetPointer(), lenEncoding);
255 SysTryReturn(NID_TEXT, (retLength > 0), null, E_SYSTEM, "[%s] Unable to convert encoding string to multi byte char array", GetErrorMessage(E_SYSTEM));
257 *(pEncoding.get() + retLength) = '\0';
259 pEncodingCore.reset(new (std::nothrow) _IcuEncodingCore);
260 SysTryReturn(NID_TEXT, (pEncodingCore != null), null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
262 pEncodingCore->__pEncoder = ucnv_open(pEncoding.get(), &err);
265 String subsEncoding(encodingFrom);
266 subsEncoding.ToUpper();
267 if (subsEncoding.StartsWith("UCS", 0))
269 r = subsEncoding.Replace("UCS", "UTF");
270 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to open ICU converter", GetErrorMessage(r));
272 r = subsEncoding.Replace("4", "32");
273 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to open ICU converter", GetErrorMessage(r));
275 size_t retLength = wcstombs(pEncoding.get(), subsEncoding.GetPointer(), subsEncoding.GetLength());
276 SysTryReturn(NID_TEXT, (retLength > 0), null, E_SYSTEM, "[%s] Unable to convert encoding string to multi byte char array", GetErrorMessage(E_SYSTEM));
278 pEncoding[retLength] = '\0';
280 pEncodingCore->__pEncoder = ucnv_open(pEncoding.get(), &err);
284 r = pEncodingCore->GetResultFromIcuErrorCode(err);
285 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to open ICU converter", GetErrorMessage(r));
287 ucnv_setFromUCallBack(pEncodingCore->__pEncoder, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, &err);
288 ucnv_setToUCallBack(pEncodingCore->__pEncoder, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, NULL, &err);
290 pEncodingCore->_encodingFrom = encodingFrom;
291 pEncodingCore->_encodingTo = L"WCHAR_T";
293 SetLastResult(E_SUCCESS);
294 return pEncodingCore.release();
298 _IcuEncodingCore::GetName(void)
300 UErrorCode err = U_ZERO_ERROR;
301 const char* pName = ucnv_getName(__pEncoder, &err);
304 return String(pName);
311 _IcuEncodingCore::GetByteCount(const wchar_t* pSrc, int srcLength, int& retLength)
313 return __Encode(pSrc, srcLength, null, 0, retLength);
317 _IcuEncodingCore::GetCharCount(const byte* pSrc, int srcLength, int& retLength)
319 return __Decode(pSrc, srcLength, null, 0, retLength);
323 _IcuEncodingCore::EncodeN(const wchar_t* pSrc, int srcLength, int& retLength)
325 int maxDestLen = UCNV_GET_MAX_BYTES_FOR_STRING(srcLength * 2, ucnv_getMaxCharSize(__pEncoder));
326 std::unique_ptr<byte[]> pByte(new (std::nothrow) byte[maxDestLen]);
327 SysTryReturn(NID_TEXT, pByte, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
329 result r = __Encode(pSrc, srcLength, pByte.get(), maxDestLen, retLength);
330 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Encode operation failed", GetErrorMessage(r));
332 SetLastResult(E_SUCCESS);
333 return pByte.release();
337 _IcuEncodingCore::DecodeN(const byte* pSrc, int srcLength, int& retLength)
339 int maxDestLen = srcLength * 2;
340 std::unique_ptr<wchar_t[]> pWchar(new (std::nothrow) wchar_t[maxDestLen]);
341 SysTryReturn(NID_TEXT, pWchar, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
343 result r = __Decode(pSrc, srcLength, pWchar.get(), maxDestLen, retLength);
344 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Encode operation failed", GetErrorMessage(r));
346 SetLastResult(E_SUCCESS);
347 return pWchar.release();
351 _IcuEncodingCore::GetMaxByteCount(int charCount) const
353 return charCount * (ucnv_getMaxCharSize(__pEncoder));
357 _IcuEncodingCore::GetMaxCharCount(int byteCount) const
359 return byteCount / (ucnv_getMinCharSize(__pEncoder));
364 _IcuEncodingCore::GetResultFromIcuErrorCode(UErrorCode& err)
366 result r = E_SUCCESS;
371 case U_MEMORY_ALLOCATION_ERROR:
377 case U_INDEX_OUTOFBOUNDS_ERROR:
383 case U_TRUNCATED_CHAR_FOUND:
384 // fall through to U_INVALID_CHAR_FOUND
385 case U_INVALID_CHAR_FOUND:
386 // fall through to U_ILLEGAL_CHAR_FOUND
387 case U_ILLEGAL_CHAR_FOUND:
389 r = E_INVALID_ENCODING_RANGE;
393 case U_INVALID_TABLE_FORMAT:
399 case U_BUFFER_OVERFLOW_ERROR:
405 case U_STRING_NOT_TERMINATED_WARNING:
411 case U_ILLEGAL_ARGUMENT_ERROR:
417 case U_FILE_ACCESS_ERROR:
418 // fall through to U_AMBIGUOUS_ALIAS_WARNING
419 case U_AMBIGUOUS_ALIAS_WARNING:
421 r = E_UNSUPPORTED_TYPE;
436 _IcuEncodingCore::GetIcuUcharN(const Tizen::Base::String& ospString, result& r)
438 UErrorCode err = U_ZERO_ERROR;
440 int srcLength = ospString.GetLength();
441 std::unique_ptr<IcuUChar> pIcuStr(new (std::nothrow) IcuUChar(srcLength + 2));
442 SysTryReturn(NID_TEXT, pIcuStr != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
444 pIcuStr.reset(u_strFromWCS(
448 ospString.GetPointer(),
453 r = GetResultFromIcuErrorCode(err);
454 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Error in converting osp string to ICU UChar", GetErrorMessage(r));
456 return pIcuStr.release();