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#include "string_util.h"
16#include <fstream>
17#include <iterator>
18#include <ctime>
19#include <sys/time.h>
20#include <climits>
21
22#include "intell_voice_log.h"
23
24#undef LOG_TAG
25#define LOG_TAG "StringUtil"
26
27using namespace std;
28
29namespace OHOS {
30namespace IntellVoiceUtils {
31static const char16_t DELIMITER_EQUAL_SIGN = '=';
32
33// #ABC#WWW##XYZ#---->vector[0]: ABC, vector[1]: WWW, vector[2]: XYZ
34void StringUtil::Split(const string &str, const string &sep, vector<string> &res)
35{
36    res.clear();
37    string tmpStr = str;
38    unsigned int startPos = 0;
39    size_t findPos = tmpStr.find(sep, startPos);
40    while (findPos != string::npos) {
41        if (findPos > startPos) {
42            res.push_back(tmpStr.substr(static_cast<uint32_t>(startPos), static_cast<uint32_t>((findPos - startPos))));
43        }
44        startPos = findPos + sep.length();
45        findPos = tmpStr.find(sep, startPos);
46    }
47
48    if (startPos < tmpStr.length()) {
49        res.push_back(tmpStr.substr(startPos));
50    }
51}
52
53// the func is called for AcousticPruner and AcousticPrunerExtra file
54std::vector<string> StringUtil::StringSplit(string &str, const string &pattern)
55{
56    string::size_type pos;
57    vector<string> result;
58    str += pattern;
59    unsigned int size = str.size();
60
61    for (unsigned int i = 0; i < size; i++) {
62        pos = str.find(pattern, i);
63        if (pos < size) {
64            string s = str.substr(i, pos - i);
65            result.push_back(s);
66            i = pos + pattern.size() - 1;
67        }
68    }
69
70    return result;
71}
72
73template <typename T> string StringUtil::PrintVector(vector<T> &array, string &delimiter)
74{
75    if (array.empty()) {
76        return "";
77    }
78
79    ostringstream oss;
80    copy(array.begin(), array.end() - 1, ostream_iterator<T>(oss, delimiter.c_str()));
81    oss << array.back();
82
83    return oss.str();
84}
85
86void StringUtil::TrimSpecialChars(string &str)
87{
88    size_t sp = 0;
89
90    while (sp < str.size()) {
91        size_t ep = str.find_first_of(" \t\n\v\f\r,.:;!~@#$%^&*()`?/-+", sp);
92        if (ep != string::npos) {
93            str.erase(ep, 1);
94            sp = ep;
95        } else {
96            break;
97        }
98    }
99}
100
101uint32_t StringUtil::CalSubStrNum(const string &str, const string &subStr)
102{
103    if (subStr.size() == 0) {
104        return 0;
105    }
106    uint32_t count = 0;
107    string::size_type pos = 0;
108    pos = str.find(subStr, pos);
109    while (pos != string::npos) {
110        count++;
111        pos = pos + subStr.size();
112        pos = str.find(subStr, pos);
113    }
114
115    return count;
116}
117bool StringUtil::SplitLineToPair(const std::string &line, std::string &first, std::string &second)
118{
119    if (line.empty()) {
120        INTELL_VOICE_LOG_ERROR("line is empty");
121        return false;
122    }
123    // pinyin:words
124    size_t pos = line.find(DELIMITER_EQUAL_SIGN);
125    // not find delimiter or it is the last char.
126    if (string::npos == pos || (line.length() - 1) == pos) {
127        return false;
128    }
129
130    first = line.substr(0, pos);
131    second = line.substr(pos + 1, string::npos);
132    // trim left and right spaces.
133    Trim(first);
134    Trim(second);
135
136    if (first.empty() || second.empty()) {
137        INTELL_VOICE_LOG_ERROR("line is invalid, first:%{public}s, second:%{public}s", first.c_str(), second.c_str());
138        return false;
139    }
140    return true;
141}
142
143bool StringUtil::StringToInt(const std::string &str, int32_t &val)
144{
145    char *endStr = nullptr;
146    long int conVal = std::strtol(str.c_str(), &endStr, 10); // decimal
147    if (conVal == LONG_MAX || conVal == LONG_MIN || endStr == nullptr || endStr == str.c_str() || *endStr != '\0') {
148        return false;
149    }
150
151    val = static_cast<int32_t>(conVal);
152    return true;
153}
154}
155}
156
157