Merge "Use atomic operation for Reference counting" into tizen_2.1
[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 the unsupported 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                                         if (ISO_8859_16_UNICODE_TABLE[*pUnicodeStr - 0xA0] != *pUnicodeStr)
95                                         {
96                                                 return E_INVALID_ENCODING_RANGE;
97                                         }
98                                 }
99                                 else if (!(*pUnicodeStr & 0xFE80))
100                                 {
101                                         bool invalid = true;
102                                         for (int i = 0; i <= 0x5F; i++)
103                                         {
104                                                 if (ISO_8859_16_UNICODE_TABLE[i] == *pUnicodeStr)
105                                                 {
106                                                         invalid = false;
107                                                         break;
108                                                 }
109                                         }
110                                         // check for invalid values
111                                         if (invalid)
112                                         {
113                                                 return E_INVALID_ENCODING_RANGE;
114                                         }
115                                 }
116                                 else if (!(*pUnicodeStr & 0xFDE0))
117                                 {
118                                         if ((*pUnicodeStr == 0x0218) || (*pUnicodeStr == 0x0219) || (*pUnicodeStr == 0x021A) ||
119                                                 (*pUnicodeStr == 0x021B))
120                                         {
121                                                 // empty statement
122                                         }
123                                         else
124                                         {
125                                                 return E_INVALID_ENCODING_RANGE;
126                                         }
127                                 }
128                                 else if (!(*pUnicodeStr & 0xDF40))
129                                 {
130                                         if ((*pUnicodeStr == 0x201D) || (*pUnicodeStr == 0x201E) || (*pUnicodeStr == 0x20AC))
131                                         {
132                                                 // empty statement
133                                         }
134                                         else
135                                         {
136                                                 return E_INVALID_ENCODING_RANGE;
137                                         }
138                                 }
139                                 else
140                                 {
141                                         return E_INVALID_ENCODING_RANGE;
142                                 }
143                         }
144                         pUnicodeStr++;
145                         srcLength--;
146                 }
147                 retLength = iso8859_16Size;
148                 return E_SUCCESS;
149         }
150
151         return E_INVALID_ARG;
152 }
153
154 result
155 _Iso885916EncodingCore::GetCharCount(const byte* pSrc, int srcLength, int& retLength)
156 {
157         retLength = -1;
158         SysTryReturnResult(NID_TEXT, pSrc, E_INVALID_ARG,
159                         "[%s] Invalid argument is used. Input buffer pSrc is null.", GetErrorMessage(E_INVALID_ARG));
160         retLength = srcLength;
161         return E_SUCCESS;
162 }
163
164 byte*
165 _Iso885916EncodingCore::EncodeN(const wchar_t* pSrc, int srcLength, int& retLength)
166 {
167         wchar_t* pUnicodeStr = (wchar_t*) pSrc;
168         result r = GetByteCount(pUnicodeStr, srcLength, retLength);
169         SysTryReturn(NID_TEXT, retLength > 0, null, r, "[%s] Encoding Failed", GetErrorMessage(r));
170
171         std::unique_ptr<byte[]> pIso8859_16Byte(new (std::nothrow) byte[retLength + 1]);
172         SysTryReturn(NID_TEXT, pIso8859_16Byte, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
173
174         byte* pCurrPos = pIso8859_16Byte.get();
175         while (srcLength > 0)
176         {
177                 if ((*pUnicodeStr) <= 0x00FF)
178                 {
179                         *pCurrPos = (byte) * pUnicodeStr;
180                 }
181                 else if (!(*pUnicodeStr & 0xFE80))
182                 {
183                         for (int i = 0; i <= 0x5F; i++)
184                         {
185                                 if (ISO_8859_16_UNICODE_TABLE[i] == *pUnicodeStr)
186                                 {
187                                         *pCurrPos = (byte) (i + 0xA0);
188                                         break;
189                                 }
190                         }
191                 }
192                 else if (!(*pUnicodeStr & 0xFDE0))
193                 {
194                         if (*pUnicodeStr == 0x0218)
195                         {
196                                 *pCurrPos = 0xAA;
197                         }
198                         else if (*pUnicodeStr == 0x0219)
199                         {
200                                 *pCurrPos = 0xBA;
201                         }
202                         else if (*pUnicodeStr == 0x021A)
203                         {
204                                 *pCurrPos = 0xDE;
205                         }
206                         else if (*pUnicodeStr == 0x021B)
207                         {
208                                 *pCurrPos = 0xFE;
209                         }
210                         else
211                         {
212                                 return null;
213                         }
214                 }
215                 else if (!(*pUnicodeStr & 0xDF40))
216                 {
217                         if (*pUnicodeStr == 0x201D)
218                         {
219                                 *pCurrPos = 0xB5;
220                         }
221                         else if (*pUnicodeStr == 0x201E)
222                         {
223                                 *pCurrPos = 0xA5;
224                         }
225                         else if (*pUnicodeStr == 0x20AC)
226                         {
227                                 *pCurrPos = 0xA4;
228                         }
229                         else
230                         {
231                                 return null;
232                         }
233                 }
234                 else
235                 {
236                         return null;
237                 }
238
239                 pCurrPos++;
240                 pUnicodeStr++;
241                 srcLength--;
242         }
243
244         SetLastResult(E_SUCCESS);
245         return pIso8859_16Byte.release();
246 }
247
248 wchar_t*
249 _Iso885916EncodingCore::DecodeN(const byte* pSrc, int srcLength, int& retLength)
250 {
251         byte* pIso8859_16Byte = (byte*) pSrc;
252         result r = GetCharCount(pIso8859_16Byte, srcLength, retLength);
253         SysTryReturn(NID_TEXT, retLength > 0, null, r, "[%s] Encoding Failed", GetErrorMessage(r));
254
255         std::unique_ptr<wchar_t[]> pUnicodeStr( new (std::nothrow) wchar_t[retLength + 1]);
256         SysTryReturn(NID_TEXT, pUnicodeStr, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
257
258         wchar_t* pCurrPos = pUnicodeStr.get();
259         while (srcLength > 0)
260         {
261                 if ((*pIso8859_16Byte) <= 0xA0)
262                 {
263                         *pCurrPos = (unsigned short) *pIso8859_16Byte;
264                 }
265                 // added following check to resolved c+=test issue, this check will always be true if the above condition is false
266                 else if ((*pIso8859_16Byte) <= 0xFF)
267                 {
268                         *pCurrPos = ISO_8859_16_UNICODE_TABLE[*pIso8859_16Byte - 0xA0];
269                 }
270                 pCurrPos++;
271                 pIso8859_16Byte++;
272                 srcLength--;
273         }
274
275         pUnicodeStr[retLength] = '\0';
276         SetLastResult(E_SUCCESS);
277         return pUnicodeStr.release();
278 }
279
280 int
281 _Iso885916EncodingCore::GetMaxByteCount(int charCount) const
282 {
283         return charCount;
284 }
285
286 int
287 _Iso885916EncodingCore::GetMaxCharCount(int byteCount) const
288 {
289         return byteCount;
290 }
291
292 } } // Tizen::Text