Merge "Update code of system and text for reporting Klocwork." into tizen_2.2
[platform/framework/native/appfw.git] / src / text / FText_Ucs2EncodingCore.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                FText_Ucs2EncodingCore.cpp
19  * @brief               This is the implementation file for _Ucs2EncodingCore class.
20  */
21
22 // Includes
23 #include <unique_ptr.h>
24 #include <FBaseSysLog.h>
25 #include "FText_Ucs2EncodingCore.h"
26
27
28 using namespace Tizen::Base;
29
30 #define UCS2_BOM_SIZE 2
31
32 namespace Tizen { namespace Text
33 {
34
35 _Ucs2EncodingCore::_Ucs2EncodingCore(void)
36         : __encodingType(UCS2_ENCODING_BE)
37         , __bomType(UCS2_BOM_NONE)
38         , __encodingName("")
39 {
40 }
41
42
43 _Ucs2EncodingCore::~_Ucs2EncodingCore(void)
44 {
45 }
46
47 _EncodingCore*
48 _Ucs2EncodingCore::GetEncodingCoreImplN(const Tizen::Base::String& encodingFrom, const Tizen::Base::String& encodingTo)
49 {
50         String encodingStr(encodingFrom);
51         encodingStr.ToUpper();
52
53         encodingStr.Replace(L"-", "");
54         encodingStr.Replace("_", "");
55
56         SysTryReturn(NID_TEXT, encodingStr.StartsWith(L"UCS2", 0), null, E_UNSUPPORTED_TYPE, "[E_UNSUPPORTED_TYPE] It is not the UCS2 type.");
57
58         if ((encodingStr == "UCS2") || (encodingStr == "UCS2BE") || (encodingStr == "UCS2LE"))
59         {
60                 std::unique_ptr<_Ucs2EncodingCore> pEncodingCore(new (std::nothrow) _Ucs2EncodingCore);
61                 SysTryReturn(NID_TEXT, pEncodingCore, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
62
63                 if (encodingStr == "UCS2")
64                 {
65                         pEncodingCore->__encodingType = UCS2_ENCODING_LE; //UCS2_ENCODING;
66                 }
67
68                 if (encodingStr == "UCS2BE")
69                 {
70                         pEncodingCore->__encodingType = UCS2_ENCODING_BE;
71                 }
72
73                 if (encodingStr == "UCS2LE")
74                 {
75                         pEncodingCore->__encodingType = UCS2_ENCODING_LE;
76                 }
77
78                 pEncodingCore->__encodingName = encodingFrom;
79
80                 return pEncodingCore.release();
81         }
82
83         return null;
84 }
85
86
87 String
88 _Ucs2EncodingCore::GetName(void)
89 {
90         return __encodingName;
91 }
92
93 result
94 _Ucs2EncodingCore::GetByteCount(const wchar_t* pSrc, int srcLength, int& retLength)
95 {
96         retLength = -1;
97         wchar_t* pUnicodeStr = (wchar_t*) pSrc;
98         SysTryReturnResult(NID_TEXT, (pUnicodeStr != null), E_INVALID_ARG,
99                         "[%s] Invalid argument is used. Input string pSrc is null.", GetErrorMessage(E_INVALID_ARG));
100
101         int ucs2Size = srcLength * 2;
102         while (srcLength > 0)
103         {
104                 SysTryReturnResult(NID_TEXT, (*pUnicodeStr <= 0xFFFF), E_INVALID_ENCODING_RANGE,                                "[%s] Encoding failed. pSrc(%ls) contains code(%x) pointing outside of bounds by UCS2 encdoing.", GetErrorMessage(E_INVALID_ENCODING_RANGE), pSrc, *pUnicodeStr);
105                 SysTryReturnResult(NID_TEXT, (*pUnicodeStr < 0xD800 || *pUnicodeStr > 0xDFFF),
106                                                   E_INVALID_ENCODING_RANGE,
107                                 "[%s] Encoding failed. pSrc(%ls) contains code(%x) pointing outside of bounds by GSM encdoing.", GetErrorMessage(E_INVALID_ENCODING_RANGE), pSrc, *pUnicodeStr);
108
109                 srcLength--;
110                 pUnicodeStr++;
111         }
112
113         if (__encodingType == UCS2_ENCODING)
114         {
115                 ucs2Size += UCS2_BOM_SIZE;
116         }
117
118         retLength = ucs2Size;
119         return E_SUCCESS;
120 }
121
122 result
123 _Ucs2EncodingCore::GetCharCount(const byte* pSrc, int srcLength, int& retLength)
124 {
125         retLength = -1;
126         byte* pUcs2Byte = (byte*) pSrc;
127         if (pUcs2Byte != null)
128         {
129                 if (__encodingType == UCS2_ENCODING && srcLength > 2)
130                 {
131                         if ((pUcs2Byte[0] == 0xFE) && (pUcs2Byte[1] == 0xFF))
132                         {
133                                 __bomType = UCS2_BOM_BE;
134                                 srcLength -= 2;
135                                 pUcs2Byte += 2;
136                         }
137                         else if ((pUcs2Byte[0] == 0xFF) && (pUcs2Byte[1] == 0xFE))
138                         {
139                                 __bomType = UCS2_BOM_LE;
140                                 srcLength -= 2;
141                                 pUcs2Byte += 2;
142                         }
143                         else
144                         {
145                                 __bomType = UCS2_BOM_NONE;
146                         }
147                 }
148
149                 if ((srcLength == 0x01) && (pUcs2Byte[srcLength - 1] == '\0'))
150                 {
151                         retLength = 1;
152                         return E_SUCCESS;
153                 }
154
155                 if ((srcLength & 0x01) && (pUcs2Byte[srcLength - 1] != '\0'))
156                 {
157                         return E_INVALID_ENCODING_RANGE;
158                 }
159
160                 int uniSize = srcLength >> 1;
161                 while (srcLength > 0)
162                 {
163                         if (__encodingType == UCS2_ENCODING_BE || __bomType == UCS2_BOM_BE)
164                         {
165                                 if (!(*pUcs2Byte < 0xD8 || *pUcs2Byte > 0xDF))
166                                 {
167                                         return E_INVALID_ENCODING_RANGE;
168                                 }
169                                 pUcs2Byte += 2;
170                         }
171                         else
172                         {
173                                 pUcs2Byte++;
174                                 if (!(*pUcs2Byte < 0xD8 || *pUcs2Byte > 0xDF))
175                                 {
176                                         return E_INVALID_ENCODING_RANGE;
177                                 }
178                                 pUcs2Byte++;
179                         }
180                         srcLength -= 2;
181                 }
182
183                 retLength = uniSize;
184                 return E_SUCCESS;
185         }
186
187         return E_INVALID_ARG;
188 }
189
190 byte*
191 _Ucs2EncodingCore::EncodeN(const wchar_t* pSrc, int srcLength, int& retLength)
192 {
193         result r = GetByteCount(pSrc, srcLength, retLength);
194         SysTryReturn(NID_TEXT, retLength >= 0, null, r,
195                         "[%s] Encoding Failed. retLength(%d) can not be negative", GetErrorMessage(r), retLength);
196
197         std::unique_ptr<byte[]>pUcs2Byte(new (std::nothrow) byte[retLength + 1]);
198         SysTryReturn(NID_TEXT, pUcs2Byte, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
199
200         wchar_t* pUnicodeStr = (wchar_t*) pSrc;
201         byte* pCurrPos = pUcs2Byte.get();
202         if (__encodingType == UCS2_ENCODING)
203         {
204                 *pCurrPos = 0xFF;
205                 pCurrPos++;
206                 *pCurrPos = 0xFE;
207                 pCurrPos++;
208         }
209
210         if (__encodingType == UCS2_ENCODING_BE)
211         {
212                 while (srcLength > 0)
213                 {
214                         *pCurrPos = (byte) ((*pUnicodeStr & 0xFF00) >> 8);
215                         *(++pCurrPos) = (byte) (*pUnicodeStr & 0x00FF);
216
217                         pCurrPos++;
218                         pUnicodeStr++;
219                         srcLength--;
220                 }
221         }
222         else
223         {
224                 while (srcLength > 0)
225                 {
226                         *pCurrPos = (byte) (*pUnicodeStr & 0x00FF);
227                         *(++pCurrPos) = (byte) ((*pUnicodeStr & 0xFF00) >> 8);
228
229                         pCurrPos++;
230                         pUnicodeStr++;
231                         srcLength--;
232                 }
233         }
234
235         SetLastResult(E_SUCCESS);
236         return pUcs2Byte.release();
237 }
238
239 wchar_t*
240 _Ucs2EncodingCore::DecodeN(const byte* pSrc, int srcLength, int& retLength)
241 {
242         result r = GetCharCount(pSrc, srcLength, retLength);
243         SysTryReturn(NID_TEXT, retLength >= 0, null, r, "[%s] Encoding Failed", GetErrorMessage(r));
244
245         byte* pUcs2Byte = (byte*) pSrc;
246         std::unique_ptr<wchar_t[]> pUnicodeStr( new (std::nothrow) wchar_t[retLength + 1]);
247
248         SysTryReturn(NID_TEXT, pUnicodeStr, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
249
250         if (__encodingType == UCS2_ENCODING)
251         {
252                 if (__bomType != UCS2_BOM_NONE)
253                 {
254                         pUcs2Byte += 2;
255                         srcLength -= 2;
256                 }
257         }
258
259         wchar_t* pCurrPos = pUnicodeStr.get();
260         if (__encodingType == UCS2_ENCODING_BE || __bomType == UCS2_BOM_BE)
261         {
262                 while (srcLength > 0)
263                 {
264                         *pCurrPos = (((wchar_t) *pUcs2Byte) << 8);
265                         *pCurrPos = *pCurrPos | ((wchar_t) *(++pUcs2Byte));
266
267                         pCurrPos++;
268                         pUcs2Byte++;
269                         srcLength -= 2;
270                 }
271         }
272         else
273         {
274                 while (srcLength > 0)
275                 {
276                         *pCurrPos = ((wchar_t) *pUcs2Byte);
277                         *pCurrPos = *pCurrPos | (((wchar_t) *(++pUcs2Byte)) << 8);
278
279                         pCurrPos++;
280                         pUcs2Byte++;
281                         srcLength -= 2;
282                 }
283         }
284
285         pUnicodeStr[retLength] = '\0';
286         SetLastResult(E_SUCCESS);
287         __bomType = UCS2_BOM_NONE;
288         return pUnicodeStr.release();
289 }
290
291 int
292 _Ucs2EncodingCore::GetMaxByteCount(int charCount) const
293 {
294         return charCount * 2;
295 }
296
297 int
298 _Ucs2EncodingCore::GetMaxCharCount(int byteCount) const
299 {
300         return byteCount;
301 }
302
303 } } // Tizen::Text