• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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 "codec_cov.h"
17 
18 #include <memory>
19 #include <iostream>
20 #ifdef _WIN32
21 #include <windows.h>
22 #endif
23 
24 namespace SysTuning {
25 namespace base {
PreNum(unsigned char byte)26 int32_t PreNum(unsigned char byte)
27 {
28     constexpr uint32_t BITS = 8;
29     unsigned char mask = 0x80;
30     int32_t num = 0;
31     for (uint32_t i = 0; i < BITS; i++) {
32         if ((byte & mask) == mask) {
33             mask = mask >> 1;
34             num++;
35         } else {
36             break;
37         }
38     }
39     return num;
40 }
41 
IsUTF8(const uint8_t * data,int32_t len)42 bool IsUTF8(const uint8_t *data, int32_t len)
43 {
44     constexpr uint8_t mask = 0x80;
45     constexpr uint8_t firstByte = 0xc0;
46     constexpr int32_t target = 2;
47     int32_t num = 0;
48     int32_t i = 0;
49     while (i < len) {
50         if ((data[i] & mask) == 0x00) {
51             i++;
52             continue;
53         }
54         if ((num = PreNum(data[i])) <= target) {
55             return false;
56         }
57         i++;
58         for (int32_t j = 0; j < num - 1; j++) {
59             if ((data[i] & firstByte) != mask) {
60                 return false;
61             }
62             i++;
63         }
64     }
65     return true;
66 }
67 
IsGBK(const uint8_t * data,int32_t len)68 bool IsGBK(const uint8_t *data, int32_t len)
69 {
70     constexpr int32_t step = 2;
71     constexpr uint8_t asciiEnd = 0x7f;
72     constexpr uint8_t firstByte = 0x81;
73     constexpr uint8_t firstByteEnd = 0xfe;
74     constexpr uint8_t secondByteOne = 0x40;
75     constexpr uint8_t secondByteTwoEnd = 0xfe;
76     constexpr uint8_t gbkMask = 0x7f;
77     int32_t i = 0;
78     while (i < len) {
79         if (data[i] <= asciiEnd) {
80             i++;
81             continue;
82         } else {
83             if (data[i] >= firstByte && data[i] <= firstByteEnd && data[i + 1] >= secondByteOne &&
84                 data[i + 1] <= secondByteTwoEnd && data[i + 1] != gbkMask) {
85                 i += step;
86                 continue;
87             } else {
88                 return false;
89             }
90         }
91     }
92     return true;
93 }
94 
GetCoding(const uint8_t * data,int32_t len)95 CODING GetCoding(const uint8_t *data, int32_t len)
96 {
97     CODING coding;
98     if (IsUTF8(data, len)) {
99         coding = UTF8;
100     } else if (IsGBK(data, len)) {
101         coding = GBK;
102     } else {
103         coding = UNKOWN;
104     }
105     return coding;
106 }
107 
108 #ifdef _WIN32
GbkToUtf8(const char * srcStr)109 std::string GbkToUtf8(const char *srcStr)
110 {
111     int32_t len = MultiByteToWideChar(CP_ACP, 0, srcStr, -1, NULL, 0);
112     std::unique_ptr<wchar_t[]> wstr = std::make_unique<wchar_t[]>(len + 1);
113     MultiByteToWideChar(CP_ACP, 0, srcStr, -1, wstr.get(), len);
114     len = WideCharToMultiByte(CP_UTF8, 0, wstr.get(), -1, NULL, 0, NULL, NULL);
115     std::unique_ptr<char[]> str = std::make_unique<char[]>(len + 1);
116     WideCharToMultiByte(CP_UTF8, 0, wstr.get(), -1, str.get(), len, NULL, NULL);
117     return std::string(str.get());
118 }
Utf8ToGbk(const char * srcStr)119 std::string Utf8ToGbk(const char *srcStr)
120 {
121     int32_t len = MultiByteToWideChar(CP_UTF8, 0, srcStr, -1, NULL, 0);
122     std::unique_ptr<wchar_t[]> wstr = std::make_unique<wchar_t[]>(len + 1);
123     MultiByteToWideChar(CP_UTF8, 0, srcStr, -1, wstr.get(), len);
124     len = WideCharToMultiByte(CP_ACP, 0, wstr.get(), -1, NULL, 0, NULL, NULL);
125     std::unique_ptr<char[]> str = std::make_unique<char[]>(len + 1);
126     WideCharToMultiByte(CP_ACP, 0, wstr.get(), -1, str.get(), len, NULL, NULL);
127     return std::string(str.get());
128 }
129 /** @fn        std::wstring String2WString(const std::string& strInput)
130  *  @brief    string转换为wstring
131  *  @param    (IN) const std::string&
132  *  @return    std::wstring
133  */
String2WString(const std::string & strInput)134 std::wstring String2WString(const std::string &strInput)
135 {
136     auto codePage = IsGBK(reinterpret_cast<const uint8_t *>(strInput.c_str()), strInput.length()) ? CP_ACP : CP_UTF8;
137     if (strInput.empty()) {
138         std::cout << "strInput is empty" << std::endl;
139         return L"";
140     }
141 
142     // 获取待转换的数据的长度
143     int len_in = MultiByteToWideChar(codePage, 0, (LPCSTR)strInput.c_str(), -1, NULL, 0);
144     if (len_in <= 0) {
145         std::cout << "The result of WideCharToMultiByte is Invalid!" << std::endl;
146         return L"";
147     }
148 
149     // 为输出数据申请空间
150     std::wstring wstr_out;
151     wstr_out.resize(len_in - 1, L'\0');
152 
153     // 数据格式转换
154     int to_result = MultiByteToWideChar(codePage, 0, (LPCSTR)strInput.c_str(), -1, (LPWSTR)wstr_out.c_str(), len_in);
155     // 判断转换结果
156     if (0 == to_result) {
157         std::cout << "Can't transfer String to WString" << std::endl;
158     }
159 
160     return wstr_out;
161 }
162 #endif
163 } // namespace base
164 } // namespace SysTuning
165