Merge "Fix prevent defect on Text." into tizen_2.2
[platform/framework/native/appfw.git] / src / text / FText_Iso885916EncodingCore.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_Iso885916EncodingCore.cpp
19  * @brief               This is the implementation file for _Iso885916EncodingCore class.
20  */
21
22 // Includes
23 #include <unique_ptr.h>
24 #include <FBaseSysLog.h>
25 #include "FText_Iso885916EncodingCore.h"
26
27
28 using namespace Tizen::Base;
29
30 namespace Tizen { namespace Text
31 {
32
33 static const wchar_t ISO_8859_16_UNICODE_TABLE[] =
34 {
35         0x00A0, 0x0104, 0x0105, 0x0141, 0x20AC, 0x201E, 0x0160, 0x00A7,
36         0x0161, 0x00A9, 0x0218, 0x00AB, 0x0179, 0x00AD, 0x017A, 0x017B,
37         0x00B0, 0x00B1, 0x010C, 0x0142, 0x017D, 0x201D, 0x00B6, 0x00B7,
38         0x017E, 0x010D, 0x0219, 0x00BB, 0x0152, 0x0153, 0x0178, 0x017C,
39         0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0106, 0x00C6, 0x00C7,
40         0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
41         0x0110, 0x0143, 0x00D2, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x015A,
42         0x0170, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0118, 0x021A, 0x00DF,
43         0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x0107, 0x00E6, 0x00E7,
44         0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
45         0x0111, 0x0144, 0x00F2, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x015B,
46         0x0171, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0119, 0x021B, 0x00FF
47 };
48
49
50 _Iso885916EncodingCore::_Iso885916EncodingCore(void)
51 {
52 }
53
54
55 _Iso885916EncodingCore::~_Iso885916EncodingCore(void)
56 {
57 }
58
59 _EncodingCore*
60 _Iso885916EncodingCore::GetEncodingCoreImplN(const Tizen::Base::String& encodingFrom, const Tizen::Base::String& encodingTo)
61 {
62         SysTryReturn(NID_TEXT, encodingFrom == L"ISO-8859-16", null, E_UNSUPPORTED_TYPE, "[E_UNSUPPORTED_TYPE] It is not the ISO-8859-16 type.");
63         _Iso885916EncodingCore* pEncodingCore = new (std::nothrow) _Iso885916EncodingCore;
64         SysTryReturn(NID_TEXT, pEncodingCore, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
65         return pEncodingCore;
66 }
67
68
69 String
70 _Iso885916EncodingCore::GetName(void)
71 {
72         return String(L"ISO-8859-16");
73 }
74
75 result
76 _Iso885916EncodingCore::GetByteCount(const wchar_t* pSrc, int srcLength, int& retLength)
77 {
78         retLength = -1;
79         wchar_t* pUnicodeStr = (wchar_t*) pSrc;
80         if (pUnicodeStr)
81         {
82                 int iso8859_16Size = srcLength;
83                 while (srcLength > 0)
84                 {
85                         if ((*pUnicodeStr) > 0x00A0)
86                         {
87                                 if (((*pUnicodeStr) > 0xFFFF))
88                                 {
89                                         return E_INVALID_ENCODING_RANGE;
90                                 }
91
92                                 if (!(*pUnicodeStr & 0xFF00))
93                                 {
94                                         int tableSize = sizeof(ISO_8859_16_UNICODE_TABLE) / sizeof(ISO_8859_16_UNICODE_TABLE[0]);
95                                         SysTryReturn(NID_TEXT, *pUnicodeStr - 0xA0 < tableSize, E_INVALID_ENCODING_RANGE, E_INVALID_ENCODING_RANGE,
96                                                 "[E_INVALID_ENCODING_RANGE] It is an invalid byte.");
97
98                                         if (ISO_8859_16_UNICODE_TABLE[*pUnicodeStr - 0xA0] != *pUnicodeStr)
99                                         {
100                                                 return E_INVALID_ENCODING_RANGE;
101                                         }
102                                 }
103                                 else if (!(*pUnicodeStr & 0xFE80))
104                                 {
105                                         bool invalid = true;
106                                         for (int i = 0; i <= 0x5F; i++)
107                                         {
108                                                 if (ISO_8859_16_UNICODE_TABLE[i] == *pUnicodeStr)
109                                                 {
110                                                         invalid = false;
111                                                         break;
112                                                 }
113                                         }
114                                         // check for invalid values
115                                         if (invalid)
116                                         {
117                                                 return E_INVALID_ENCODING_RANGE;
118                                         }
119                                 }
120                                 else if (!(*pUnicodeStr & 0xFDE0))
121                                 {
122                                         if ((*pUnicodeStr == 0x0218) || (*pUnicodeStr == 0x0219) || (*pUnicodeStr == 0x021A) ||
123                                                 (*pUnicodeStr == 0x021B))
124                                         {
125                                                 // empty statement
126                                         }
127                                         else
128                                         {
129                                                 return E_INVALID_ENCODING_RANGE;
130                                         }
131                                 }
132                                 else if (!(*pUnicodeStr & 0xDF40))
133                                 {
134                                         if ((*pUnicodeStr == 0x201D) || (*pUnicodeStr == 0x201E) || (*pUnicodeStr == 0x20AC))
135                                         {
136                                                 // empty statement
137                                         }
138                                         else
139                                         {
140                                                 return E_INVALID_ENCODING_RANGE;
141                                         }
142                                 }
143                                 else
144                                 {
145                                         return E_INVALID_ENCODING_RANGE;
146                                 }
147                         }
148                         pUnicodeStr++;
149                         srcLength--;
150                 }
151                 retLength = iso8859_16Size;
152                 return E_SUCCESS;
153         }
154
155         return E_INVALID_ARG;
156 }
157
158 result
159 _Iso885916EncodingCore::GetCharCount(const byte* pSrc, int srcLength, int& retLength)
160 {
161         retLength = -1;
162         SysTryReturnResult(NID_TEXT, pSrc, E_INVALID_ARG,
163                         "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
164         retLength = srcLength;
165         return E_SUCCESS;
166 }
167
168 byte*
169 _Iso885916EncodingCore::EncodeN(const wchar_t* pSrc, int srcLength, int& retLength)
170 {
171         wchar_t* pUnicodeStr = (wchar_t*) pSrc;
172         result r = GetByteCount(pUnicodeStr, srcLength, retLength);
173         SysTryReturn(NID_TEXT, retLength > 0, null, r, "[%s] Encoding Failed", GetErrorMessage(r));
174
175         std::unique_ptr<byte[]> pIso8859_16Byte(new (std::nothrow) byte[retLength + 1]);
176         SysTryReturn(NID_TEXT, pIso8859_16Byte, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
177
178         byte* pCurrPos = pIso8859_16Byte.get();
179         while (srcLength > 0)
180         {
181                 if ((*pUnicodeStr) <= 0x00FF)
182                 {
183                         *pCurrPos = (byte) * pUnicodeStr;
184                 }
185                 else if (!(*pUnicodeStr & 0xFE80))
186                 {
187                         for (int i = 0; i <= 0x5F; i++)
188                         {
189                                 if (ISO_8859_16_UNICODE_TABLE[i] == *pUnicodeStr)
190                                 {
191                                         *pCurrPos = (byte) (i + 0xA0);
192                                         break;
193                                 }
194                         }
195                 }
196                 else if (!(*pUnicodeStr & 0xFDE0))
197                 {
198                         if (*pUnicodeStr == 0x0218)
199                         {
200                                 *pCurrPos = 0xAA;
201                         }
202                         else if (*pUnicodeStr == 0x0219)
203                         {
204                                 *pCurrPos = 0xBA;
205                         }
206                         else if (*pUnicodeStr == 0x021A)
207                         {
208                                 *pCurrPos = 0xDE;
209                         }
210                         else if (*pUnicodeStr == 0x021B)
211                         {
212                                 *pCurrPos = 0xFE;
213                         }
214                         else
215                         {
216                                 return null;
217                         }
218                 }
219                 else if (!(*pUnicodeStr & 0xDF40))
220                 {
221                         if (*pUnicodeStr == 0x201D)
222                         {
223                                 *pCurrPos = 0xB5;
224                         }
225                         else if (*pUnicodeStr == 0x201E)
226                         {
227                                 *pCurrPos = 0xA5;
228                         }
229                         else if (*pUnicodeStr == 0x20AC)
230                         {
231                                 *pCurrPos = 0xA4;
232                         }
233                         else
234                         {
235                                 return null;
236                         }
237                 }
238                 else
239                 {
240                         return null;
241                 }
242
243                 pCurrPos++;
244                 pUnicodeStr++;
245                 srcLength--;
246         }
247
248         SetLastResult(E_SUCCESS);
249         return pIso8859_16Byte.release();
250 }
251
252 wchar_t*
253 _Iso885916EncodingCore::DecodeN(const byte* pSrc, int srcLength, int& retLength)
254 {
255         byte* pIso8859_16Byte = (byte*) pSrc;
256         result r = GetCharCount(pIso8859_16Byte, srcLength, retLength);
257         SysTryReturn(NID_TEXT, retLength > 0, null, r, "[%s] Encoding Failed", GetErrorMessage(r));
258
259         std::unique_ptr<wchar_t[]> pUnicodeStr( new (std::nothrow) wchar_t[retLength + 1]);
260         SysTryReturn(NID_TEXT, pUnicodeStr, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
261
262         wchar_t* pCurrPos = pUnicodeStr.get();
263         while (srcLength > 0)
264         {
265                 if ((*pIso8859_16Byte) <= 0xA0)
266                 {
267                         *pCurrPos = (unsigned short) *pIso8859_16Byte;
268                 }
269                 // added following check to resolved c+=test issue, this check will always be true if the above condition is false
270                 else if ((*pIso8859_16Byte) <= 0xFF)
271                 {
272                         *pCurrPos = ISO_8859_16_UNICODE_TABLE[*pIso8859_16Byte - 0xA0];
273                 }
274                 pCurrPos++;
275                 pIso8859_16Byte++;
276                 srcLength--;
277         }
278
279         pUnicodeStr[retLength] = '\0';
280         SetLastResult(E_SUCCESS);
281         return pUnicodeStr.release();
282 }
283
284 int
285 _Iso885916EncodingCore::GetMaxByteCount(int charCount) const
286 {
287         return charCount;
288 }
289
290 int
291 _Iso885916EncodingCore::GetMaxCharCount(int byteCount) const
292 {
293         return byteCount;
294 }
295
296 } } // Tizen::Text