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#ifdef _WIN32 20#include <windows.h> 21#endif 22 23namespace SysTuning { 24namespace base { 25int32_t PreNum(unsigned char byte) 26{ 27 constexpr uint32_t BITS = 8; 28 unsigned char mask = 0x80; 29 int32_t num = 0; 30 for (uint32_t i = 0; i < BITS; i++) { 31 if ((byte & mask) == mask) { 32 mask = mask >> 1; 33 num++; 34 } else { 35 break; 36 } 37 } 38 return num; 39} 40 41bool IsUTF8(const uint8_t *data, int32_t len) 42{ 43 constexpr uint8_t mask = 0x80; 44 constexpr uint8_t firstByte = 0xc0; 45 constexpr int32_t target = 2; 46 int32_t num = 0; 47 int32_t i = 0; 48 while (i < len) { 49 if ((data[i] & mask) == 0x00) { 50 i++; 51 continue; 52 } 53 if ((num = PreNum(data[i])) <= target) { 54 return false; 55 } 56 i++; 57 for (int32_t j = 0; j < num - 1; j++) { 58 if ((data[i] & firstByte) != mask) { 59 return false; 60 } 61 i++; 62 } 63 } 64 return true; 65} 66 67bool IsGBK(const uint8_t *data, int32_t len) 68{ 69 constexpr int32_t step = 2; 70 constexpr uint8_t asciiEnd = 0x7f; 71 constexpr uint8_t firstByte = 0x81; 72 constexpr uint8_t firstByteEnd = 0xfe; 73 constexpr uint8_t secondByteOne = 0x40; 74 constexpr uint8_t secondByteTwoEnd = 0xfe; 75 constexpr uint8_t gbkMask = 0xf7; 76 int32_t i = 0; 77 while (i < len) { 78 if (data[i] <= asciiEnd) { 79 i++; 80 continue; 81 } else { 82 if (data[i] >= firstByte && data[i] <= firstByteEnd && data[i + 1] >= secondByteOne && 83 data[i + 1] <= secondByteTwoEnd && data[i + 1] != gbkMask) { 84 i += step; 85 continue; 86 } else { 87 return false; 88 } 89 } 90 } 91 return true; 92} 93 94CODING GetCoding(const uint8_t *data, int32_t len) 95{ 96 CODING coding; 97 if (IsUTF8(data, len)) { 98 coding = UTF8; 99 } else if (IsGBK(data, len)) { 100 coding = GBK; 101 } else { 102 coding = UNKOWN; 103 } 104 return coding; 105} 106 107#ifdef _WIN32 108std::string GbkToUtf8(const char *srcStr) 109{ 110 int32_t len = MultiByteToWideChar(CP_ACP, 0, srcStr, -1, NULL, 0); 111 std::unique_ptr<wchar_t[]> wstr = std::make_unique<wchar_t[]>(len + 1); 112 MultiByteToWideChar(CP_ACP, 0, srcStr, -1, wstr.get(), len); 113 len = WideCharToMultiByte(CP_UTF8, 0, wstr.get(), -1, NULL, 0, NULL, NULL); 114 std::unique_ptr<char[]> str = std::make_unique<char[]>(len + 1); 115 WideCharToMultiByte(CP_UTF8, 0, wstr.get(), -1, str.get(), len, NULL, NULL); 116 return std::string(str.get()); 117} 118#endif 119} // namespace base 120} // namespace SysTuning 121