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 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#include "nfc_sdk_common.h"
16
17#include <algorithm>
18#include <sstream>
19#include <securec.h>
20#include <sys/time.h>
21
22#include "loghelper.h"
23
24namespace OHOS {
25namespace NFC {
26namespace KITS {
27
28bool NfcSdkCommon::IsLittleEndian()
29{
30    const char LAST_DATA_BYTE = 0x78;
31    union CheckData {
32        int x;
33        char y;
34    };
35
36    union CheckData data;
37    data.x = 0x12345678;
38    if (data.y == LAST_DATA_BYTE) {
39        return true;
40    }
41    return false;
42}
43
44std::string NfcSdkCommon::BytesVecToHexString(const unsigned char* src, uint32_t length)
45{
46    std::string result = "";
47    if (length <= 0) {
48        return result;
49    }
50    const std::string hexKeys = "0123456789ABCDEF";
51    for (uint32_t i = 0; i < length; i++) {
52        result.push_back(hexKeys[(src[i] & 0xF0) >> HALF_BYTE_BITS]);
53        result.push_back(hexKeys[src[i] & 0x0F]);
54    }
55    return result;
56}
57
58std::string NfcSdkCommon::UnsignedCharToHexString(const unsigned char src)
59{
60    std::string result = "";
61    const std::string hexKeys = "0123456789ABCDEF";
62    result.push_back(hexKeys[(src & 0xF0) >> HALF_BYTE_BITS]);
63    result.push_back(hexKeys[src & 0x0F]);
64    return result;
65}
66
67void NfcSdkCommon::HexStringToBytes(const std::string &src, std::vector<unsigned char> &bytes)
68{
69    if (src.empty()) {
70        return;
71    }
72
73    uint32_t bytesLen = src.length() / HEX_BYTE_LEN;
74    std::string strByte;
75    unsigned int srcIntValue;
76    for (uint32_t i = 0; i < bytesLen; i++) {
77        strByte = src.substr(i * HEX_BYTE_LEN, HEX_BYTE_LEN);
78        if (sscanf_s(strByte.c_str(), "%x", &srcIntValue) <= 0) {
79            ErrorLog("HexStringToBytes, sscanf_s failed.");
80            bytes.clear();
81            return;
82        }
83        bytes.push_back(static_cast<unsigned char>(srcIntValue & 0xFF));
84    }
85}
86
87uint32_t NfcSdkCommon::GetHexStrBytesLen(const std::string src)
88{
89    // 2 charactors consist of one byte.
90    if (src.empty()) {
91        return 0;
92    }
93    uint32_t length = src.length();
94    if (length % HEX_BYTE_LEN == 0) {
95        return (length / HEX_BYTE_LEN);
96    } else {
97        return ((length / HEX_BYTE_LEN) + 1);
98    }
99}
100
101unsigned char NfcSdkCommon::GetByteFromHexStr(const std::string src, uint32_t index)
102{
103    // 2 charactors consist of one byte.
104    if (src.empty() || (src.length() < index * HEX_BYTE_LEN + HEX_BYTE_LEN)) {
105        ErrorLog("GetByteFromHexStr, src length error.");
106        return 0;
107    }
108    std::string strByte = src.substr(index * HEX_BYTE_LEN, HEX_BYTE_LEN);
109    unsigned int srcIntValue;
110    if (sscanf_s(strByte.c_str(), "%x", &srcIntValue) <= 0) {
111        ErrorLog("GetByteFromHexStr, sscanf_s failed.");
112        return 0;
113    }
114    return static_cast<unsigned char>(srcIntValue & 0xFF);
115}
116
117uint32_t NfcSdkCommon::StringToInt(std::string src, bool bLittleEndian)
118{
119    uint32_t value = 0;
120    if (bLittleEndian) {
121        for (size_t i = SHIFT_TIME; i > 0; i--) {
122            value += static_cast<uint32_t>((src.at(SHIFT_TIME - i)) << (i * SHIFT_SIZE - SHIFT_SIZE));
123        }
124    } else {
125        for (size_t i = 0; i < SHIFT_TIME; i++) {
126            value += static_cast<uint32_t>((src.at(i)) << (i * SHIFT_SIZE));
127        }
128    }
129    return value;
130}
131
132std::string NfcSdkCommon::IntToHexString(uint32_t num)
133{
134    std::stringstream ss;
135    ss << std::hex << num;
136    std::string result = ss.str();
137    transform(result.begin(), result.end(), result.begin(), ::toupper);
138    if (result.length() % HEX_BYTE_LEN > 0) { // expend "0" if string length is odd
139        result = "0" + result;
140    }
141    return result;
142}
143
144void NfcSdkCommon::StringToAsciiBytes(const std::string &src, std::vector<unsigned char> &bytes)
145{
146    if (src.empty()) {
147        return;
148    }
149    uint32_t bytesLen = src.length();
150    for (uint32_t i = 0; i < bytesLen; i++) {
151        unsigned int srcAsciiIntVal = static_cast<unsigned int>(src[i]);
152        bytes.push_back(static_cast<unsigned char>(srcAsciiIntVal & 0xFF));
153    }
154}
155
156std::string NfcSdkCommon::StringToHexString(const std::string &src)
157{
158    std::vector<unsigned char> bytes;
159    StringToAsciiBytes(src, bytes);
160    uint32_t len = src.length();
161    std::string result = BytesVecToHexString(&bytes[0], len);
162    return result;
163}
164
165std::string NfcSdkCommon::HexStringToAsciiString(const std::string &src)
166{
167    if (src.size() % HEX_BYTE_LEN != 0 || src.empty()) {  // 2 is Even number judgement
168        ErrorLog("HexStringToAsciiString length error");
169        return "";
170    }
171    std::string result = "";
172    for (size_t i = 0; i < src.size() / HEX_BYTE_LEN; i++) {
173        unsigned char byteVal = GetByteFromHexStr(src, i);
174        const char minPrintChar = ' ';
175        const char maxPrintChar = '~';
176        /* ' ' to '~' is the printable char range */
177        if (static_cast<char>(byteVal) < minPrintChar || static_cast<char>(byteVal) > maxPrintChar) {
178            return "";
179        }
180        result.push_back(static_cast<char>(byteVal));
181    }
182    return result;
183}
184
185/*
186 * transfer Hex array to String without checking Ascii validation, compatible with Chinese characters
187 */
188std::string NfcSdkCommon::HexArrayToStringWithoutChecking(const std::string &src)
189{
190    if (src.size() % HEX_BYTE_LEN != 0 || src.empty()) {  // 2 is Even number judgement
191        ErrorLog("HexStringToAsciiString length error");
192        return "";
193    }
194    std::string result = "";
195    for (size_t i = 0; i < src.size() / HEX_BYTE_LEN; i++) {
196        unsigned char byteVal = GetByteFromHexStr(src, i);
197        result.push_back(static_cast<char>(byteVal));
198    }
199    return result;
200}
201
202uint64_t NfcSdkCommon::GetCurrentTime()
203{
204    // get the time since 1970/1/1
205    constexpr int timeRate = 1000;
206    struct timeval time = {0};
207    gettimeofday(&time, nullptr);
208    return static_cast<uint64_t>(time.tv_sec * timeRate + time.tv_usec / timeRate);
209}
210
211uint64_t NfcSdkCommon::GetRelativeTime()
212{
213    // get the time since the system was booted
214    constexpr int64_t msPerSecond = 1000;
215    constexpr int64_t nsPerMs = 1000000;
216
217    struct timespec times = {0};
218    clock_gettime(CLOCK_MONOTONIC, &times);
219    return ((times.tv_sec * msPerSecond) + (times.tv_nsec / nsPerMs));
220}
221
222std::string NfcSdkCommon::CodeMiddlePart(const std::string &src)
223{
224    std::string res = "";
225    if (src.empty()) {
226        return res;
227    }
228    const char code = 'X';
229    const uint32_t maxStrLen = 1024;
230    uint32_t len = src.length();
231    if (len > maxStrLen) {
232        return res;
233    }
234
235    uint32_t head = (len / 2) / 2; // Divide the string evenly into 2 * 2 parts
236    if (len <= head * 2) {  // The length of the head * 2 is greater than src
237        return src;
238    }
239    for (uint32_t i = 0; i < head; i++) {
240        res.push_back(src[i]);
241    }
242    for (uint32_t i = head; i < (len - head); i++) {
243        res.push_back(code);
244    }
245    for (uint32_t i = (len - head); i < len; i++) {
246        res.push_back(src[i]);
247    }
248    return res;
249}
250}  // namespace KITS
251}  // namespace NFC
252}  // namespace OHOS
253