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