1 /*
2 * Copyright (C) 2024 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 "dfx_utils.h"
17
18 #include <chrono>
19 #include <iomanip>
20 #include <sstream>
21
22 #include "dfx_const.h"
23 #include "media_file_utils.h"
24 #include "media_log.h"
25 using namespace std;
26 namespace OHOS {
27 namespace Media {
28 namespace {
29 constexpr int ONE_MORE = 1;
30 constexpr int ONE_SECOND = 1;
31 constexpr int32_t BASEYEAR = 1900;
32 constexpr int32_t LENGTH_TWO = 2;
33 constexpr int32_t LENGTH_THREE = 3;
34 }
35
36 static const char *UTF16_CERROR = "__CONVERSION_ERROR__";
37 static const char16_t *g_utf8Cerror = u"__CONVERSION_ERROR__";
38
Split(string & input,const string & pattern)39 vector<string> DfxUtils::Split(string &input, const string &pattern)
40 {
41 vector<string> result;
42 if (input == "") {
43 return result;
44 }
45 string strs = input + pattern;
46 size_t pos = strs.find(pattern);
47 while (pos != strs.npos) {
48 string temp = strs.substr(0, pos);
49 result.push_back(temp);
50 strs = strs.substr(pos + 1, strs.size());
51 pos = strs.find(pattern);
52 }
53 return result;
54 }
55
GetSafePath(const string & path)56 string DfxUtils::GetSafePath(const string &path)
57 {
58 string safePath = path;
59 if (path == "") {
60 return safePath;
61 }
62 if (MediaFileUtils::StartsWith(path, CLOUD_PHOTO_PATH)) {
63 return safePath.replace(0, CLOUD_PHOTO_PATH.length(), GARBLE);
64 }
65 safePath = safePath.replace(0, CLOUD_FILE_PATH.length(), GARBLE);
66 size_t splitIndex = safePath.find_last_of(SPLIT_PATH);
67 string displayName;
68 if (splitIndex == string::npos) {
69 displayName = "";
70 } else {
71 displayName = safePath.substr(splitIndex + 1);
72 }
73 string safeDisplayName = GetSafeDiaplayName(displayName);
74 safePath = safePath.substr(0, splitIndex) + safeDisplayName;
75 return safePath;
76 }
77
GetSafeUri(const string & uri)78 string DfxUtils::GetSafeUri(const string &uri)
79 {
80 string safeUri = uri;
81 if (uri == "") {
82 return safeUri;
83 }
84 size_t splitIndex = safeUri.find_last_of(SPLIT_PATH);
85 string displayName;
86 if (splitIndex == string::npos) {
87 return safeUri;
88 } else {
89 displayName = safeUri.substr(splitIndex + 1);
90 }
91 string safeDisplayName = GetSafeDiaplayName(displayName);
92 safeUri = safeUri.substr(0, splitIndex) + "/" + safeDisplayName;
93 return safeUri;
94 }
95
GetSafeDiaplayName(string & displayName)96 string DfxUtils::GetSafeDiaplayName(string &displayName)
97 {
98 if (displayName == "") {
99 return displayName;
100 }
101 string extension;
102 size_t splitIndex = displayName.find_last_of(DOT);
103 if (splitIndex == string::npos) {
104 extension = "";
105 } else {
106 extension = displayName.substr(splitIndex);
107 }
108 string title = MediaFileUtils::GetTitleFromDisplayName(displayName);
109 if (title == "") {
110 return title;
111 }
112 uint32_t length = title.size();
113 string safeDisplayName;
114 if (length <= GARBLE_SMALL) {
115 safeDisplayName = GARBLE + title.substr(length - GARBLE_LAST_ONE) + extension;
116 } else if (length > GARBLE_LARGE) {
117 safeDisplayName = GARBLE + title.substr(GARBLE_LARGE) + extension;
118 } else {
119 safeDisplayName = GARBLE + title.substr(length - GARBLE_LAST_TWO) + extension;
120 }
121 return safeDisplayName;
122 }
123
GetCurrentDate()124 string DfxUtils::GetCurrentDate()
125 {
126 auto now = std::chrono::system_clock::now();
127 auto time = std::chrono::system_clock::to_time_t(now);
128 std::tm* tmPtr = std::localtime(&time);
129 if (tmPtr == nullptr) {
130 MEDIA_ERR_LOG("GetCurrentDate failed: tmPtr is nullptr");
131 return "";
132 }
133 std::stringstream ss;
134 ss << std::put_time(tmPtr, "%Y-%m-%d");
135 return ss.str();
136 }
137
GetCurrentDateMillisecond()138 string DfxUtils::GetCurrentDateMillisecond()
139 {
140 auto now = std::chrono::system_clock::now();
141 std::time_t now_time = std::chrono::system_clock::to_time_t(now);
142 std::tm* now_tm = std::localtime(&now_time);
143 if (now_tm == nullptr) {
144 MEDIA_ERR_LOG("GetCurrentDateMillisecond failed: now_tm is nullptr");
145 return "";
146 }
147 auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
148 std::chrono::duration<int, std::milli> ms_part = now_ms.time_since_epoch() % std::chrono::seconds(ONE_SECOND);
149
150 std::stringstream ss;
151 ss << (now_tm->tm_year + BASEYEAR) << '-'
152 << std::setw(LENGTH_TWO) << std::setfill('0') << (now_tm->tm_mon + ONE_MORE) << '-'
153 << std::setw(LENGTH_TWO) << std::setfill('0') << now_tm->tm_mday << ' '
154 << std::setw(LENGTH_TWO) << std::setfill('0') << now_tm->tm_hour << ':'
155 << std::setw(LENGTH_TWO) << std::setfill('0') << now_tm->tm_min << ':'
156 << std::setw(LENGTH_TWO) << std::setfill('0') << now_tm->tm_sec << '.'
157 << std::setw(LENGTH_THREE) << ms_part.count();
158 return ss.str();
159 }
160
JoinStrings(const unordered_set<string> & strSet,char delimiter)161 string DfxUtils::JoinStrings(const unordered_set<string>& strSet, char delimiter)
162 {
163 string result;
164 for (auto it = strSet.begin(); it != strSet.end(); ++it) {
165 if (it != strSet.begin()) {
166 result += delimiter;
167 }
168 result += *it;
169 }
170 return result;
171 }
172
SplitString(const string & input,char delimiter)173 unordered_set<string> DfxUtils::SplitString(const string& input, char delimiter)
174 {
175 if (input.empty()) {
176 return {};
177 }
178
179 unordered_set<std::string> result;
180 std::istringstream iss(input);
181 string token;
182 while (std::getline(iss, token, delimiter)) {
183 result.emplace(token);
184 }
185 return result;
186 }
187
GetSafeAlbumName(const string & albumName)188 string DfxUtils::GetSafeAlbumName(const string& albumName)
189 {
190 if (albumName == "") {
191 return albumName;
192 }
193 uint32_t length = albumName.size();
194 string safeAlbumName;
195 if (length <= GARBLE_SMALL) {
196 safeAlbumName = GARBLE + albumName.substr(length - GARBLE_LAST_ONE);
197 } else if (length > GARBLE_LARGE) {
198 safeAlbumName = GARBLE + albumName.substr(GARBLE_LARGE);
199 } else {
200 safeAlbumName = GARBLE + albumName.substr(length - GARBLE_LAST_TWO);
201 }
202 return safeAlbumName;
203 }
204
Str8ToStr16(const std::string & inputStr)205 std::u16string DfxUtils::Str8ToStr16(const std::string &inputStr)
206 {
207 if (inputStr.empty()) {
208 return u"";
209 }
210 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert(UTF16_CERROR, g_utf8Cerror);
211 std::u16string result = convert.from_bytes(inputStr);
212 return result == g_utf8Cerror ? u"" : result;
213 }
214
Str16ToStr8(const std::u16string & inputStr)215 std::string DfxUtils::Str16ToStr8(const std::u16string &inputStr)
216 {
217 if (inputStr.empty()) {
218 return "";
219 }
220 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert(UTF16_CERROR, g_utf8Cerror);
221 std::string result = convert.to_bytes(inputStr);
222 return result == UTF16_CERROR ? "" : result;
223 }
224
GetSafeAlbumNameWhenChinese(const string & albumName)225 string DfxUtils::GetSafeAlbumNameWhenChinese(const string &albumName)
226 {
227 CHECK_AND_RETURN_RET_LOG(!albumName.empty(), "", "input albumName is empty");
228 std::u16string wideStr = Str8ToStr16(albumName);
229 uint32_t length = wideStr.size();
230 if (length <= 0) {
231 return GARBLE;
232 }
233 std::u16string safeAlbumName;
234 if (length <= GARBLE_SMALL) {
235 safeAlbumName = wideStr.substr(length - GARBLE_LAST_ONE);
236 } else if (length > GARBLE_LARGE) {
237 safeAlbumName = wideStr.substr(GARBLE_LARGE);
238 } else {
239 safeAlbumName = wideStr.substr(length - GARBLE_LAST_TWO);
240 }
241 return GARBLE + Str16ToStr8(safeAlbumName);
242 }
243
GetSafeDiaplayNameWhenChinese(const string & displayName)244 string DfxUtils::GetSafeDiaplayNameWhenChinese(const string &displayName)
245 {
246 CHECK_AND_RETURN_RET_LOG(!displayName.empty(), "", "input displayName is empty");
247 string extension;
248 size_t splitIndex = displayName.find_last_of(DOT);
249 if (splitIndex == string::npos) {
250 extension = "";
251 } else {
252 extension = displayName.substr(splitIndex);
253 }
254 string title = MediaFileUtils::GetTitleFromDisplayName(displayName);
255 CHECK_AND_RETURN_RET_LOG(!title.empty(), "", "input title is empty");
256 std::u16string wideStr = Str8ToStr16(title);
257 uint32_t length = wideStr.size();
258 if (length <= 0) {
259 return GARBLE + extension;
260 }
261 std::u16string safeTitle;
262 if (length <= GARBLE_SMALL) {
263 safeTitle = wideStr.substr(length - GARBLE_LAST_ONE);
264 } else if (length > GARBLE_LARGE) {
265 safeTitle = wideStr.substr(GARBLE_LARGE);
266 } else {
267 safeTitle = wideStr.substr(length - GARBLE_LAST_TWO);
268 }
269
270 return GARBLE + Str16ToStr8(safeTitle) + extension;
271 }
272 } // namespace Media
273 } // namespace OHOS