1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_SIM_CHAR_DECODE_H
17 #define OHOS_SIM_CHAR_DECODE_H
18 
19 #include <cstring>
20 #include <stdlib.h>
21 #include <string>
22 #include <map>
23 #include <iostream>
24 #include <iomanip>
25 #include <type_traits>
26 #include <memory>
27 
28 #include "securec.h"
29 #include "sim_constant.h"
30 #include "telephony_log_wrapper.h"
31 
32 namespace OHOS {
33 namespace Telephony {
34 static const int MAX_CHINESE_NAME = 6;
35 static const int MAX_ENGLISH_NAME = 12;
36 static const int EMPTY = 0;
37 static const int CHINESE_FLAG = 0x80;
38 static const int CHAR_LENGTH = 2;
39 static const int CHAR16_LENGTH = 4;
40 static const int CHAR32_LENGTH = 8;
41 static const int ENCODE_CHAR_LENGTH = 100;
42 static const int BYTE_BIT = 8;
43 static const int BYTE_LESS = 7;
44 
45 class SimCharDecode {
46 public:
47     SimCharDecode();
48     ~SimCharDecode();
49     static bool IsChineseString(const std::string &str);
50     template<typename tStringType, typename tTraits = typename tStringType::traits_type>
CharCodeToSequence(const tStringType & str,bool chinese)51     static std::string CharCodeToSequence(const tStringType &str, bool chinese)
52     {
53         using char_type = typename tTraits::char_type;
54         static_assert(std::is_same<char_type, char>::value || std::is_same<char_type, char16_t>::value ||
55                 std::is_same<char_type, char32_t>::value,
56             "error");
57         using unsigned_char_type = typename std::make_unsigned<char_type>::type;
58         using unsigned_int_type = typename std::make_unsigned<typename tTraits::int_type>::type;
59         int w = std::is_same<char, char_type>::value ? CHAR_LENGTH :
60             (std::is_same<char16_t, char_type>::value ? CHAR16_LENGTH : CHAR32_LENGTH);
61         char tempChar[ENCODE_CHAR_LENGTH] = {0};
62         int contentLen = sizeof(tempChar);
63         int flagLen = 0;
64         int maxNumber = 0;
65         if (memset_s(tempChar, contentLen, 0x00, contentLen) != EOK) {
66             TELEPHONY_LOGE("DebugTpdu memset_s error");
67             return "";
68         }
69         if (chinese) {
70             char flag[] = "80";
71             if (strcat_s(tempChar, contentLen, flag) != EOK) {
72                 TELEPHONY_LOGE("DebugTpdu strcat_s error");
73                 return "";
74             }
75             flagLen = strlen(flag) * sizeof(char);
76             maxNumber = MAX_CHINESE_NAME;
77         } else {
78             maxNumber = MAX_ENGLISH_NAME;
79         }
80         int i = 0;
81         uint8_t step = w;
82         for (auto c : str) {
83             auto value = static_cast<unsigned_int_type>(static_cast<unsigned_char_type>(c));
84             const int len = contentLen - (i * step) - flagLen;
85             if (snprintf_s(tempChar + flagLen + (i * step), len - 1, len - 1,
86                 (step == CHAR16_LENGTH) ? "%04X" : "%02X", value) < 0) {
87                 TELEPHONY_LOGE("DebugTpdu snprintf_s error");
88                 return "";
89             }
90             i++;
91             if (i >= maxNumber) {
92                 break;
93             }
94         }
95         std::string result(tempChar);
96         return result;
97     }
98 
99 private:
100     static void EnableCountrySpecificEncodings();
101 };
102 } // namespace Telephony
103 } // namespace OHOS
104 
105 #endif // OHOS_SIM_CHAR_DECODE_H