• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "vcard_utils.h"
17 
18 #include <algorithm>
19 #include <fstream>
20 #include <iconv.h>
21 #include <numeric>
22 #include <regex>
23 #include <sstream>
24 
25 #include "base64.h"
26 #include "map"
27 #include "telephony_errors.h"
28 #include "telephony_log_wrapper.h"
29 #include "vcard_configuration.h"
30 #include "vcard_constant.h"
31 
32 namespace OHOS {
33 namespace Telephony {
34 namespace {
35 std::map<ImType, std::string> imLabelIdToType = { { ImType::IM_AIM, VCARD_TYPE_X_AIM },
36     { ImType::IM_MSN, VCARD_TYPE_X_MSN }, { ImType::IM_YAHOO, VCARD_TYPE_X_YAHOO },
37     { ImType::IM_ICQ, VCARD_TYPE_X_ICQ }, { ImType::IM_JABBER, VCARD_TYPE_X_JABBER },
38     { ImType::IM_SKYPE, VCARD_TYPE_X_SKYPE_USERNAME }, { ImType::IM_QQ, VCARD_TYPE_X_QQ },
39     { ImType::IM_HUANLIAO, VCARD_TYPE_X_HUANLIAO} };
40 std::map<PhoneVcType, std::string> phoneLabelIdToType = { { PhoneVcType::NUM_HOME, VCARD_PARAM_TYPE_CELL },
41     { PhoneVcType::NUM_MOBILE, VCARD_PARAM_TYPE_HOME }, { PhoneVcType::NUM_WORK, VCARD_PARAM_TYPE_WORK },
42     { PhoneVcType::NUM_PAGER, VCARD_PARAM_TYPE_PAGER }, { PhoneVcType::NUM_OTHER, VCARD_PARAM_TYPE_VOICE },
43     { PhoneVcType::NUM_CALLBACK, VCARD_PARAM_PHONE_EXTRA_TYPE_CALLBACK },
44     { PhoneVcType::NUM_CAR, VCARD_PARAM_TYPE_CAR }, { PhoneVcType::NUM_COMPANY_MAIN, VCARD_PARAM_TYPE_WORK },
45     { PhoneVcType::NUM_ISDN, VCARD_PARAM_TYPE_ISDN }, { PhoneVcType::NUM_OTHER_FAX, VCARD_PARAM_TYPE_FAX },
46     { PhoneVcType::NUM_RADIO, VCARD_PARAM_PHONE_EXTRA_TYPE_RADIO }, { PhoneVcType::NUM_TELEX, VCARD_PARAM_TYPE_TLX },
47     { PhoneVcType::NUM_TTY_TDD, VCARD_PARAM_PHONE_EXTRA_TYPE_TTY_TDD },
48     { PhoneVcType::NUM_ASSISTANT, VCARD_PARAM_PHONE_EXTRA_TYPE_ASSISTANT },
49     { PhoneVcType::NUM_MMS, VCARD_PARAM_TYPE_MSG }, { PhoneVcType::NUM_MAIN, VCARD_PARAM_TYPE_PREF }};
50 std::map<std::string, PhoneVcType> typeToPhoneTypeMap = { { VCARD_PARAM_TYPE_CAR, PhoneVcType::NUM_CAR },
51     { VCARD_PARAM_TYPE_PAGER, PhoneVcType::NUM_PAGER }, { VCARD_PARAM_TYPE_ISDN, PhoneVcType::NUM_ISDN },
52     { VCARD_PARAM_TYPE_HOME, PhoneVcType::NUM_MOBILE }, { VCARD_PARAM_TYPE_WORK, PhoneVcType::NUM_WORK },
53     { VCARD_PARAM_TYPE_CELL, PhoneVcType::NUM_HOME },
54     { VCARD_PARAM_PHONE_EXTRA_TYPE_CALLBACK, PhoneVcType::NUM_CALLBACK },
55     { VCARD_PARAM_PHONE_EXTRA_TYPE_RADIO, PhoneVcType::NUM_RADIO },
56     { VCARD_PARAM_PHONE_EXTRA_TYPE_TTY_TDD, PhoneVcType::NUM_TTY_TDD },
57     { VCARD_PARAM_PHONE_EXTRA_TYPE_ASSISTANT, PhoneVcType::NUM_ASSISTANT },
58     { VCARD_PARAM_TYPE_VOICE, PhoneVcType::NUM_OTHER } };
59 } // namespace
60 
EncodeBase64(const std::string & input)61 std::string VCardUtils::EncodeBase64(const std::string &input)
62 {
63     std::shared_ptr<std::string> encodedDataString = OHOS::Telephony::Base64::Encode(input);
64     if (encodedDataString == nullptr) {
65         return "";
66     }
67     return *encodedDataString;
68 }
69 
DecodeBase64(const std::string & input)70 std::string VCardUtils::DecodeBase64(const std::string &input)
71 {
72     auto decodedDataString = OHOS::Telephony::Base64::Decode(input);
73     if (decodedDataString == nullptr) {
74         return "";
75     }
76     return std::string(decodedDataString->begin(), decodedDataString->end());
77 }
78 
DecodeBase64NoWrap(const std::string & input)79 std::string VCardUtils::DecodeBase64NoWrap(const std::string &input)
80 {
81     const std::string LF_SIGN = "\n";
82     std::string::size_type pos;
83     std::string rawStr = input;
84     while ((pos = rawStr.find(LF_SIGN)) != std::string::npos) {
85         rawStr.erase(pos, LF_SIGN.length());
86     }
87     return DecodeBase64(rawStr);
88 }
89 
EqualsIgnoreCase(const std::string & str1,const std::string & str2)90 bool VCardUtils::EqualsIgnoreCase(const std::string &str1, const std::string &str2)
91 {
92     std::string copy1 = str1;
93     std::string copy2 = str2;
94 
95     std::transform(copy1.begin(), copy1.end(), copy1.begin(), ::tolower);
96     std::transform(copy2.begin(), copy2.end(), copy2.begin(), ::tolower);
97 
98     return copy1 == copy2;
99 }
100 
Split(const std::string & input,const std::string & delimiter)101 std::vector<std::string> VCardUtils::Split(const std::string &input, const std::string &delimiter)
102 {
103     std::vector<std::string> result;
104     std::size_t pos = 0;
105     std::size_t delimiterPos;
106 
107     while ((delimiterPos = input.find(delimiter, pos)) != std::string::npos) {
108         std::string token = input.substr(pos, delimiterPos - pos);
109         result.push_back(token);
110         pos = delimiterPos + delimiter.size();
111     }
112 
113     if (pos < input.size()) {
114         std::string token = input.substr(pos);
115         result.push_back(token);
116     }
117 
118     return result;
119 }
120 
Trim(std::string & str)121 std::string VCardUtils::Trim(std::string &str)
122 {
123     std::string::size_type pos1 = str.find_first_not_of(" \t\n\r\f\v");
124     std::string::size_type pos2 = str.find_last_not_of(" \t\n\r\f\v");
125     if (pos1 != std::string::npos && pos2 != std::string::npos) {
126         str = str.substr(pos1, pos2 - pos1 + 1);
127     } else {
128         str.clear();
129     }
130 
131     return str;
132 }
133 
ToUpper(const std::string & str)134 std::string VCardUtils::ToUpper(const std::string &str)
135 {
136     std::string temp = str;
137     for (char &c : temp) {
138         c = std::toupper(c);
139     }
140     return temp;
141 }
142 
StartWith(const std::string & str,const std::string & prefix)143 bool VCardUtils::StartWith(const std::string &str, const std::string &prefix)
144 {
145     if (str.length() < prefix.length()) {
146         return false;
147     }
148     return str.substr(0, prefix.length()) == prefix;
149 }
150 
EndWith(const std::string & fullString,const std::string & ending)151 bool VCardUtils::EndWith(const std::string &fullString, const std::string &ending)
152 {
153     if (fullString.length() < ending.length()) {
154         return false;
155     }
156 
157     std::string extractedEnding = fullString.substr(fullString.length() - ending.length());
158 
159     return extractedEnding == ending;
160 }
161 
ConvertCharset(const std::string & input,const std::string & fromCharset,const std::string & toCharset,int32_t & errorCode)162 std::string VCardUtils::ConvertCharset(
163     const std::string &input, const std::string &fromCharset, const std::string &toCharset, int32_t &errorCode)
164 {
165     iconv_t converter = iconv_open(toCharset.c_str(), fromCharset.c_str());
166     if (converter == (iconv_t)(-1)) {
167         TELEPHONY_LOGE("ConvertCharset_old open fail");
168         errorCode = TELEPHONY_ERR_VCARD_FILE_INVALID;
169         return "";
170     }
171 
172     size_t inBytes = input.size();
173     size_t outBytes = inBytes * 4; // Allocate enough space for the worst-case scenario
174     char *inBuf = const_cast<char *>(input.c_str());
175     char *outBuf = new char[outBytes];
176     char *outBufPtr = outBuf;
177     if (iconv(converter, &inBuf, &inBytes, &outBufPtr, &outBytes) == (size_t)(-1)) {
178         TELEPHONY_LOGE("ConvertCharset open fail");
179         errorCode = TELEPHONY_ERR_VCARD_FILE_INVALID;
180         delete[] outBuf;
181         iconv_close(converter);
182         return "";
183     }
184     std::string output(outBuf, outBufPtr - outBuf);
185     delete[] outBuf;
186     iconv_close(converter);
187     return output;
188 }
189 
CreateFileName()190 std::string VCardUtils::CreateFileName()
191 {
192     std::time_t now = std::time(nullptr);
193     std::tm *timeinfo = std::localtime(&now);
194     std::ostringstream oss;
195     oss << std::put_time(timeinfo, VCARD_TIME_FORMAT);
196     std::string fileName = oss.str() + ".vcf";
197     return fileName;
198 }
199 
SaveFile(const std::string & fileStr,const std::string & path)200 void VCardUtils::SaveFile(const std::string &fileStr, const std::string &path)
201 {
202     std::ofstream file(path, std::ios::trunc | std::ios::binary);
203     if (file.is_open()) {
204         file.write(fileStr.data(), fileStr.size());
205     }
206 }
207 
IsWrapPrintableAscii(std::vector<std::string> strs)208 bool VCardUtils::IsWrapPrintableAscii(std::vector<std::string> strs)
209 {
210     for (auto str : strs) {
211         for (char ch : str) {
212             if (!(IsPrintableAscii(ch) || ch == '\r' || ch == '\n')) {
213                 return false;
214             }
215         }
216     }
217     return true;
218 }
219 
IsPrintableAscii(std::vector<std::string> strs)220 bool VCardUtils::IsPrintableAscii(std::vector<std::string> strs)
221 {
222     for (auto it : strs) {
223         if (!IsPrintableAscii(it)) {
224             return false;
225         }
226     }
227     return true;
228 }
229 
IsPrintableAscii(const std::string & str)230 bool VCardUtils::IsPrintableAscii(const std::string &str)
231 {
232     for (char ch : str) {
233         if (!IsPrintableAscii(ch)) {
234             return false;
235         }
236     }
237     return true;
238 }
239 
IsPrintableAscii(char ch)240 bool VCardUtils::IsPrintableAscii(char ch)
241 {
242     return std::isprint(static_cast<unsigned char>(ch));
243 }
244 
IsNum(const std::string & str)245 bool VCardUtils::IsNum(const std::string &str)
246 {
247     if (str.empty()) {
248         return false;
249     }
250     for (char ch : str) {
251         if (!std::isdigit(ch)) {
252             return false;
253         }
254     }
255     return true;
256 }
257 
GetTypeFromImLabelId(std::string labelId)258 std::string VCardUtils::GetTypeFromImLabelId(std::string labelId)
259 {
260     if (!IsNum(labelId)) {
261         return "";
262     }
263     int32_t num = std::stoi(labelId);
264     auto it = imLabelIdToType.find(static_cast<ImType>(num));
265     if (it != imLabelIdToType.end()) {
266         return it->second;
267     }
268     return "";
269 }
270 
GetLabelIdFromImType(std::string type)271 int32_t VCardUtils::GetLabelIdFromImType(std::string type)
272 {
273     if (type.empty()) {
274         return static_cast<int32_t>(ImType::INVALID_LABEL_ID);
275     }
276     if (type == VCARD_TYPE_X_AIM) {
277         return static_cast<int32_t>(ImType::IM_AIM);
278     } else if (type == VCARD_TYPE_X_MSN) {
279         return static_cast<int32_t>(ImType::IM_MSN);
280     } else if (type == VCARD_TYPE_X_YAHOO) {
281         return static_cast<int32_t>(ImType::IM_YAHOO);
282     } else if (type == VCARD_TYPE_X_ICQ) {
283         return static_cast<int32_t>(ImType::IM_ICQ);
284     } else if (type == VCARD_TYPE_X_JABBER) {
285         return static_cast<int32_t>(ImType::IM_JABBER);
286     } else if (type == VCARD_TYPE_X_QQ) {
287         return static_cast<int32_t>(ImType::IM_QQ);
288     } else if (type == VCARD_TYPE_X_SKYPE_USERNAME) {
289         return static_cast<int32_t>(ImType::IM_SKYPE);
290     } else if (type == VCARD_TYPE_X_HUANLIAO) {
291         return static_cast<int32_t>(ImType::IM_HUANLIAO);
292     } else {
293         return static_cast<int32_t>(ImType::CUSTOM_LABEL);
294     }
295 }
296 
GetTypeFromPhoneLabelId(std::string labelId)297 std::vector<std::string> VCardUtils::GetTypeFromPhoneLabelId(std::string labelId)
298 {
299     std::vector<std::string> paramTypes = {};
300     if (!IsNum(labelId) || labelId.size() > INT_64_LENTGH) {
301         return paramTypes;
302     }
303     int64_t num = std::stoll(labelId);
304     auto phoneType = static_cast<PhoneVcType>(num);
305     auto it = phoneLabelIdToType.find(phoneType);
306     if (it != phoneLabelIdToType.end()) {
307         paramTypes.push_back(it->second);
308         return paramTypes;
309     }
310     switch (phoneType) {
311         case PhoneVcType::NUM_FAX_HOME: {
312             paramTypes.push_back(VCARD_PARAM_TYPE_HOME);
313             paramTypes.push_back(VCARD_PARAM_TYPE_FAX);
314             return paramTypes;
315         }
316         case PhoneVcType::NUM_FAX_WORK: {
317             paramTypes.push_back(VCARD_PARAM_TYPE_WORK);
318             paramTypes.push_back(VCARD_PARAM_TYPE_FAX);
319             return paramTypes;
320         }
321         case PhoneVcType::NUM_WORK_MOBILE: {
322             paramTypes.push_back(VCARD_PARAM_TYPE_WORK);
323             paramTypes.push_back(VCARD_PARAM_TYPE_CELL);
324             return paramTypes;
325         }
326         case PhoneVcType::NUM_WORK_PAGER: {
327             paramTypes.push_back(VCARD_PARAM_TYPE_WORK);
328             paramTypes.push_back(VCARD_PARAM_TYPE_PAGER);
329             return paramTypes;
330         }
331         default:
332             break;
333     }
334     return paramTypes;
335 }
336 
TrimListToString(const std::vector<std::string> & strs)337 std::string VCardUtils::TrimListToString(const std::vector<std::string> &strs)
338 {
339     int32_t size = static_cast<int32_t>(strs.size());
340     std::string result;
341     if (size > 1) {
342         std::string init = "";
343         result = std::accumulate(strs.begin(), strs.end(), init,
344             [](std::string &str, const std::string &element) { return str + element + ";"; });
345     } else if (size == 1) {
346         return strs[0];
347     } else {
348         return "";
349     }
350     return result;
351 }
352 
HandleCh(char nextCh,std::string vcardType)353 std::string VCardUtils::HandleCh(char nextCh, std::string vcardType)
354 {
355     std::string unescapedString = "";
356     if (vcardType == VERSION_40) {
357         if (nextCh == 'n' || nextCh == 'N') {
358             unescapedString = "\n";
359         } else {
360             unescapedString = nextCh;
361         }
362     } else if (vcardType == VERSION_30) {
363         if (nextCh == 'n' || nextCh == 'N') {
364             unescapedString = "\n";
365         } else {
366             unescapedString = nextCh;
367         }
368     } else {
369         if (nextCh == '\\' || nextCh == ';' || nextCh == ':' || nextCh == ',') {
370             unescapedString = nextCh;
371         } else {
372             unescapedString = "";
373         }
374     }
375     return unescapedString;
376 }
377 
ConstructListFromValue(const std::string & value,std::string vcardType)378 std::vector<std::string> VCardUtils::ConstructListFromValue(const std::string &value, std::string vcardType)
379 {
380     std::vector<std::string> result;
381     std::string builder;
382     int32_t length = static_cast<int32_t>(value.length());
383     for (int32_t i = 0; i < length; i++) {
384         char ch = value[i];
385         if (ch == '\\' && i < length - 1) {
386             char nextCh = value[i + 1];
387             std::string unescapedString = HandleCh(nextCh, vcardType);
388             if (!unescapedString.empty()) {
389                 builder += unescapedString;
390                 i++;
391             } else {
392                 builder += ch;
393             }
394         } else if (ch == ';') {
395             result.push_back(builder);
396         } else {
397             builder += ch;
398         }
399     }
400     result.push_back(builder);
401     return result;
402 }
403 
HandleTypeAndLabel(int32_t & type,std::string & label,std::string number,std::string labelCandidate)404 void VCardUtils::HandleTypeAndLabel(int32_t &type, std::string &label, std::string number, std::string labelCandidate)
405 {
406     std::map<std::string, PhoneVcType>::iterator iter = typeToPhoneTypeMap.find(labelCandidate);
407     if (iter != typeToPhoneTypeMap.end()) {
408         PhoneVcType phoneType = iter->second;
409         int32_t typeCandidate = static_cast<int32_t>(phoneType);
410 
411         std::size_t indexOfAt = -1;
412         std::size_t found = number.find("@");
413         if (found != std::string::npos) {
414             indexOfAt = found;
415         }
416 
417         if ((typeCandidate == static_cast<int32_t>(PhoneVcType::NUM_PAGER) && 0 < indexOfAt &&
418                 indexOfAt < number.length() - 1) ||
419             type < 0 || type == static_cast<int32_t>(PhoneVcType::CUSTOM_LABEL) ||
420             type == static_cast<int32_t>(PhoneVcType::NUM_OTHER)) {
421             type = typeCandidate;
422         }
423     } else if (type < 0) {
424         type = static_cast<int32_t>(PhoneVcType::CUSTOM_LABEL);
425         label = labelCandidate;
426     }
427 }
428 
GetPhoneTypeFromStrings(const std::vector<std::string> & types,std::string number,std::tuple<int32_t,std::string> & result)429 void VCardUtils::GetPhoneTypeFromStrings(
430     const std::vector<std::string> &types, std::string number, std::tuple<int32_t, std::string> &result)
431 {
432     int32_t type = -1;
433     std::string label;
434     bool isFax = false;
435     bool hasPref = false;
436 
437     for (std::string typeStringOrg : types) {
438         std::string typeStringUpperCase = ToUpper(typeStringOrg);
439         if (typeStringUpperCase == VCARD_PARAM_TYPE_PREF) {
440             hasPref = true;
441         } else if (typeStringUpperCase == VCARD_PARAM_TYPE_FAX) {
442             isFax = true;
443         } else {
444             std::string labelCandidate;
445             if (StartWith(typeStringUpperCase, "X-") && type < 0) {
446                 labelCandidate = typeStringOrg.substr(VALUE_INDEX_TWO);
447             } else {
448                 labelCandidate = typeStringOrg;
449                 label = labelCandidate;
450             }
451             if (labelCandidate.length() == 0) {
452                 continue;
453             }
454             HandleTypeAndLabel(type, label, number, labelCandidate);
455         }
456     }
457 
458     if (type < 0) {
459         if (hasPref) {
460             type = static_cast<int32_t>(PhoneVcType::NUM_MAIN);
461         } else {
462             type = static_cast<int32_t>(PhoneVcType::NUM_HOME);
463         }
464     }
465 
466     if (isFax) {
467         if (type == static_cast<int32_t>(PhoneVcType::NUM_MOBILE)) {
468             type = static_cast<int32_t>(PhoneVcType::NUM_FAX_HOME);
469         } else if (type == static_cast<int32_t>(PhoneVcType::NUM_WORK)) {
470             type = static_cast<int32_t>(PhoneVcType::NUM_FAX_WORK);
471         } else if (type == static_cast<int32_t>(PhoneVcType::NUM_OTHER)) {
472             type = static_cast<int32_t>(PhoneVcType::NUM_OTHER_FAX);
473         }
474     }
475 
476     if (type == static_cast<int32_t>(PhoneVcType::CUSTOM_LABEL)) {
477         std::get<0>(result) = -1;
478         std::get<1>(result) = label;
479     } else {
480         std::get<0>(result) = type;
481         std::get<1>(result) = "-1";
482     }
483 }
484 
VcardtypeToInt(const std::string & vcardType)485 int32_t VCardUtils::VcardtypeToInt(const std::string &vcardType)
486 {
487     if (vcardType == VERSION_21) {
488         return VERSION_21_NUM;
489     } else if (vcardType == VERSION_30) {
490         return VERSION_30_NUM;
491     } else if (vcardType == VERSION_40) {
492         return VERSION_40_NUM;
493     }
494     return -1;
495 }
496 
FormatNumber(std::string source)497 std::string VCardUtils::FormatNumber(std::string source)
498 {
499     return source;
500 }
501 
GetPhoneNumberFormat(const int32_t vcardType)502 int32_t VCardUtils::GetPhoneNumberFormat(const int32_t vcardType)
503 {
504     if (VCardConfiguration::IsJapaneseDevice(vcardType)) {
505         return VCARD_PHONE_NUM_FORMAT_JAPAN;
506     } else {
507         return VCARD_PHONE_NUM_FORMAT_NANP;
508     }
509 }
510 
GetImageType(std::string bytes)511 std::string VCardUtils::GetImageType(std::string bytes)
512 {
513     if (bytes.empty()) {
514         return "";
515     }
516     int32_t length = static_cast<int32_t>(bytes.length());
517     int32_t gifTypeLength = VALUE_LEN_THREE;
518     if (length >= gifTypeLength && bytes[VALUE_INDEX_ZERO] == 'G' && bytes[1] == 'I' && bytes[VALUE_INDEX_TWO] == 'F') {
519         return "GIF";
520     }
521     int32_t pngTypeLength = VALUE_LEN_FOUR;
522     if (length >= pngTypeLength && bytes[VALUE_INDEX_ZERO] == static_cast<char>(0x89) &&
523         bytes[VALUE_INDEX_ONE] == 'P' && bytes[VALUE_INDEX_TWO] == 'N' && bytes[VALUE_INDEX_THREE] == 'G') {
524         return "PNG";
525     }
526     int32_t jpgTypeLength = VALUE_LEN_TWO;
527     if (length >= jpgTypeLength && bytes[VALUE_INDEX_ZERO] == static_cast<char>(0xff) &&
528         bytes[VALUE_INDEX_ONE] == static_cast<char>(0xd8)) {
529         return "JPEG";
530     }
531     return "";
532 }
533 
IsAllEmpty(std::vector<std::string> values)534 bool VCardUtils::IsAllEmpty(std::vector<std::string> values)
535 {
536     for (auto value : values) {
537         if (!value.empty()) {
538             return false;
539         }
540     }
541     return true;
542 }
543 
IsContainsInvisibleChar(const std::string & value)544 bool VCardUtils::IsContainsInvisibleChar(const std::string& value)
545 {
546     std::regex regexPattern("([\\x00-\\x1F]|\\x7F|[\\u0000-\\u001F]|\\u007F)");
547     return std::regex_search(value, regexPattern);
548 }
549 
GetOStreamSize(const std::ostringstream & oss)550 size_t VCardUtils::GetOStreamSize(const std::ostringstream &oss)
551 {
552     std::streambuf *buf = oss.rdbuf();
553     const std::streampos beg = buf->pubseekoff(0, std::ios_base::beg, std::ios_base::out);
554     const std::streampos end = buf->pubseekoff(0, std::ios_base::end, std::ios_base::out);
555     if (beg == -1 || end == -1) {
556         return oss.str().size();
557     }
558     return static_cast<size_t>(end - beg);
559 }
560 
561 } // namespace Telephony
562 } // namespace OHOS
563