• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ConvertTo 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 #include "sim_utils.h"
17 
18 using namespace std;
19 
20 namespace OHOS {
21 namespace Telephony {
HexCharConvertToInt(char c)22 unsigned char SIMUtils::HexCharConvertToInt(char c)
23 {
24     if (c >= '0' && c <= '9') {
25         return (c - '0');
26     } else if (c >= 'A' && c <= 'F') {
27         return (c - 'A' + DECIMAL_MAX);
28     } else if (c >= 'a' && c <= 'f') {
29         return (c - 'a' + DECIMAL_MAX);
30     }
31     return 0;
32 }
33 
HexStringConvertToBytes(const std::string & s,int & byteslen)34 std::shared_ptr<unsigned char> SIMUtils::HexStringConvertToBytes(const std::string &s, int &byteslen)
35 {
36     if (s.empty()) {
37         return nullptr;
38     }
39     int id = 0;
40     int sz = s.length();
41     if (sz % HALF_LEN != 0) {
42         return nullptr;
43     }
44     int outlen = sz / HALF_LEN;
45     byteslen = outlen;
46     if (outlen == 0) {
47         return nullptr;
48     }
49     unsigned char *cache = (unsigned char *)calloc(outlen, sizeof(unsigned char));
50     if (cache == nullptr) {
51         return nullptr;
52     }
53     std::shared_ptr<unsigned char> ptr(cache, [](unsigned char *ptr) { free(ptr); });
54     unsigned char *ret = ptr.get();
55     for (int i = 0; i < sz; i += HALF_LEN) {
56         id = i / HALF_LEN;
57         ret[id] =
58             (unsigned char)((HexCharConvertToInt(s.at(i)) << HALF_BYTE_LEN) | HexCharConvertToInt(s.at(i + 1)));
59     }
60     return ptr;
61 }
62 
BytesConvertToHexString(const unsigned char * bytes,int byteLen)63 std::string SIMUtils::BytesConvertToHexString(const unsigned char *bytes, int byteLen)
64 {
65     if (bytes == nullptr) {
66         return "";
67     }
68     std::string str = "";
69     for (int i = 0; i < byteLen; i++) {
70         int b = 0;
71         b = 0x0f & (bytes[i] >> HALF_BYTE_LEN);
72         str.push_back(HEX_CHARS[b]);
73         b = 0x0f & bytes[i];
74         str.push_back(HEX_CHARS[b]);
75     }
76     return str;
77 }
78 
ArrayCopy(const unsigned char * src,int srcPos,unsigned char * dest,int destPos,int length)79 void SIMUtils::ArrayCopy(const unsigned char *src, int srcPos, unsigned char *dest, int destPos, int length)
80 {
81     src += srcPos;
82     dest += destPos;
83     for (int i = 0; i < length; i++) {
84         dest[i] = src[i];
85     }
86 }
87 
IsShowableAscii(char c)88 bool SIMUtils::IsShowableAscii(char c)
89 {
90     int asciiFirst = 0x20;
91     int asciiLast = 0x7E;
92     return (asciiFirst <= c && c <= asciiLast) || c == '\r' || c == '\n';
93 }
94 
IsShowableAsciiOnly(const std::string & str)95 bool SIMUtils::IsShowableAsciiOnly(const std::string &str)
96 {
97     int len = str.length();
98     for (int i = 0; i < len; i++) {
99         if (!IsShowableAscii(str.at(i))) {
100             return false;
101         }
102     }
103     return true;
104 }
105 
CharsConvertToChar16(const unsigned char * charBytes,int charBytesLen,int & outChar16Len,bool bigEndian)106 std::shared_ptr<char16_t> SIMUtils::CharsConvertToChar16(
107     const unsigned char *charBytes, int charBytesLen, int &outChar16Len, bool bigEndian)
108 {
109     if (charBytes == nullptr || charBytesLen == 0) {
110         return nullptr;
111     }
112 
113     int id = 0;
114     if (charBytesLen % HALF_LEN != 0) {
115         return nullptr;
116     }
117 
118     int outLen = charBytesLen / HALF_LEN;
119     outChar16Len = outLen;
120     if (outChar16Len == 0) {
121         return nullptr;
122     }
123     char16_t *cache = (char16_t *)calloc(outLen, sizeof(char16_t));
124     if (cache == nullptr) {
125         return nullptr;
126     }
127     std::shared_ptr<char16_t> ptr(cache, [](char16_t *ptr) { free(ptr); });
128     char16_t *ret = ptr.get();
129     for (int i = 0; i < charBytesLen; i += HALF_LEN) {
130         id = i / HALF_LEN;
131         char16_t high = charBytes[i];
132         char16_t low = charBytes[i + 1];
133         if (bigEndian) {
134             ret[id] = (char16_t)((high << BYTE_LENGTH) | low);
135         } else {
136             ret[id] = (char16_t)((low << BYTE_LENGTH) | high);
137         }
138     }
139     return ptr;
140 }
141 
BcdPlmnConvertToString(const std::string & data,int offset)142 std::string SIMUtils::BcdPlmnConvertToString(const std::string &data, int offset)
143 {
144     (void)data;
145     (void)offset;
146     return "";
147 }
148 
DiallingNumberStringFieldConvertToString(std::shared_ptr<unsigned char> array,int offset,int length,int offPos)149 std::string SIMUtils::DiallingNumberStringFieldConvertToString(
150     std::shared_ptr<unsigned char> array, int offset, int length, int offPos)
151 {
152     if (length <= 0 || array == nullptr) {
153         return "";
154     }
155     unsigned char *data = array.get();
156 
157     if (data[offset] == (unsigned char)CHINESE_FLAG) {
158         TELEPHONY_LOGI("DiallingNumberStringFieldToString: start 16be decode");
159         int ucslen = (length - 1) / HALF_LEN;
160         int outlen = 0;
161         std::shared_ptr<char16_t> cs = CharsConvertToChar16(data + 1, ucslen * HALF_LEN, outlen, true);
162         std::string ns = "";
163         std::u16string hs(cs.get(), 0, outlen);
164         std::u16string rtl = u"";
165         if (!hs.empty()) {
166             ucslen = hs.length();
167             wchar_t c = L'\uFFFF';
168             while (ucslen > 0 && hs.at(ucslen - 1) == c) {
169                 ucslen--;
170             }
171             rtl = hs.substr(0, ucslen);
172             std::string uz = Str16ToStr8(hs);
173             ns = Str16ToStr8(rtl);
174             TELEPHONY_LOGI("16be result %{public}s, %{public}s", uz.c_str(), ns.c_str());
175             return ns;
176         }
177     } else {
178         int i = 0;
179         for (i = offset; i < offset + length; i++) {
180             int c = data[i] & BYTE_VALUE;
181             if (c == BYTE_VALUE) {
182                 break;
183             }
184         }
185         i -= offset;
186         std::string str((char *)data, offset, i);
187         TELEPHONY_LOGI("8bit decode result");
188         if (!str.empty()) {
189             return str;
190         }
191     }
192     return UcsCodeConvertToString(array, offset, length, offPos);
193 }
194 
UcsCodeConvertToString(std::shared_ptr<unsigned char> array,int offset,int length,int offPos)195 std::string SIMUtils::UcsCodeConvertToString(
196     std::shared_ptr<unsigned char> array, int offset, int length, int offPos)
197 {
198     bool isucs2 = false;
199     char base = '\0';
200     int len = 0;
201     unsigned char *data = array.get();
202     if (length >= START_POS && data[offset] == (unsigned char)UCS_FLAG) {
203         len = data[offset + 1] & BYTE_VALUE;
204         if (len > length - START_POS) {
205             len = length - START_POS;
206         }
207         base = (char)((data[offset + HALF_LEN] & BYTE_VALUE) << BYTE_LESS);
208         offset += START_POS;
209         isucs2 = true;
210     } else if (length >= END_POS && data[offset] == (unsigned char)UCS_WIDE_FLAG) {
211         len = data[offset + 1] & BYTE_VALUE;
212         if (len > length - END_POS)
213             len = length - END_POS;
214 
215         base =
216             (char)(((data[offset + HALF_LEN] & BYTE_VALUE) << BYTE_BIT) | (data[offset + START_POS] & BYTE_VALUE));
217         offset += END_POS;
218         isucs2 = true;
219     }
220 
221     if (isucs2) {
222         std::string retuc = "";
223         while (len > 0) {
224             if (data[offset] < 0) {
225                 retuc.push_back((char)(base + (data[offset] & 0x7F)));
226                 offset++;
227                 len--;
228             }
229             int count = 0;
230             int id = offset + count;
231             while ((count < len) && (data[id] >= 0)) {
232                 count++;
233                 id = offset + count;
234             }
235             TELEPHONY_LOGI("start 8bit decode");
236             offset += count;
237             len -= count;
238         }
239         TELEPHONY_LOGI("isucs2 decode result %{public}s", retuc.c_str());
240         return retuc;
241     }
242 
243     std::string defaultCharset = "";
244     TELEPHONY_LOGI("UcsCodeConvertToString finished");
245     return defaultCharset;
246 }
247 
Trim(std::string & str)248 std::string SIMUtils::Trim(std::string& str)
249 {
250     string::size_type pos = str.find_last_not_of(' ');
251     if (pos != string::npos) {
252         str.erase(pos + POS_NOT_BLANK);
253         pos = str.find_first_not_of(' ');
254         if (pos != string::npos) {
255             str.erase(0, pos);
256         }
257     } else {
258         str.erase(str.begin(), str.end());
259     }
260     return str;
261 }
262 } // namespace Telephony
263 } // namespace OHOS