• 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 <vector>
20 #include <regex>
21 #include <iomanip>
22 
23 #include "userfile_manager_types.h"
24 #include "media_column.h"
25 #include "media_log.h"
26 
27 namespace OHOS::Media {
28 
29 // 处理重复displayName场景时,避免扩展的后缀长度超过255,截取超出的部分,保留最终总长为255
GetPrefixStrLength(std::string yearMonthDayStr,std::string hourMinuteSecondStr)30 int32_t DisplayNameInfo::GetPrefixStrLength(std::string yearMonthDayStr, std::string hourMinuteSecondStr)
31 {
32     int32_t extendLength = static_cast<int32_t>(yearMonthDayStr.size() + hourMinuteSecondStr.size()
33         + this->suffix.size());
34     return std::min<int32_t>(this->prefix.size(), static_cast<int32_t>(MAX_DISPLAY_NAME_LENGTH) - extendLength);
35 }
36 
DisplayNameInfo(const PhotoAssetInfo & photoAssetInfo)37 DisplayNameInfo::DisplayNameInfo(const PhotoAssetInfo &photoAssetInfo)
38 {
39     ParseDisplayName(photoAssetInfo);
40 }
41 
ToString()42 std::string DisplayNameInfo::ToString()
43 {
44     std::string yearMonthDayStr;
45     std::string hourMinuteSecondStr;
46     if (this->yearMonthDay != 0) {
47         std::ostringstream yearMonthDayStream;
48         yearMonthDayStream << std::setw(YEAR_MONTH_DAY_LENGTH) << std::setfill('0') << this->yearMonthDay;
49         std::ostringstream hourMinuteSecondStream;
50         hourMinuteSecondStream << std::setw(HOUR_MINUTE_SECOND_LENGTH) << std::setfill('0') << this->hourMinuteSecond;
51         yearMonthDayStr = "_" + yearMonthDayStream.str();
52         hourMinuteSecondStr = "_" + hourMinuteSecondStream.str();
53     } else {
54         yearMonthDayStr = this->yearMonthDay == 0 ? "" : "_" + std::to_string(this->yearMonthDay);
55         hourMinuteSecondStr = this->hourMinuteSecond == 0 ? "" : "_" + std::to_string(this->hourMinuteSecond);
56     }
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 }  // namespace OHOS::Media