1 /*
2 * Copyright (C) 2022 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 "Thumbnail"
16
17 #include "thumbnail_uri_utils.h"
18
19 #include "medialibrary_errno.h"
20 #include "media_log.h"
21 #include "thumbnail_const.h"
22
23 using namespace std;
24
25 namespace OHOS {
26 namespace Media {
ParseFileUri(const string & uriString,string & outFileId,string & ourNetworkId)27 bool ThumbnailUriUtils::ParseFileUri(const string &uriString, string &outFileId, string &ourNetworkId)
28 {
29 outFileId = GetIdFromUri(uriString);
30 ourNetworkId = GetNetworkIdFromUri(uriString);
31 return true;
32 }
33
ParseThumbnailKey(const string & key,const string & value,string & outAction,int & outWidth,int & outHeight)34 void ThumbnailUriUtils::ParseThumbnailKey(const string &key, const string &value, string &outAction,
35 int &outWidth, int &outHeight)
36 {
37 if (key == THUMBNAIL_OPERN_KEYWORD) {
38 outAction = value;
39 } else if (key == THUMBNAIL_WIDTH) {
40 if (IsNumber(value)) {
41 outWidth = stoi(value);
42 }
43 } else if (key == THUMBNAIL_HEIGHT) {
44 if (IsNumber(value)) {
45 outHeight = stoi(value);
46 }
47 }
48 }
49
ParseThumbnailInfo(const string & uriString,string & outFileId,Size & outSize,string & ourNetworkId)50 bool ThumbnailUriUtils::ParseThumbnailInfo(const string &uriString, string &outFileId, Size &outSize,
51 string &ourNetworkId)
52 {
53 string::size_type pos = uriString.find_last_of('?');
54 if (pos == string::npos) {
55 return false;
56 }
57 vector<string> keyWords = {
58 THUMBNAIL_OPERN_KEYWORD,
59 THUMBNAIL_WIDTH,
60 THUMBNAIL_HEIGHT
61 };
62 string queryKeys = uriString.substr(pos + 1);
63 string uri = uriString.substr(0, pos);
64 outFileId = GetIdFromUri(uri);
65 ourNetworkId = GetNetworkIdFromUri(uri);
66 vector<string> vectorKeys;
67 SplitKeys(queryKeys, vectorKeys);
68 if (vectorKeys.size() != keyWords.size()) {
69 MEDIA_ERR_LOG("Parse error keys count %{private}d", (int)vectorKeys.size());
70 return false;
71 }
72 string action;
73 int width = 0;
74 int height = 0;
75 string subKey;
76 string subVal;
77 for (uint32_t i = 0; i < vectorKeys.size(); i++) {
78 SplitKeyValue(vectorKeys[i], subKey, subVal);
79 if (subKey.empty()) {
80 MEDIA_ERR_LOG("Parse key error [ %{private}s ]", vectorKeys[i].c_str());
81 return false;
82 }
83 ParseThumbnailKey(subKey, subVal, action, width, height);
84 }
85 MEDIA_INFO_LOG("Action [%{private}s] id %{public}s width %{private}d height %{private}d",
86 action.c_str(), outFileId.c_str(), width, height);
87 if (action != MEDIA_DATA_DB_THUMBNAIL || width <= 0 || height <= 0) {
88 MEDIA_ERR_LOG("ParseThumbnailInfo | Error args");
89 return false;
90 }
91
92 outSize.width = width;
93 outSize.height = height;
94 return true;
95 }
96
GetNetworkIdFromUri(const string & uri)97 string ThumbnailUriUtils::GetNetworkIdFromUri(const string &uri)
98 {
99 string deviceId;
100 if (uri.empty()) {
101 return deviceId;
102 }
103 size_t pos = uri.find(MEDIALIBRARY_DATA_ABILITY_PREFIX);
104 if (pos == string::npos) {
105 return deviceId;
106 }
107
108 string tempUri = uri.substr(MEDIALIBRARY_DATA_ABILITY_PREFIX.length());
109 if (tempUri.empty()) {
110 return deviceId;
111 }
112 MEDIA_INFO_LOG("ThumbnailUriUtils::GetNetworkIdFromUri tempUri = %{private}s", tempUri.c_str());
113 pos = tempUri.find_first_of('/');
114 if (pos == 0 || pos == string::npos) {
115 return deviceId;
116 }
117 deviceId = tempUri.substr(0, pos);
118 return deviceId;
119 }
120
GetIdFromUri(const string & uri)121 string ThumbnailUriUtils::GetIdFromUri(const string &uri)
122 {
123 string rowNum = "-1";
124
125 size_t pos = uri.rfind('/');
126 if (pos != std::string::npos) {
127 rowNum = uri.substr(pos + 1);
128 }
129
130 return rowNum;
131 }
132
SplitKeyValue(const string & keyValue,string & key,string & value)133 void ThumbnailUriUtils::SplitKeyValue(const string& keyValue, string &key, string &value)
134 {
135 string::size_type pos = keyValue.find('=');
136 if (string::npos != pos) {
137 key = keyValue.substr(0, pos);
138 value = keyValue.substr(pos + 1);
139 }
140 }
141
SplitKeys(const string & query,vector<string> & keys)142 void ThumbnailUriUtils::SplitKeys(const string& query, vector<string>& keys)
143 {
144 string::size_type pos1 = 0;
145 string::size_type pos2 = query.find('&');
146 while (string::npos != pos2) {
147 keys.push_back(query.substr(pos1, pos2-pos1));
148 pos1 = pos2 + 1;
149 pos2 = query.find('&', pos1);
150 }
151 if (pos1 != query.length()) {
152 keys.push_back(query.substr(pos1));
153 }
154 }
155
IsNumber(const string & str)156 bool ThumbnailUriUtils::IsNumber(const string &str)
157 {
158 if (str.empty()) {
159 MEDIA_ERR_LOG("IsNumber input is empty ");
160 return false;
161 }
162
163 for (char const &c : str) {
164 if (isdigit(c) == 0) {
165 return false;
166 }
167 }
168 return true;
169 }
170
ParseThumbnailInfo(const string & uriString)171 bool ThumbnailUriUtils::ParseThumbnailInfo(const string &uriString)
172 {
173 string outFileId;
174 string ourNetworkId;
175 Size outSize;
176 return ParseThumbnailInfo(uriString, outFileId, outSize, ourNetworkId);
177 }
178 } // namespace Media
179 } // namespace OHOS
180