• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define MLOG_TAG "DisplayNameInfo"
16 
17 #include "display_name_info.h"
18 
19 #include <algorithm>
20 #include <vector>
21 #include <regex>
22 #include <iomanip>
23 
24 #include "userfile_manager_types.h"
25 #include "media_column.h"
26 #include "media_log.h"
27 
28 namespace OHOS::Media {
29 // LCOV_EXCL_START
30 // 处理重复displayName场景时,避免扩展的后缀长度超过255,截取超出的部分,保留最终总长为255
GetPrefixStrLength(std::string yearMonthDayStr,std::string hourMinuteSecondStr)31 int32_t DisplayNameInfo::GetPrefixStrLength(std::string yearMonthDayStr, std::string hourMinuteSecondStr)
32 {
33     int32_t extendLength = static_cast<int32_t>(yearMonthDayStr.size() + hourMinuteSecondStr.size()
34         + this->suffix.size());
35     return std::min<int32_t>(this->prefix.size(), static_cast<int32_t>(MAX_DISPLAY_NAME_LENGTH) - extendLength);
36 }
37 
DisplayNameInfo(const PhotoAssetInfo & photoAssetInfo)38 DisplayNameInfo::DisplayNameInfo(const PhotoAssetInfo &photoAssetInfo)
39 {
40     ParseDisplayName(photoAssetInfo);
41 }
42 
ToString()43 std::string DisplayNameInfo::ToString()
44 {
45     std::string yearMonthDayStr;
46     std::string hourMinuteSecondStr;
47     if (this->yearMonthDay != 0) {
48         std::ostringstream yearMonthDayStream;
49         yearMonthDayStream << std::setw(YEAR_MONTH_DAY_LENGTH) << std::setfill('0') << this->yearMonthDay;
50         std::ostringstream hourMinuteSecondStream;
51         hourMinuteSecondStream << std::setw(HOUR_MINUTE_SECOND_LENGTH) << std::setfill('0') << this->hourMinuteSecond;
52         yearMonthDayStr = "_" + yearMonthDayStream.str();
53         hourMinuteSecondStr = "_" + hourMinuteSecondStream.str();
54     } else {
55         yearMonthDayStr = this->yearMonthDay == 0 ? "" : "_" + std::to_string(this->yearMonthDay);
56         hourMinuteSecondStr = this->hourMinuteSecond == 0 ? "" : "_" + std::to_string(this->hourMinuteSecond);
57     }
58     return this->prefix.substr(0, GetPrefixStrLength(yearMonthDayStr, hourMinuteSecondStr))
59         + yearMonthDayStr + hourMinuteSecondStr + this->suffix;
60 }
61 
Next()62 std::string DisplayNameInfo::Next()
63 {
64     this->hourMinuteSecond++;
65     return this->ToString();
66 }
67 
ParseDisplayName(const PhotoAssetInfo & photoAssetInfo)68 void DisplayNameInfo::ParseDisplayName(const PhotoAssetInfo &photoAssetInfo)
69 {
70     if (photoAssetInfo.subtype == static_cast<int32_t>(PhotoSubType::BURST)) {
71         ParseBurstDisplayName(photoAssetInfo);
72         return;
73     }
74     ParseNormalDisplayName(photoAssetInfo);
75     return;
76 }
77 
ParseBurstDisplayName(const PhotoAssetInfo & photoAssetInfo)78 void DisplayNameInfo::ParseBurstDisplayName(const PhotoAssetInfo &photoAssetInfo)
79 {
80     bool isValid = photoAssetInfo.subtype == static_cast<int32_t>(PhotoSubType::BURST);
81     isValid = isValid && photoAssetInfo.displayName.size() > BURST_DISPLAY_NAME_MIN_LENGTH;
82     if (!isValid) {
83         return ParseNormalDisplayName(photoAssetInfo);
84     }
85     std::string displayName = photoAssetInfo.displayName;
86     std::regex pattern(R"(IMG_\d{8}_\d{6}_)", std::regex_constants::icase);
87     std::smatch match;
88     if (!std::regex_search(displayName, match, pattern)) {
89         return ParseNormalDisplayName(photoAssetInfo);
90     }
91     std::vector<std::string> parts;
92     std::istringstream iss(displayName);
93     std::string part;
94     while (std::getline(iss, part, '_')) {
95         parts.push_back(part);
96     }
97     if (parts.size() >= BURST_DISPLAY_NAME_MIN_SUBLINE_COUNT) {
98         this->prefix = parts[0];
99         this->yearMonthDay = this->ToNumber(parts[BURST_DISPLAY_NAME_YEAR_INDEX]);
100         this->hourMinuteSecond = this->ToNumber(parts[BURST_DISPLAY_NAME_HOUR_INDEX]);
101         this->suffix = displayName.substr(BURST_DISPLAY_NAME_MIN_LENGTH - 1);
102     }
103     MEDIA_INFO_LOG("ParseBurstDisplayName Original display name: %{public}s, BurstDisplayNameInfo: %{public}s",
104         displayName.c_str(),
105         this->ToString().c_str());
106 }
107 
ToNumber(const std::string & str)108 int32_t DisplayNameInfo::ToNumber(const std::string &str)
109 {
110     char *end;
111     long number = std::strtol(str.c_str(), &end, 10);
112 
113     if (*end != '\0') {
114         MEDIA_ERR_LOG("ToNumber failed, has invalid char. str: %{public}s", str.c_str());
115         return 0;
116     } else if (number < INT_MIN || number > INT_MAX) {
117         MEDIA_ERR_LOG("ToNumber failed, number overflow. str: %{public}s", str.c_str());
118         return 0;
119     }
120     return static_cast<int32_t>(number);
121 }
122 
ParseNormalDisplayName(const PhotoAssetInfo & photoAssetInfo)123 void DisplayNameInfo::ParseNormalDisplayName(const PhotoAssetInfo &photoAssetInfo)
124 {
125     std::string displayName = photoAssetInfo.displayName;
126     size_t dotPos = displayName.rfind('.');
127     if (dotPos != std::string::npos) {
128         this->prefix = displayName.substr(0, dotPos);
129         this->suffix = displayName.substr(dotPos);  // include dot, e.g. ".jpg"
130     }
131     MEDIA_INFO_LOG("ParseNormalDisplayName Original display name: %{public}s, BurstDisplayNameInfo: %{public}s",
132         displayName.c_str(),
133         this->ToString().c_str());
134 }
135 // LCOV_EXCL_STOP
136 }  // namespace OHOS::Media