2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FText_GsmEncodingCore.cpp
19 * @brief This is the implementation file for _GsmEncodingCore class.
23 #include <unique_ptr.h>
24 #include <FBaseSysLog.h>
25 #include "FText_GsmEncodingCore.h"
28 using namespace Tizen::Base;
30 namespace Tizen { namespace Text
41 #define GSM_TABLE_UNI_LENGTH 0x80
42 static const wchar_t GSM_UNICODE_TABLE[] =
44 0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC,
45 0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5,
46 0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8,
47 0x03A3, 0x0398, 0x039E, 0xFFFD, 0x00C6, 0x00E6, 0x00DF, 0x00C9,
48 0x0020, 0x0021, 0x0022, 0x0023, 0x00A4, 0x0025, 0x0026, 0x0027,
49 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
50 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
51 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
52 0x00A1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
53 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
54 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
55 0x0058, 0x0059, 0x005A, 0x00C4, 0x00D6, 0x00D1, 0x00DC, 0x00A7,
56 0x00BF, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
57 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
58 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
59 0x0078, 0x0079, 0x007A, 0x00E4, 0x00F6, 0x00F1, 0x00FC, 0x00E0
63 #define EXT_GSM_TABLE_1B_LENGTH 10
64 static const GsmUniTable GSM_UNICODE_TABLE_EXTENSION[] =
66 {0x0A, 0x000C}, {0x14, 0x005E}, {0x28, 0x007B}, {0x29, 0x007D}, {0x2F, 0x005C},
67 {0x3C, 0x005B}, {0x3D, 0x007E}, {0x3E, 0x005D}, {0x40, 0x007C}, {0x65, 0x20AC}
70 _GsmEncodingCore::_GsmEncodingCore(void)
75 _GsmEncodingCore::~_GsmEncodingCore(void)
80 _GsmEncodingCore::GetEncodingCoreImplN(const Tizen::Base::String& encodingFrom, const Tizen::Base::String& encodingTo)
82 SysTryReturn(NID_TEXT, encodingFrom == L"GSM", null, E_UNSUPPORTED_TYPE, "[E_UNSUPPORTED_TYPE] It is the unsupported type.");
83 _GsmEncodingCore* pEncoderDecoder = new (std::nothrow) _GsmEncodingCore;
84 SysTryReturn(NID_TEXT, pEncoderDecoder, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
85 return pEncoderDecoder;
90 _GsmEncodingCore::GetName(void)
92 return String(L"GSM");
96 _GsmEncodingCore::GetByteCount(const wchar_t* pSrc, int srcLength, int& retLength)
103 wchar_t* pUnicodeStr = (wchar_t*) pSrc;
104 while (srcLength > 0)
106 bool foundInExtTable = false;
107 SysTryReturnResult(NID_TEXT, (*pUnicodeStr != 0xFFFD), E_INVALID_ENCODING_RANGE,
108 "[%s] Encoding failed. pSrc(%ls) contains code(%x) pointing outside of bounds by GSM encdoing.", GetErrorMessage(E_INVALID_ENCODING_RANGE), pSrc, *pUnicodeStr);
109 SysTryReturnResult(NID_TEXT, (*pUnicodeStr <= 0x20AC), E_INVALID_ENCODING_RANGE,
110 "[%s] Encoding failed. pSrc(%ls) contains code(%x) pointing outside of bounds by GSM encdoing.", GetErrorMessage(E_INVALID_ENCODING_RANGE), pSrc, *pUnicodeStr);
112 if (*pUnicodeStr == '\0')
118 for (index = 0; index < EXT_GSM_TABLE_1B_LENGTH; index++)
120 if (*pUnicodeStr == GSM_UNICODE_TABLE_EXTENSION[index].unicode)
123 foundInExtTable = true;
127 if (!foundInExtTable)
129 bool foundInUniTable = false;
131 // 0x0020 - 0x005F, 0x0061 - 0x007E
132 if (*pUnicodeStr < 0x0020 || *pUnicodeStr > 0x007E || *pUnicodeStr == 0x0060)
134 for (index = 0; index < GSM_TABLE_UNI_LENGTH; index++)
136 if (*pUnicodeStr == GSM_UNICODE_TABLE[index])
138 foundInUniTable = true;
143 SysTryReturnResult(NID_TEXT, foundInUniTable, E_INVALID_ENCODING_RANGE,
144 "[%s] Encoding failed. String contains code pointing outside of bounds by GSM encdoing.", GetErrorMessage(E_INVALID_ENCODING_RANGE));
156 return E_INVALID_ARG;
160 _GsmEncodingCore::GetCharCount(const byte* pSrc, int srcLength, int& retLength)
167 byte* pGsmByte = (byte*) pSrc;
168 while (srcLength > 1)
170 SysTryReturnResult(NID_TEXT, not (*pGsmByte & 0x80), E_INVALID_ENCODING_RANGE,
171 "[%s] Encoding failed. String contains code pointing outside of bounds by GSM encdoing.", GetErrorMessage(E_INVALID_ENCODING_RANGE));
172 if (*pGsmByte == 0x1B)
174 bool foundInExtTable = false;
178 for (index = 0; index < EXT_GSM_TABLE_1B_LENGTH; index++)
180 if (*pGsmByte == GSM_UNICODE_TABLE_EXTENSION[index].gsm)
182 foundInExtTable = true;
186 SysTryReturnResult(NID_TEXT, foundInExtTable, E_INVALID_ENCODING_RANGE,
187 "[%s] Encoding failed. String contains code pointing outside of bounds by GSM encdoing.", GetErrorMessage(E_INVALID_ENCODING_RANGE));
196 SysTryReturnResult(NID_TEXT, not ((*pGsmByte & 0x80) || (*pGsmByte == 0x1B)), E_INVALID_ENCODING_RANGE,
197 "[%s] Encoding failed. String contains code pointing outside of bounds by GSM encdoing.", GetErrorMessage(E_INVALID_ENCODING_RANGE));
205 return E_INVALID_ARG;
209 _GsmEncodingCore::EncodeN(const wchar_t* pSrc, int srcLength, int& retLength)
211 result r = GetByteCount(pSrc, srcLength, retLength);
212 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Encoding failed", GetErrorMessage(r));
214 std::unique_ptr<byte[]> pDst(new (std::nothrow) byte[retLength + 1]);
215 SysTryReturn(NID_TEXT, pDst, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
217 wchar_t* pUnicodeStr = (wchar_t*) pSrc;
218 byte* pCurrPos = pDst.get();
220 while (srcLength > 0)
222 bool foundInUniTable = false;
223 if (*pUnicodeStr < GSM_TABLE_UNI_LENGTH)
225 if (*pUnicodeStr == GSM_UNICODE_TABLE[*pUnicodeStr])
227 *pCurrPos = (byte) (*pUnicodeStr);
228 foundInUniTable = true;
231 if (!foundInUniTable)
233 for (index = 0; index < GSM_TABLE_UNI_LENGTH; index++)
235 if (*pUnicodeStr == GSM_UNICODE_TABLE[index])
237 *pCurrPos = (byte) index;
238 foundInUniTable = true;
242 if (!foundInUniTable)
244 for (index = 0; index < EXT_GSM_TABLE_1B_LENGTH; index++)
246 if (*pUnicodeStr == GSM_UNICODE_TABLE_EXTENSION[index].unicode)
249 *(++pCurrPos) = GSM_UNICODE_TABLE_EXTENSION[index].gsm;
261 SetLastResult(E_SUCCESS);
262 return pDst.release();
266 _GsmEncodingCore::DecodeN(const byte* pSrc, int srcLength, int& retLength)
268 // 0 in GSM is mapped to 0x40 ['@'] in UNICODE, following code is to handle terminating null.
269 if (srcLength > 1 && pSrc[srcLength - 1] == '\0')
274 result r = GetCharCount(pSrc, srcLength, retLength);
275 SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Encoding failed", GetErrorMessage(r));
277 std::unique_ptr<wchar_t[]> pDst( new (std::nothrow) wchar_t[retLength + 1]);
278 SysTryReturn(NID_TEXT, pDst, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
280 byte* pGsmByte = (byte*) pSrc;
281 wchar_t* pCurrPos = pDst.get();
283 while (srcLength > 0 && pGsmByte != null)
285 *pCurrPos = GSM_UNICODE_TABLE[*pGsmByte];
286 if (*pGsmByte == 0x001B)
291 for (index = 0; index < EXT_GSM_TABLE_1B_LENGTH; index++)
293 if (*pGsmByte == GSM_UNICODE_TABLE_EXTENSION[index].gsm)
295 *pCurrPos = GSM_UNICODE_TABLE_EXTENSION[index].unicode;
305 *(pDst.get() + (retLength)) = '\0';
306 SetLastResult(E_SUCCESS);
307 return pDst.release();
311 _GsmEncodingCore::GetMaxByteCount(int charCount) const
313 return charCount * 2;
317 _GsmEncodingCore::GetMaxCharCount(int byteCount) const