• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 
16 #include "common_util.h"
17 
18 #include <regex>
19 
20 #include "file_util.h"
21 #include "hiview_logger.h"
22 #include "string_util.h"
23 #include "time_util.h"
24 
25 namespace OHOS {
26 namespace HiviewDFX {
27 namespace UCollectUtil {
28 namespace {
29 DEFINE_LOG_TAG("UCollectUtil-CommonUtil");
30 constexpr char EXPORT_FILE_REGEX[] = "[0-9]{14}(.*)";
31 constexpr char UNDERLINE[] = "_";
32 }
33 
ParseTypeAndValue(const std::string & str,std::string & type,int64_t & value)34 bool CommonUtil::ParseTypeAndValue(const std::string &str, std::string &type, int64_t &value)
35 {
36     std::string::size_type typePos = str.find(":");
37     if (typePos != std::string::npos) {
38         type = str.substr(0, typePos);
39         std::string valueStr = str.substr(typePos + 1);
40         std::string::size_type valuePos = valueStr.find("kB");
41         if (valuePos == std::string::npos) {
42             valuePos = valueStr.find("KB");
43         }
44         if (valuePos != std::string::npos) {
45             valueStr.resize(valuePos);
46             StrToNum(valueStr, value);
47             return true;
48         } else {
49             StrToNum(valueStr, value);
50             return true;
51         }
52     }
53     return false;
54 }
55 
GetDirRegexFiles(const std::string & path,const std::string & pattern,std::vector<std::string> & files)56 void CommonUtil::GetDirRegexFiles(const std::string& path, const std::string& pattern,
57     std::vector<std::string>& files)
58 {
59     DIR* dir = opendir(path.c_str());
60     if (dir == nullptr) {
61         HIVIEW_LOGE("failed to open dir=%{public}s", path.c_str());
62         return;
63     }
64     std::regex reg = std::regex(pattern);
65     struct dirent* ptr = nullptr;
66     while ((ptr = readdir(dir)) != nullptr) {
67         if (ptr->d_type == DT_REG) {
68             if (regex_match(ptr->d_name, reg)) {
69                 files.push_back(FileUtil::IncludeTrailingPathDelimiter(path) + std::string(ptr->d_name));
70             }
71         }
72     }
73     closedir(dir);
74     std::sort(files.begin(), files.end());
75 }
76 
GetFileNameNum(const std::string & fileName,const std::string & ext)77 int CommonUtil::GetFileNameNum(const std::string& fileName, const std::string& ext)
78 {
79     int ret = 0;
80     auto startPos = fileName.find(UNDERLINE);
81     if (startPos == std::string::npos) {
82         return ret;
83     }
84     auto endPos = fileName.find(ext);
85     if (endPos == std::string::npos) {
86         return ret;
87     }
88     if (endPos <= startPos + 1) {
89         return ret;
90     }
91     return StringUtil::StrToInt(fileName.substr(startPos + 1, endPos - startPos - 1));
92 }
93 
CreateExportFile(const std::string & path,int32_t maxFileNum,const std::string & prefix,const std::string & ext)94 std::string CommonUtil::CreateExportFile(const std::string& path, int32_t maxFileNum, const std::string& prefix,
95     const std::string& ext)
96 {
97     if (!FileUtil::IsDirectory(path) && !FileUtil::ForceCreateDirectory(path)) {
98         HIVIEW_LOGE("failed to create dir=%{public}s", path.c_str());
99         return "";
100     }
101 
102     std::vector<std::string> files;
103     GetDirRegexFiles(path, prefix + EXPORT_FILE_REGEX, files);
104     if (files.size() >= static_cast<size_t>(maxFileNum)) {
105         for (size_t index = 0; index <= files.size() - static_cast<size_t>(maxFileNum); ++index) {
106             HIVIEW_LOGI("remove file=%{public}s", FileUtil::ExtractFileName(files[index]).c_str());
107             (void)FileUtil::RemoveFile(files[index]);
108         }
109     }
110 
111     uint64_t fileTime = TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC;
112     std::string timeFormat = TimeUtil::TimestampFormatToDate(fileTime, "%Y%m%d%H%M%S");
113     std::string fileName;
114     fileName.append(path).append(prefix).append(timeFormat);
115     if (!files.empty()) {
116         auto startPos = files.back().find(timeFormat);
117         if (startPos != std::string::npos) {
118             int fileNameNum = GetFileNameNum(files.back().substr(startPos), ext); // yyyymmddHHMMSS_1.txt
119             fileName.append(UNDERLINE).append(std::to_string(++fileNameNum));
120         }
121     }
122     fileName.append(ext);
123     (void)FileUtil::CreateFile(fileName);
124     HIVIEW_LOGI("create file=%{public}s", FileUtil::ExtractFileName(fileName).c_str());
125     return fileName;
126 }
127 
ReadNodeWithOnlyNumber(const std::string & fileName)128 int32_t CommonUtil::ReadNodeWithOnlyNumber(const std::string& fileName)
129 {
130     std::string content;
131     if (!FileUtil::LoadStringFromFile(fileName, content)) {
132         HIVIEW_LOGW("read node failed");
133         return 0;
134     }
135     int32_t parsedVal = 0;
136     // this string content might be empty or consist of some special charactors
137     // so "std::stoi" and "StringUtil::StrToInt" aren't applicable here.
138     std::stringstream ss(content);
139     ss >> parsedVal;
140     return parsedVal;
141 }
142 } // UCollectUtil
143 } // HiViewDFX
144 } // OHOS
145