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