1 /*
2 * Copyright (C) 2024 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 #ifndef OHOS_ARCH_LITE
16 #include <unicode/ucnv.h>
17 #endif // OHOS_ARCH_LITE
18 #include <iostream>
19 #include <string>
20 #include <cstring>
21 #include <cstdlib>
22 #include <securec.h>
23 #include "wifi_code_convert.h"
24
25 namespace OHOS {
26 namespace Wifi {
IsUtf8(const std::string & stf)27 bool WifiCodeConvertUtil::IsUtf8(const std::string &stf)
28 {
29 return Utf8Check(stf.c_str(), stf.length());
30 }
31
Utf8Check(const char * str,size_t length)32 bool WifiCodeConvertUtil::Utf8Check(const char *str, size_t length)
33 {
34 size_t i = 0;
35 int32_t nBytes = 0;
36 unsigned char chr = 0;
37 while (i < length) {
38 chr = *(str + i);
39 if (!IsUtf8Char(chr, nBytes)) {
40 return false;
41 }
42 i++;
43 }
44 return true;
45 }
46
47 const unsigned char MASK_80 = 0x80;
48 const unsigned char MASK_C0 = 0xC0;
49 const int MIN_BYTES = 2;
50 const int MAX_BYTES = 6;
IsUtf8Char(unsigned char chr,int32_t & nBytes)51 bool WifiCodeConvertUtil::IsUtf8Char(unsigned char chr, int32_t &nBytes)
52 {
53 if (nBytes == 0) {
54 if ((chr & MASK_80) == 0) {
55 return true;
56 }
57 while ((chr & MASK_80) == MASK_80) {
58 chr <<= 1;
59 nBytes++;
60 }
61
62 if (nBytes < MIN_BYTES || nBytes > MAX_BYTES) {
63 return false;
64 }
65 nBytes--;
66 } else {
67 if ((chr & MASK_C0) != MASK_80) {
68 return false;
69 }
70 nBytes--;
71 }
72 return true;
73 }
74
GbkToUtf8(const std::string & strGbk)75 std::string WifiCodeConvertUtil::GbkToUtf8(const std::string &strGbk)
76 {
77 #ifdef OHOS_ARCH_LITE
78 return strGbk;
79 #else
80 if (strGbk.length() == 0 || IsUtf8(strGbk)) {
81 return strGbk;
82 }
83 std::string result = Convert(strGbk, "gb2312", "utf8");
84 if (result.length() == 0) {
85 return strGbk;
86 }
87 return result;
88 #endif // OHOS_ARCH_LITE
89 }
90
Utf8ToGbk(const std::string & strUtf8)91 std::string WifiCodeConvertUtil::Utf8ToGbk(const std::string &strUtf8)
92 {
93 #ifdef OHOS_ARCH_LITE
94 return strUtf8;
95 #else
96 if (strUtf8.length() == 0 || !IsUtf8(strUtf8)) {
97 return strUtf8;
98 }
99
100 std::string result = Convert(strUtf8, "utf8", "gb2312");
101 if (result.length() == 0) {
102 return strUtf8;
103 }
104 return result;
105 #endif // OHOS_ARCH_LITE
106 }
107
Convert(const std::string & str,const std::string & fromCharset,const std::string & toCharset)108 std::string WifiCodeConvertUtil::Convert(const std::string &str, const std::string &fromCharset,
109 const std::string &toCharset)
110 {
111 #ifdef OHOS_ARCH_LITE
112 return str;
113 #else
114 UErrorCode status = U_ZERO_ERROR;
115 int32_t resultlen = ucnv_convert(toCharset.c_str(), fromCharset.c_str(), nullptr, 0, str.c_str(),
116 str.length(), &status);
117 std::unique_ptr<char[]> result = std::make_unique<char[]>(resultlen + 1);
118 memset_s(result.get(), resultlen + 1, 0, resultlen + 1);
119 status = U_ZERO_ERROR;
120 ucnv_convert(toCharset.c_str(), fromCharset.c_str(), result.get(), resultlen + 1,
121 str.c_str(), str.length(), &status);
122 if (U_FAILURE(status)) {
123 return str;
124 }
125 return std::string(result.get());
126 #endif // OHOS_ARCH_LITE
127 }
128 } // namespace Wifi
129 } // namespace OHOS
130