* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "text_coder.h"
#include "iconv.h"
#include "mms_charset.h"
#include "securec.h"
#include "telephony_log_wrapper.h"
namespace OHOS {
namespace Telephony {
using msg_encode_type_t = uint8_t;
using namespace std;
static constexpr uint8_t GSM7_DEFLIST_LEN = 128;
static constexpr uint8_t UCS2_LEN_MIN = 2;
static constexpr uint32_t UCS2_LEN_MAX = INT_MAX / sizeof(WCHAR);
const WCHAR GSM7_BIT_TO_UC_S2[] = { 0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC, 0x00F2, 0x00C7,
0x000A, 216, 0x00F8, 0x000D, 0x00C5, 0x00E5, 0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8, 0x03A3,
0x0398, 0x039E, 0x001B, 0x00C6, 0x00E6, 0x00DF, 0x00C9, 0x0020, 0x0021, 0x0022, 0x0023, 0x00A4, 0x0025, 0x0026,
0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034,
0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x00A1, 0x0041, 0x0042,
0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00C4, 0x00D6, 0x00D1, 0x00DC,
0x00A7, 0x00BF, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C,
0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A,
0x00E4, 0x00F6, 0x00F1, 0x00FC, 0x00E0 };
TextCoder::TextCoder()
{
InitExtCharMap();
InitGsm7bitDefMap();
InitGsm7bitExtMap();
InitTurkishMap();
InitSpanishMap();
InitPortuMap();
InitReplaceCharMap();
}
TextCoder::~TextCoder()
{
extCharMap_.clear();
gsm7bitDefMap_.clear();
gsm7bitExtMap_.clear();
turkishMap_.clear();
spanishMap_.clear();
portuMap_.clear();
replaceCharMap_.clear();
}
TextCoder &TextCoder::Instance()
{
static TextCoder instance;
return instance;
}
void TextCoder::InitExtCharMap()
{
extCharMap_.clear();
extCharMap_ = { { 0x000C, MSG_GSM7EXT_CHAR }, { 0x005B, MSG_GSM7EXT_CHAR }, { 0x005C, MSG_GSM7EXT_CHAR },
{ 0x005D, MSG_GSM7EXT_CHAR }, { 0x005E, MSG_GSM7EXT_CHAR }, { 0x007B, MSG_GSM7EXT_CHAR },
{ 0x007C, MSG_GSM7EXT_CHAR }, { 0x007D, MSG_GSM7EXT_CHAR }, { 0x007E, MSG_GSM7EXT_CHAR },
{ 0x20AC, MSG_GSM7EXT_CHAR }, { 0x00E7, MSG_TURKISH_CHAR }, { 0x011E, MSG_TURKISH_CHAR },
{ 0x011F, MSG_TURKISH_CHAR }, { 0x01E6, MSG_TURKISH_CHAR }, { 0x01E7, MSG_TURKISH_CHAR },
{ 0x0130, MSG_TURKISH_CHAR }, { 0x0131, MSG_TURKISH_CHAR }, { 0x015E, MSG_TURKISH_CHAR },
{ 0x015F, MSG_TURKISH_CHAR }, { 0x00C1, MSG_SPANISH_CHAR }, { 0x00E1, MSG_SPANISH_CHAR },
{ 0x00CD, MSG_SPANISH_CHAR }, { 0x00ED, MSG_SPANISH_CHAR }, { 0x00D3, MSG_SPANISH_CHAR },
{ 0x00F3, MSG_SPANISH_CHAR }, { 0x00DA, MSG_SPANISH_CHAR }, { 0x00FA, MSG_SPANISH_CHAR },
{ 0x00D4, MSG_PORTUGUESE_CHAR }, { 0x00F4, MSG_PORTUGUESE_CHAR }, { 0x00CA, MSG_PORTUGUESE_CHAR },
{ 0x00EA, MSG_PORTUGUESE_CHAR }, { 0x00C0, MSG_PORTUGUESE_CHAR }, { 0x00E7, MSG_PORTUGUESE_CHAR },
{ 0x00C3, MSG_PORTUGUESE_CHAR }, { 0x00E3, MSG_PORTUGUESE_CHAR }, { 0x00D5, MSG_PORTUGUESE_CHAR },
{ 0x00F5, MSG_PORTUGUESE_CHAR }, { 0x00C2, MSG_PORTUGUESE_CHAR }, { 0x00E2, MSG_PORTUGUESE_CHAR } };
}
void TextCoder::InitGsm7bitDefMap()
{
gsm7bitDefMap_.clear();
for (uint8_t i = 0; i < GSM7_DEFLIST_LEN; i++) {
gsm7bitDefMap_[GSM7_BIT_TO_UC_S2[i]] = i;
}
}
void TextCoder::InitGsm7bitExtMap()
{
gsm7bitExtMap_.clear();
gsm7bitExtMap_ = { { 0x005B, 0x3C }, { 0x005D, 0x3E }, { 0x007B, 0x28 }, { 0x007D, 0x29 }, { 0x000C, 0x0A },
{ 0x005C, 0x2F }, { 0x005E, 0x14 }, { 0x007C, 0x40 }, { 0x007E, 0x3D }, { 0x20AC, 0x65 } };
}
void TextCoder::InitTurkishMap()
{
turkishMap_.clear();
turkishMap_ = { { 0x005B, 0x3C }, { 0x005D, 0x3E }, { 0x007B, 0x28 }, { 0x007D, 0x29 }, { 0x000C, 0x0A },
{ 0x005C, 0x2F }, { 0x005E, 0x14 }, { 0x007C, 0x40 }, { 0x007E, 0x3D }, { 0x20AC, 0x65 }, { 0x00E7, 0x63 },
{ 0x011E, 0x47 }, { 0x011F, 0x67 }, { 0x01E6, 0x47 }, { 0x01E7, 0x67 }, { 0x0130, 0x49 }, { 0x0131, 0x69 },
{ 0x015E, 0x53 }, { 0x015F, 0x73 } };
}
void TextCoder::InitSpanishMap()
{
spanishMap_.clear();
spanishMap_ = { { 0x005B, 0x3C }, { 0x005D, 0x3E }, { 0x007B, 0x28 }, { 0x007D, 0x29 }, { 0x000C, 0x0A },
{ 0x005C, 0x2F }, { 0x005E, 0x14 }, { 0x007C, 0x40 }, { 0x007E, 0x3D }, { 0x20AC, 0x65 }, { 0x00C1, 0x41 },
{ 0x00E1, 0x61 }, { 0x00CD, 0x49 }, { 0x00ED, 0x69 }, { 0x00D3, 0x4F }, { 0x00F3, 0x6F }, { 0x00DA, 0x55 },
{ 0x00FA, 0x75 } };
}
void TextCoder::InitPortuMap()
{
portuMap_.clear();
portuMap_ = { { 0x005B, 0x3C }, { 0x005D, 0x3E }, { 0x007B, 0x28 }, { 0x007D, 0x29 }, { 0x000C, 0x0A },
{ 0x005C, 0x2F }, { 0x005E, 0x14 }, { 0x007C, 0x40 }, { 0x007E, 0x3D }, { 0x20AC, 0x65 }, { 0x00D4, 0x0B },
{ 0x00F4, 0x0C }, { 0x00C1, 0x0E }, { 0x00E1, 0x0F }, { 0x00CA, 0x1F }, { 0x00EA, 0x05 }, { 0x00C0, 0x41 },
{ 0x00E7, 0x09 }, { 0x00CD, 0x49 }, { 0x00ED, 0x69 }, { 0x00D3, 0x4F }, { 0x00F3, 0x6F }, { 0x00DA, 0x55 },
{ 0x00FA, 0x75 }, { 0x00C3, 0x61 }, { 0x00E3, 0x7B }, { 0x00D5, 0x5C }, { 0x00F5, 0x7C }, { 0x00C2, 0x61 },
{ 0x00E2, 0x7F }, { 0x03A6, 0x12 }, { 0x0393, 0x13 }, { 0x03A9, 0x15 }, { 0x03A0, 0x16 }, { 0x03A8, 0x17 },
{ 0x03A3, 0x18 }, { 0x0398, 0x19 } };
}
void TextCoder::InitReplaceCharMap()
{
replaceCharMap_.clear();
replaceCharMap_ = { { 0x00E0, 0x61 }, { 0x00E1, 0x61 }, { 0x00E2, 0x61 }, { 0x00E3, 0x61 }, { 0x00E4, 0x61 },
{ 0x00E5, 0x61 }, { 0x00E6, 0x61 }, { 0x0101, 0x61 }, { 0x0103, 0x61 }, { 0x0105, 0x61 }, { 0x01CE, 0x61 },
{ 0x00C0, 0x41 }, { 0x00C1, 0x41 }, { 0x00C2, 0x41 }, { 0x00C3, 0x41 }, { 0x00C4, 0x41 }, { 0x00C5, 0x41 },
{ 0x00C6, 0x41 }, { 0x0100, 0x41 }, { 0x0102, 0x41 }, { 0x0104, 0x41 }, { 0x01CD, 0x41 }, { 0x00E7, 0x63 },
{ 0x0107, 0x63 }, { 0x0109, 0x63 }, { 0x010B, 0x63 }, { 0x010D, 0x63 }, { 0x00C7, 0x43 }, { 0x0106, 0x43 },
{ 0x0108, 0x43 }, { 0x010A, 0x43 }, { 0x010C, 0x43 }, { 0x010F, 0x64 }, { 0x0111, 0x64 }, { 0x010E, 0x44 },
{ 0x0110, 0x44 }, { 0x00E8, 0x65 }, { 0x00E9, 0x65 }, { 0x00EA, 0x65 }, { 0x00EB, 0x65 }, { 0x0113, 0x65 },
{ 0x0115, 0x65 }, { 0x0117, 0x65 }, { 0x0119, 0x65 }, { 0x011B, 0x65 }, { 0x0259, 0x65 }, { 0x00C8, 0x45 },
{ 0x00C9, 0x45 }, { 0x00CA, 0x45 }, { 0x00CB, 0x45 }, { 0x0112, 0x45 }, { 0x0114, 0x45 }, { 0x0116, 0x45 },
{ 0x0118, 0x45 }, { 0x011A, 0x45 }, { 0x018F, 0x45 }, { 0x011D, 0x67 }, { 0x011F, 0x67 }, { 0x0121, 0x67 },
{ 0x0123, 0x67 }, { 0x01E7, 0x67 }, { 0x01F5, 0x67 }, { 0x1E21, 0x67 }, { 0x011C, 0x47 }, { 0x011E, 0x47 },
{ 0x0120, 0x47 }, { 0x0122, 0x47 }, { 0x01E6, 0x47 }, { 0x01F4, 0x47 }, { 0x1E20, 0x47 }, { 0x00EC, 0x69 },
{ 0x00ED, 0x69 }, { 0x00EE, 0x69 }, { 0x00EF, 0x69 }, { 0x0129, 0x69 }, { 0x012B, 0x69 }, { 0x012D, 0x69 },
{ 0x012F, 0x69 }, { 0x01D0, 0x69 }, { 0x0131, 0x69 }, { 0x00CC, 0x49 }, { 0x00CD, 0x49 }, { 0x00CE, 0x49 },
{ 0x00CF, 0x49 }, { 0x0128, 0x49 }, { 0x012A, 0x49 }, { 0x012C, 0x49 }, { 0x012E, 0x49 }, { 0x0130, 0x49 },
{ 0x0137, 0x6B }, { 0x0136, 0x4B }, { 0x013A, 0x6C }, { 0x013C, 0x6C }, { 0x013E, 0x6C }, { 0x0140, 0x6C },
{ 0x0142, 0x6C }, { 0x0139, 0x4C }, { 0x013B, 0x4C }, { 0x013D, 0x4C }, { 0x013F, 0x4C }, { 0x0141, 0x4C },
{ 0x00F1, 0x6E }, { 0x0144, 0x6E }, { 0x0146, 0x6E }, { 0x0148, 0x6E }, { 0x00D1, 0x4E }, { 0x0143, 0x4E },
{ 0x0145, 0x4E }, { 0x0147, 0x4E }, { 0x00F2, 0x6F }, { 0x00F3, 0x6F }, { 0x00F4, 0x6F }, { 0x00F5, 0x6F },
{ 0x00F6, 0x6F }, { 0x00F8, 0x6F }, { 0x014D, 0x6F }, { 0x014F, 0x6F }, { 0x01D2, 0x6F }, { 0x01EB, 0x6F },
{ 0x0151, 0x6F }, { 0x0153, 0x6F }, { 0x00D2, 0x4F }, { 0x00D3, 0x4F }, { 0x00D4, 0x4F }, { 0x00D5, 0x4F },
{ 0x00D6, 0x4F }, { 216, 0x4F }, { 0x014C, 0x4F }, { 0x014E, 0x4F }, { 0x01D1, 0x4F }, { 0x01EA, 0x4F },
{ 0x0150, 0x4F }, { 0x0152, 0x4F }, { 0x0155, 0x72 }, { 0x0157, 0x72 }, { 0x0159, 0x72 }, { 0x0154, 0x52 },
{ 0x0156, 0x52 }, { 0x0158, 0x52 }, { 0x015B, 0x73 }, { 0x015D, 0x73 }, { 0x015F, 0x73 }, { 0x0161, 0x73 },
{ 0x015A, 0x53 }, { 0x015C, 0x53 }, { 0x015E, 0x53 }, { 0x0160, 0x53 }, { 0x00FE, 0x74 }, { 0x0163, 0x74 },
{ 0x0165, 0x74 }, { 0x0167, 0x74 }, { 0x021B, 0x74 }, { 0x00DE, 0x54 }, { 0x0162, 0x54 }, { 0x0164, 0x54 },
{ 0x0166, 0x54 }, { 0x00F9, 0x75 }, { 0x00FA, 0x75 }, { 0x00FB, 0x75 }, { 0x00FC, 0x75 }, { 0x0169, 0x75 },
{ 0x016B, 0x75 }, { 0x016D, 0x75 }, { 0x016F, 0x75 }, { 0x0171, 0x75 }, { 0x0173, 0x75 }, { 0x01D4, 0x75 },
{ 0x00D9, 0x55 }, { 0x00DA, 0x55 }, { 0x00DB, 0x55 }, { 0x00DC, 0x55 }, { 0x0168, 0x55 }, { 0x016A, 0x55 },
{ 0x016C, 0x55 }, { 0x016E, 0x55 }, { 0x0170, 0x55 }, { 0x0172, 0x55 }, { 0x01D3, 0x55 }, { 0x00FD, 0x79 },
{ 0x00FF, 0x79 }, { 0x0177, 0x79 }, { 0x0233, 0x79 }, { 0x1EF3, 0x79 }, { 0x1EF9, 0x79 }, { 0x00DD, 0x59 },
{ 0x0176, 0x59 }, { 0x0178, 0x59 }, { 0x0232, 0x59 }, { 0x1EF2, 0x59 }, { 0x1EF8, 0x59 }, { 0x017A, 0x7A },
{ 0x017C, 0x7A }, { 0x017E, 0x7A }, { 0x0179, 0x5A }, { 0x017B, 0x5A }, { 0x017D, 0x5A } };
}
bool TextCoder::GetEncodeString(
std::string &encodeString, uint32_t charset, uint32_t valLength, const std::string &strEncodeString)
{
std::string strToCodeset("UTF-8");
std::string strFromCodeset;
auto charSetInstance = DelayedSingleton<MmsCharSet>::GetInstance();
if (charSetInstance == nullptr || (!charSetInstance->GetCharSetStrFromInt(strFromCodeset, charset))) {
strFromCodeset = "UTF-8";
}
iconv_t cd = iconv_open(strToCodeset.c_str(), strFromCodeset.c_str());
if (cd == reinterpret_cast<iconv_t>(-1)) {
TELEPHONY_LOGE("GetEncodeString iconv_open failed");
return false;
}
size_t inLen = static_cast<size_t>(valLength);
auto outBufSize = strEncodeString.size() * 4;
std::unique_ptr<char[]> outBufPtr = std::make_unique<char[]>(outBufSize);
char *outBuf = outBufPtr.get();
char *inBuf = const_cast<char*>(strEncodeString.c_str());
size_t err = iconv(cd, &inBuf, &inLen, &outBuf, &outBufSize);
iconv_close(cd);
if (static_cast<int>(err) == -1) {
TELEPHONY_LOGW("iconv conversion failed, but continue conv");
}
encodeString = std::string(outBufPtr.get(), outBuf - outBufPtr.get());
return true;
}
* @brief Utf8ToGsm7bit
* max # of Ucs2 chars, NOT bytes. when all utf8 chars are only one byte,
* Ucs2Length is maxUcs2 Length. otherwise (ex: 2 bytes of UTF8 is one char)
* Ucs2Length must be less than utf8Length
*/
int TextCoder::Utf8ToGsm7bit(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength, MSG_LANGUAGE_ID_T &langId)
{
if (srcLength == -1 && src) {
srcLength = strlen(reinterpret_cast<const char *>(src));
}
if (srcLength <= 0 || src == nullptr || dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("text is null");
return 0;
}
int maxUcs2Length = srcLength;
if (static_cast<uint32_t>(maxUcs2Length) >= UCS2_LEN_MAX) {
TELEPHONY_LOGE("src over size");
return 0;
}
std::unique_ptr<WCHAR[]> ucs2Text = std::make_unique<WCHAR[]>(maxUcs2Length);
if (ucs2Text == nullptr) {
TELEPHONY_LOGE("make_unique error");
return 0;
}
WCHAR *pUcs2Text = ucs2Text.get();
if (memset_s(pUcs2Text, maxUcs2Length * sizeof(WCHAR), 0x00, maxUcs2Length * sizeof(WCHAR)) != EOK) {
TELEPHONY_LOGE("memset_s error");
return 0;
}
TELEPHONY_LOGI("srcLength = %{public}d", srcLength);
int ucs2Length = Utf8ToUcs2(reinterpret_cast<uint8_t *>(pUcs2Text), maxUcs2Length * sizeof(WCHAR), src, srcLength);
return Ucs2ToGsm7bit(dest, maxLength, reinterpret_cast<uint8_t *>(pUcs2Text), ucs2Length, langId);
}
int TextCoder::Utf8ToUcs2(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength)
{
if (srcLength == -1 && src) {
srcLength = strlen(reinterpret_cast<char *>(const_cast<uint8_t *>(src)));
}
if (srcLength <= 0 || src == nullptr || dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("text is null");
return 0;
}
size_t textLen = static_cast<size_t>(srcLength);
auto unicodeTemp = reinterpret_cast<uint8_t *>(dest);
size_t remainedLength = static_cast<size_t>(maxLength);
iconv_t cd = iconv_open("UTF16BE", "UTF8");
if (cd == reinterpret_cast<iconv_t>(-1)) {
TELEPHONY_LOGE("Utf8ToUcs2-iconv_open is error");
return 0;
}
size_t err = iconv(cd, reinterpret_cast<char **>(const_cast<uint8_t **>(&src)), &textLen,
reinterpret_cast<char **>(&unicodeTemp), &remainedLength);
iconv_close(cd);
return (static_cast<int>(err) == -1) ? -1 : (maxLength - static_cast<int>(remainedLength));
}
int TextCoder::GsmUtf8ToAuto(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength,
DataCodingScheme &scheme, SmsCodingNationalType codingNationalType, MSG_LANGUAGE_ID_T &langId)
{
int maxUcs2Length = srcLength;
if (maxLength <= 0 || maxUcs2Length <= 0 || static_cast<uint32_t>(maxUcs2Length) >= UCS2_LEN_MAX) {
TELEPHONY_LOGE("length invalid");
return 0;
}
std::unique_ptr<WCHAR[]> ucs2Text = std::make_unique<WCHAR[]>(maxUcs2Length);
if (ucs2Text == nullptr) {
TELEPHONY_LOGE("GsmUtf8ToAuto make_unique error");
return 0;
}
WCHAR *pUcs2Text = ucs2Text.get();
if (memset_s(pUcs2Text, maxUcs2Length * sizeof(WCHAR), 0x00, maxUcs2Length * sizeof(WCHAR)) != EOK) {
TELEPHONY_LOGE("GsmUtf8ToAuto memset_s error");
return 0;
}
int ucs2Length = Utf8ToUcs2(reinterpret_cast<uint8_t *>(pUcs2Text), maxUcs2Length * sizeof(WCHAR), src, srcLength);
int tempTextLen = 0;
if (ucs2Length < 0) {
scheme = DATA_CODING_8BIT;
tempTextLen = (srcLength > maxLength) ? maxLength : srcLength;
if (memcpy_s(dest, tempTextLen, src, tempTextLen) != EOK) {
TELEPHONY_LOGE("GsmUtf8ToAuto memcpy_s error");
}
return tempTextLen;
}
bool unknown = false;
int length = Ucs2ToGsm7bitAuto(dest, maxLength, reinterpret_cast<uint8_t *>(pUcs2Text), ucs2Length,
unknown, codingNationalType);
if (unknown) {
scheme = DATA_CODING_UCS2;
if (ucs2Length <= 0) {
return length;
}
tempTextLen = (ucs2Length > maxLength) ? maxLength : ucs2Length;
if (memcpy_s(dest, tempTextLen, pUcs2Text, tempTextLen) != EOK) {
TELEPHONY_LOGE("memcpy_s error");
}
return tempTextLen;
}
langId = static_cast<MSG_LANGUAGE_ID_T>(codingNationalType);
scheme = DATA_CODING_7BIT;
return length;
}
int TextCoder::CdmaUtf8ToAuto(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength, DataCodingScheme &scheme)
{
int maxUcs2Length = srcLength;
if (maxLength <= 0 || maxUcs2Length <= 0 || static_cast<uint32_t>(maxUcs2Length) >= UCS2_LEN_MAX) {
TELEPHONY_LOGE("length invalid");
return 0;
}
std::unique_ptr<WCHAR[]> ucs2Text = std::make_unique<WCHAR[]>(maxUcs2Length);
if (ucs2Text == nullptr) {
TELEPHONY_LOGE("CdmaUtf8ToAuto make_unique error");
return 0;
}
WCHAR *pUcs2Text = ucs2Text.get();
if (memset_s(pUcs2Text, maxUcs2Length * sizeof(WCHAR), 0x00, maxUcs2Length * sizeof(WCHAR)) != EOK) {
TELEPHONY_LOGE("CdmaUtf8ToAuto memset_s error");
return 0;
}
int ucs2Length = Utf8ToUcs2(reinterpret_cast<uint8_t *>(pUcs2Text), maxUcs2Length * sizeof(WCHAR), src, srcLength);
int tempTextLen = 0;
if (ucs2Length < 0) {
scheme = DATA_CODING_8BIT;
tempTextLen = (srcLength > maxLength) ? maxLength : srcLength;
if (memcpy_s(dest, tempTextLen, src, tempTextLen) != EOK) {
TELEPHONY_LOGE("memcpy_s error");
}
return tempTextLen;
}
bool unknown = false;
int gsm7bitLength = Ucs2ToAscii(dest, maxLength, reinterpret_cast<uint8_t *>(pUcs2Text), ucs2Length, unknown);
if (unknown) {
scheme = DATA_CODING_UCS2;
if (ucs2Length <= 0) {
return gsm7bitLength;
}
tempTextLen = (ucs2Length > maxLength) ? maxLength : ucs2Length;
if (memcpy_s(dest, tempTextLen, pUcs2Text, tempTextLen) != EOK) {
TELEPHONY_LOGE("memcpy_s error");
}
return tempTextLen;
}
scheme = DATA_CODING_ASCII7BIT;
return gsm7bitLength;
}
* @brief Gsm7bitToUtf8
* max # of Ucs2 chars, NOT bytes. when all gsm7 chars are only one byte(-there is no extension)
* Ucs2Length is maxUcs2 Length. otherwise(ex: gsm7 char starts with 0x1b)
* Ucs2Length must be less than gsm7 length
*/
int TextCoder::Gsm7bitToUtf8(
uint8_t *dest, int maxLength, const uint8_t *src, int srcLength, const MsgLangInfo &langInfo)
{
int maxUcs2Length = srcLength;
if (maxUcs2Length <= 0 || static_cast<uint32_t>(maxUcs2Length) >= UCS2_LEN_MAX) {
TELEPHONY_LOGE("Gsm7bitToUtf8 src over size");
return 0;
}
std::unique_ptr<WCHAR[]> ucs2Text = std::make_unique<WCHAR[]>(maxUcs2Length);
if (ucs2Text == nullptr) {
TELEPHONY_LOGE("Gsm7bitToUtf8 make_unique error");
return 0;
}
WCHAR *pUcs2Text = ucs2Text.get();
if (memset_s(pUcs2Text, maxUcs2Length * sizeof(WCHAR), 0x00, maxUcs2Length * sizeof(WCHAR)) != EOK) {
TELEPHONY_LOGE("Gsm7bitToUtf8 memset_s error");
return 0;
}
TELEPHONY_LOGI("max dest Length = %{public}d, srcLength = %{public}d", maxLength, srcLength);
int ucs2Length =
Gsm7bitToUcs2(reinterpret_cast<uint8_t *>(pUcs2Text), maxUcs2Length * sizeof(WCHAR), src, srcLength, langInfo);
if (ucs2Length > maxLength) {
if (ucs2Length > static_cast<int>(maxUcs2Length * sizeof(WCHAR))) {
TELEPHONY_LOGI("src over size, ucs2Length = %{public}d, maxLength = %{public}d", ucs2Length,
static_cast<int>(maxUcs2Length * sizeof(WCHAR)));
return 0;
}
}
return Ucs2ToUtf8(dest, maxLength, reinterpret_cast<uint8_t *>(pUcs2Text), ucs2Length);
}
int TextCoder::Ucs2ToUtf8(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength)
{
if (srcLength == -1 && src) {
TELEPHONY_LOGE("stcLength == -1 && src branch");
srcLength = strlen(reinterpret_cast<char *>(const_cast<uint8_t *>(src)));
}
if (srcLength <= 0 || src == nullptr || dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("text is null");
return 0;
}
size_t textLen = static_cast<size_t >(srcLength);
size_t remainedLength = static_cast<size_t >(maxLength);
iconv_t cd = iconv_open("UTF8", "UTF16BE");
if (cd == reinterpret_cast<iconv_t>(-1)) {
TELEPHONY_LOGE("Ucs2ToUtf8 iconv_open is error");
return 0;
}
size_t err = iconv(cd, reinterpret_cast<char **>(const_cast<uint8_t **>(&src)),
reinterpret_cast<size_t *>(&textLen), reinterpret_cast<char **>(&dest),
reinterpret_cast<size_t *>(&remainedLength));
iconv_close(cd);
if (static_cast<int>(err) == -1) {
TELEPHONY_LOGW("Ucs2ToUtf8-iconv result is err, but continue conv");
}
int length = maxLength - static_cast<int>(remainedLength);
if (length < 0 || length >= maxLength) {
return 0;
}
return length;
}
int TextCoder::EuckrToUtf8(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength)
{
if (srcLength == -1 && src) {
srcLength = strlen(reinterpret_cast<char *>(const_cast<uint8_t *>(src)));
}
if (srcLength <= 0 || src == nullptr || dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("text is null");
return 0;
}
size_t remainedLength = static_cast<size_t>(maxLength);
size_t textLen = static_cast<size_t>(srcLength);
iconv_t cd = iconv_open("UTF8", "EUCKR");
if (cd == reinterpret_cast<iconv_t>(-1)) {
TELEPHONY_LOGE("EuckrToUtf8 iconv_open is error");
return 0;
}
size_t err = iconv(cd, reinterpret_cast<char **>(const_cast<uint8_t **>(&src)),
reinterpret_cast<size_t *>(&textLen), reinterpret_cast<char **>(&dest),
reinterpret_cast<size_t *>(&remainedLength));
if (static_cast<int>(err) == -1) {
TELEPHONY_LOGW("EuckrToUtf8 iconv result is err, but continue conv");
}
int utf8Length = maxLength - static_cast<int>(remainedLength);
if (utf8Length < 0 || utf8Length >= maxLength) {
return 0;
}
dest[utf8Length] = 0x00;
return utf8Length;
}
int TextCoder::ShiftjisToUtf8(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength) const
{
if (srcLength == -1 && src) {
srcLength = strlen(reinterpret_cast<char *>(const_cast<uint8_t *>(src)));
}
if (srcLength <= 0 || src == nullptr || dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("text is null");
return 0;
}
size_t textLen = static_cast<size_t>(srcLength);
size_t remainedLength = static_cast<size_t>(maxLength);
iconv_t cd = iconv_open("UTF8", "SHIFT-JIS");
if (cd == reinterpret_cast<iconv_t>(-1)) {
TELEPHONY_LOGE("ShiftjisToUtf8 iconv_open is error");
return 0;
}
size_t err = iconv(cd, reinterpret_cast<char **>(const_cast<uint8_t **>(&src)),
reinterpret_cast<size_t *>(&textLen), reinterpret_cast<char **>(&dest),
reinterpret_cast<size_t *>(&remainedLength));
iconv_close(cd);
if (static_cast<int>(err) == -1) {
TELEPHONY_LOGW("ShiftjisToUtf8 iconv result is err, but continue conv");
}
int utf8Length = maxLength - static_cast<int>(remainedLength);
if (utf8Length < 0 || utf8Length >= maxLength) {
return 0;
}
dest[utf8Length] = 0x00;
return utf8Length;
}
int TextCoder::Ucs2ToGsm7bit(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength, MSG_LANGUAGE_ID_T &langId)
{
if (srcLength <= 0 || src == nullptr || dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("text is null");
return -1;
}
int outTextLen = 0;
int remainLen = 0;
uint16_t inText = 0;
uint8_t currType = GetLangType(src, srcLength);
std::map<uint16_t, uint8_t>::iterator itChar;
for (int index = 0; index < (srcLength - 1); index += UCS2_LEN_MIN) {
inText = src[index];
inText = ((inText << 0x08) & 0xFF00) | src[index + 1];
itChar = gsm7bitDefMap_.find(inText);
if (itChar != gsm7bitDefMap_.end()) {
dest[outTextLen++] = static_cast<uint8_t>(itChar->second);
} else {
switch (currType) {
case MSG_GSM7EXT_CHAR:
remainLen = maxLength - outTextLen;
outTextLen += FindGsm7bitExt(&dest[outTextLen], remainLen, inText);
break;
case MSG_TURKISH_CHAR:
langId = MSG_ID_TURKISH_LANG;
remainLen = maxLength - outTextLen;
outTextLen += FindTurkish(&dest[outTextLen], remainLen, inText);
break;
case MSG_SPANISH_CHAR:
langId = MSG_ID_SPANISH_LANG;
remainLen = maxLength - outTextLen;
outTextLen += FindSpanish(&dest[outTextLen], remainLen, inText);
break;
case MSG_PORTUGUESE_CHAR:
langId = MSG_ID_PORTUGUESE_LANG;
remainLen = maxLength - outTextLen;
outTextLen += FindPortu(&dest[outTextLen], remainLen, inText);
break;
default:
dest[outTextLen] = FindReplaceChar(inText);
break;
}
outTextLen++;
}
if (maxLength <= outTextLen) {
TELEPHONY_LOGE("buffer overflow");
break;
}
}
return outTextLen;
}
std::map<uint16_t, uint8_t> TextCoder::Get7BitCodingExtMap(SmsCodingNationalType codingNationalType) const
{
std::map<uint16_t, uint8_t> extMap = gsm7bitExtMap_;
switch (codingNationalType) {
case SMS_CODING_NATIONAL_TYPE_DEFAULT:
extMap = gsm7bitExtMap_;
break;
case SMS_CODING_NATIONAL_TYPE_TURKISH:
extMap = turkishMap_;
break;
case SMS_CODING_NATIONAL_TYPE_SPANISH:
extMap = spanishMap_;
break;
case SMS_CODING_NATIONAL_TYPE_PORTUGUESE:
extMap = portuMap_;
break;
default:
extMap = gsm7bitExtMap_;
break;
}
return extMap;
}
int TextCoder::Ucs2ToGsm7bitAuto(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength,
bool &unknown, SmsCodingNationalType codingNationalType)
{
if (srcLength <= 0 || src == nullptr || dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("text is null");
return -1;
}
std::map<uint16_t, uint8_t> extMap = Get7BitCodingExtMap(codingNationalType);
int outTextLen = 0;
std::map<uint16_t, uint8_t>::iterator itChar;
std::map<uint16_t, uint8_t>::iterator itExt;
uint16_t inText;
for (int i = 0; i < srcLength - 1; i += UCS2_LEN_MIN) {
inText = src[i];
inText = ((inText << 0x08) & 0xFF00) | src[i + 1];
itChar = gsm7bitDefMap_.find(inText);
if (itChar != gsm7bitDefMap_.end()) {
dest[outTextLen++] = static_cast<uint8_t>(itChar->second);
} else {
itExt = extMap.find(inText);
if (itExt == extMap.end()) {
TELEPHONY_LOGI("Abnormal character is included. inText : [%{public}04x]", inText);
unknown = true;
return 0;
}
if (maxLength <= outTextLen + 1) {
TELEPHONY_LOGE("buffer overflow.");
break;
}
dest[outTextLen++] = 0x1B;
dest[outTextLen++] = static_cast<uint8_t>(itExt->second);
}
if (maxLength <= outTextLen) {
TELEPHONY_LOGE("buffer overflow");
break;
}
}
return outTextLen;
}
int TextCoder::Ucs2ToAscii(uint8_t *dest, int maxLength, const uint8_t *src, int srcLength, bool &unknown)
{
if (srcLength <= 0 || src == nullptr || dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("text is null");
return -1;
}
int outTextLen = 0;
std::map<uint16_t, uint8_t>::iterator itChar;
std::map<uint16_t, uint8_t>::iterator itExt;
uint16_t inText;
for (int index = 0; index < srcLength - 1; index += UCS2_LEN_MIN) {
inText = src[index];
inText = ((inText << 0x08) & 0xFF00) | src[index + 1];
if (inText > 0x007f) {
TELEPHONY_LOGI("abnormal character is included [%{public}04x]", inText);
unknown = true;
return 0;
}
dest[outTextLen++] = static_cast<uint8_t>(inText);
if (maxLength <= outTextLen) {
TELEPHONY_LOGE("buffer overflow");
break;
}
}
return outTextLen;
}
uint8_t TextCoder::GetLangType(const uint8_t *src, int srcLength)
{
if (srcLength <= 0 || src == nullptr) {
TELEPHONY_LOGE("text is null");
return MSG_DEFAULT_CHAR;
}
std::map<uint16_t, uint8_t>::iterator itExt;
uint8_t currType = MSG_DEFAULT_CHAR;
uint8_t newType = MSG_DEFAULT_CHAR;
uint16_t inText;
for (int index = 0; index < (srcLength - 1); index += UCS2_LEN_MIN) {
inText = src[index];
inText = ((inText << 0x08) & 0xFF00) | src[index + 1];
itExt = extCharMap_.find(inText);
if (itExt == extCharMap_.end()) {
continue;
}
newType = static_cast<uint8_t>(itExt->second);
if (newType >= currType) {
bool isTurkisk = (inText == 0x00e7 && currType <= MSG_TURKISH_CHAR);
currType = isTurkisk ? MSG_TURKISH_CHAR : newType;
}
}
TELEPHONY_LOGI("charType : [%{public}hhu]", currType);
return currType;
}
int TextCoder::FindGsm7bitExt(uint8_t *dest, int maxLength, const uint16_t inText)
{
int outTextLen = 0;
if (dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("Invalid parameter.");
return outTextLen;
}
auto itExt = gsm7bitExtMap_.find(inText);
if (itExt == gsm7bitExtMap_.end()) {
dest[outTextLen++] = FindReplaceChar(inText);
return outTextLen;
}
if (maxLength <= outTextLen + 1) {
TELEPHONY_LOGE("FindGsm7bitExt buffer overflow");
return outTextLen;
}
dest[outTextLen++] = 0x1B;
dest[outTextLen++] = static_cast<uint8_t>(itExt->second);
return outTextLen;
}
int TextCoder::FindTurkish(uint8_t *dest, int maxLength, const uint16_t inText)
{
int outTextLen = 0;
if (dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("Invalid parameter.");
return outTextLen;
}
auto itExt = turkishMap_.find(inText);
if (itExt == turkishMap_.end()) {
dest[outTextLen++] = FindReplaceChar(inText);
return outTextLen;
}
if (maxLength <= outTextLen + 1) {
TELEPHONY_LOGE("FindTurkish buffer overflow");
return outTextLen;
}
dest[outTextLen++] = 0x1B;
dest[outTextLen++] = static_cast<uint8_t>(itExt->second);
return outTextLen;
}
int TextCoder::FindSpanish(uint8_t *dest, int maxLength, const uint16_t inText)
{
int outTextLen = 0;
if (dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("Invalid parameter.");
return outTextLen;
}
auto itExt = spanishMap_.find(inText);
if (itExt == spanishMap_.end()) {
dest[outTextLen++] = FindReplaceChar(inText);
return outTextLen;
}
if (maxLength <= outTextLen + 1) {
TELEPHONY_LOGE("FindSpanish buffer overflow");
return outTextLen;
}
dest[outTextLen++] = 0x1B;
dest[outTextLen++] = static_cast<uint8_t>(itExt->second);
return outTextLen;
}
int TextCoder::FindPortu(uint8_t *dest, int maxLength, const uint16_t inText)
{
int outTextLen = 0;
if (dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("Invalid parameter.");
return outTextLen;
}
auto itExt = portuMap_.find(inText);
if (itExt == portuMap_.end()) {
dest[outTextLen++] = FindReplaceChar(inText);
return outTextLen;
}
if (maxLength <= outTextLen + 1) {
TELEPHONY_LOGE("FindPortu buffer overflow");
return outTextLen;
}
dest[outTextLen++] = 0x1B;
dest[outTextLen++] = static_cast<uint8_t>(itExt->second);
return outTextLen;
}
uint8_t TextCoder::FindReplaceChar(const uint16_t inText)
{
uint8_t result = 0;
auto itReplace = replaceCharMap_.find(inText);
if (itReplace != replaceCharMap_.end()) {
result = static_cast<uint8_t>(itReplace->second);
} else {
result = 0x3F;
}
return result;
}
int TextCoder::Gsm7bitToUcs2(
uint8_t *dest, int maxLength, const uint8_t *src, int srcLength, const MsgLangInfo &langInfo)
{
if (srcLength == 0 || src == nullptr || dest == nullptr || maxLength <= 0) {
TELEPHONY_LOGE("text is null");
return -1;
}
int outTextLen = 0;
uint8_t lowerByte = 0;
uint8_t upperByte = 0;
uint16_t result = 0;
for (int i = 0; i < srcLength && maxLength > UCS2_LEN_MIN; i++) {
if (src[i] >= 0x80) {
TELEPHONY_LOGE("a_pTextString[%{public}d]=%{public}x, The alpha isn't the gsm 7bit code", i, src[i]);
return -1;
}
if (langInfo.bLockingShift) {
TELEPHONY_LOGI("National Language Locking Shift [%{public}d]", langInfo.lockingLang);
if (langInfo.lockingLang == MSG_ID_TURKISH_LANG) {
i += EscapeTurkishLockingToUcs2(&src[i], (srcLength - i), langInfo, result);
lowerByte = static_cast<uint8_t>(result & 0x00FF);
upperByte = static_cast<uint8_t>(result >> 0x08);
} else if (langInfo.lockingLang == MSG_ID_PORTUGUESE_LANG) {
i += EscapePortuLockingToUcs2(&src[i], (srcLength - i), langInfo, result);
lowerByte = static_cast<uint8_t>(result & 0x00FF);
upperByte = static_cast<uint8_t>(result >> 0x08);
}
} else {
i += EscapeGsm7bitToUcs2(&src[i], (srcLength - i), langInfo, result);
lowerByte = static_cast<uint8_t>(result & 0x00FF);
upperByte = static_cast<uint8_t>(result >> 0x08);
}
dest[outTextLen++] = upperByte;
dest[outTextLen++] = lowerByte;
maxLength -= 0x02;
}
dest[outTextLen] = '\0';
return outTextLen;
}
int TextCoder::EscapeTurkishLockingToUcs2(const uint8_t *src, int srcLen, const MsgLangInfo &langInfo, uint16_t &result)
{
int index = 0;
if (src == nullptr || srcLen <= 0) {
return index;
}
const WCHAR turkishLockingToUcs2[] = { 0x0040, 0x00A3, 0x0024, 0x00A5, 0x20AC, 0x00E9, 0x00F9, 0x00EC, 0x00F2,
0x00C7, 0x000A, 0x011E, 0x011F, 0x000D, 0x00C5, 0x00E5, 0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0,
0x03A8, 0x03A3, 0x0398, 0x039E, 0x001B, 0x015E, 0x015F, 0x00DF, 0x00C9, 0x0020, 0x0021, 0x0022, 0x0023, 0x00A4,
0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032,
0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0130,
0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E,
0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00C4, 0x00D6,
0x00D1, 0x00DC, 0x00A7, 0x00E7, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A,
0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
0x0079, 0x007A, 0x00E4, 0x00F6, 0x00F1, 0x00FC, 0x00E0 };
if (turkishLockingToUcs2[src[index]] == 0x001B) {
index++;
if (index >= srcLen) {
return index;
}
result = EscapeToUcs2(src[index], langInfo);
} else {
result = turkishLockingToUcs2[src[index]];
}
return index;
}
int TextCoder::EscapePortuLockingToUcs2(const uint8_t *src, int srcLen, const MsgLangInfo &langInfo, uint16_t &result)
{
int index = 0;
if (src == nullptr || srcLen <= 0) {
return index;
}
const WCHAR portuLockingToUcs2[] = { 0x0040, 0x00A3, 0x0024, 0x00A5, 0x00EA, 0x00E9, 0x00FA, 0x00ED, 0x00F3, 0x00E7,
0x000A, 0x00D4, 0x00F4, 0x000D, 0x00C1, 0x00E1, 0x0394, 0x005F, 0x0020, 0x00C7, 0x00C0, 0x0020, 0x005E, 0x005C,
0x20AC, 0x00D3, 0x007C, 0x001B, 0x00C2, 0x00E2, 0x00CA, 0x00C9, 0x0020, 0x0021, 0x0022, 0x0023, 0x00A4, 0x0025,
0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033,
0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x00CD, 0x0041,
0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00C3, 0x00D5, 0x00DA,
0x00DC, 0x00A7, 0x00BF, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B,
0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079,
0x007A, 0x00E3, 0x00F5, 0x0020, 0x00FC, 0x00E0 };
if (portuLockingToUcs2[src[index]] == 0x001B) {
index++;
if (index >= srcLen) {
return index;
}
result = EscapeToUcs2(src[index], langInfo);
} else {
result = portuLockingToUcs2[src[index]];
}
return index;
}
int TextCoder::EscapeGsm7bitToUcs2(const uint8_t *src, int srcLen, const MsgLangInfo &langInfo, uint16_t &result)
{
int index = 0;
if (src == nullptr || srcLen <= 0) {
return index;
}
if (GSM7_BIT_TO_UC_S2[src[index]] == 0x001B) {
index++;
if (index >= srcLen) {
return index;
}
result = EscapeToUcs2(src[index], langInfo);
} else {
result = GSM7_BIT_TO_UC_S2[src[index]];
}
return index;
}
uint16_t TextCoder::EscapeToUcs2(const uint8_t srcText, const MsgLangInfo &langInfo)
{
uint16_t result = 0;
if (langInfo.bSingleShift) {
TELEPHONY_LOGI("National Language Single Shift [%{public}d]", langInfo.singleLang);
switch (langInfo.singleLang) {
case MSG_ID_TURKISH_LANG:
GetTurkishSingleToUcs2(srcText, result);
break;
case MSG_ID_SPANISH_LANG:
GetSpanishSingleToUcs2(srcText, result);
break;
case MSG_ID_PORTUGUESE_LANG:
GetPortuSingleToUcs2(srcText, result);
break;
default:
GetGsm7BitExtToUcs2(srcText, result);
break;
}
} else {
GetGsm7BitExtToUcs2(srcText, result);
}
return result;
}
WCHAR TextCoder::GetUCS2Value(uint32_t charset)
{
if (charset < 0 || charset >= GSM7_DEFLIST_LEN) {
return 0;
}
return GSM7_BIT_TO_UC_S2[charset];
}
void TextCoder::GetTurkishSingleToUcs2(const uint8_t &srcText, uint16_t &result)
{
const WCHAR turkishSingleToUcs2[] = { 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x000C, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005E, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x001B, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x007B, 0x007D, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005C, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005B, 0x007E, 0x005D, 0x0020, 0x007C,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x011E, 0x0020, 0x0130, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x015E, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00E7, 0x0020, 0x20AC, 0x0020, 0x011F, 0x0020, 0x0131, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x015F, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 };
result = turkishSingleToUcs2[srcText];
}
void TextCoder::GetSpanishSingleToUcs2(const uint8_t &srcText, uint16_t &result)
{
const WCHAR spanishSingleToUcs2[] = { 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x00E7, 0x000C, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005E, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x001B, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x007B, 0x007D, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005C, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005B, 0x007E, 0x005D, 0x0020, 0x007C,
0x00C1, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00CD, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x00D3, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00DA, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x00E1, 0x0020, 0x0020, 0x0020, 0x20AC, 0x0020, 0x0020, 0x0020, 0x00ED, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x00F3, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00FA, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 };
result = spanishSingleToUcs2[srcText];
}
void TextCoder::GetGsm7BitExtToUcs2(const uint8_t &srcText, uint16_t &result)
{
const WCHAR gsm7BitExtToUcs2[] = { 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x000C, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005E, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x001B, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x007B, 0x007D, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005C, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005B, 0x007E, 0x005D, 0x0020, 0x007C, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x20AC, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 };
result = gsm7BitExtToUcs2[srcText];
}
void TextCoder::GetPortuSingleToUcs2(const uint8_t &srcText, uint16_t &result)
{
const WCHAR portuSingleToUcs2[] = { 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00EA, 0x0020, 0x0020, 0x0020, 0x00E7,
0x000C, 0x00D4, 0x00F4, 0x0020, 0x00C1, 0x00E1, 0x0020, 0x0020, 0x03A6, 0x0393, 0x005E, 0x03A9, 0x03A0, 0x03A8,
0x03A3, 0x0398, 0x0020, 0x001B, 0x0020, 0x0020, 0x0020, 0x00CA, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x007B, 0x007D, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005C, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x005B, 0x007E, 0x005D, 0x0020, 0x007C, 0x00C0,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00CD, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00D3,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00DA, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00C3, 0x00D5, 0x0020,
0x0020, 0x0020, 0x0020, 0x00C2, 0x0020, 0x0020, 0x0020, 0x20AC, 0x0020, 0x0020, 0x0020, 0x00ED, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x00F3, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x00FA, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x00E3, 0x00F5, 0x0020, 0x0020, 0x00E2 };
result = portuSingleToUcs2[srcText];
}
}
}