• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include "data_uri_utils.h"
16 #include <vector>
17 #include <memory>
18 #include <regex>
19 #include "securec.h"
20 
21 namespace OHOS {
22 namespace AppExecFwk {
23 
24 namespace {
25 const string EMPTY = "";
26 const std::regex INTEGER_REGEX("^[-+]?([0-9]+)([.]([0-9]+))?$");
27 const int BUFFER_LEN = 64;
28 const char *SEPARATOR = "/";
29 };  // namespace
30 
31 /**
32  * @brief Default constructor of DataUriUtils class
33  * @return None
34  */
DataUriUtils()35 DataUriUtils::DataUriUtils()
36 {}
37 
38 /**
39  * @brief Default deconstructor of DataUriUtils class
40  * @return None
41  */
~DataUriUtils()42 DataUriUtils::~DataUriUtils()
43 {}
44 
45 /**
46  * @brief Attaches the given ID to the end of the path component of the given URI.
47  * @param dataUri based on RFC 2396( Uniform Resource Identifier ).
48  * @param id
49  * @return Uri( scheme://authority/path1/path2/path3/updateIDNumber....)
50  */
AttachId(const Uri & dataUri,long long id)51 Uri DataUriUtils::AttachId(const Uri &dataUri, long long id)
52 {
53     // 1. get Path
54     string path = const_cast<Uri &>(dataUri).GetPath();
55     if (path.empty()) {
56         return dataUri;
57     }
58 
59     string uriString = dataUri.ToString();
60 
61     std::vector<string> pathVector;
62     const_cast<Uri &>(dataUri).GetPathSegments(pathVector);
63     if (pathVector.empty()) {
64         return dataUri;
65     }
66     string lastPath = pathVector[pathVector.size() - 1];
67 
68     char longBuffer[BUFFER_LEN] = {0};
69 
70     int ret = sprintf_s(longBuffer, sizeof(longBuffer), "%lld", id);
71     if (ret == -1) {
72         return dataUri;
73     }
74     // new path string (lastPath+SEPARATOR+number)
75     string newLastPath("");
76 
77     newLastPath = lastPath + string(SEPARATOR) + string(longBuffer);
78 
79     // find "/+lastPath"
80     string tempLastPath = string(SEPARATOR) + lastPath;
81     auto lastPathPos = uriString.rfind(tempLastPath);
82 
83     uriString.replace(lastPathPos + 1, tempLastPath.size() - 1, newLastPath.c_str());
84     return Uri(uriString);
85 }
86 
87 /**
88  * @brief Obtains the ID attached to the end of the path component of the given URI.
89  * @param dataUri based on RFC 2396( Uniform Resource Identifier ).
90  * @return long ID
91  */
GetId(const Uri & dataUri)92 long long DataUriUtils::GetId(const Uri &dataUri)
93 {
94     // 1. get Path
95     string path = const_cast<Uri &>(dataUri).GetPath();
96     if (path.empty()) {
97         return -1;
98     }
99     std::vector<string> pathVector;
100     const_cast<Uri &>(dataUri).GetPathSegments(pathVector);
101     if (pathVector.empty()) {
102         return -1;
103     }
104     string lastPath = pathVector[pathVector.size() - 1];
105     if (!IsNumber(lastPath)) {
106         return -1;
107     }
108     return std::atoll(lastPath.c_str());
109 }
110 
111 /**
112  * @brief Deletes the ID from the end of the path component of the given URI.
113  * @param dataUri based on RFC 2396( Uniform Resource Identifier ).
114  * @return long ID
115  */
DeleteId(const Uri & dataUri)116 Uri DataUriUtils::DeleteId(const Uri &dataUri)
117 {
118     return UriUpateLastPath(dataUri, EMPTY);
119 }
120 
121 /**
122  * @brief Updates the ID in the specified dataUri
123  * @param dataUri based on RFC 2396( Uniform Resource Identifier ).
124  * @param id indiates Update attached to the end of the path component of the given URI
125  * @return Uri return is the URI after path is updated
126  */
UpdateId(const Uri & dataUri,long long id)127 Uri DataUriUtils::UpdateId(const Uri &dataUri, long long id)
128 {
129     char longBuffer[BUFFER_LEN] = {0};
130     int ret = sprintf_s(longBuffer, sizeof(longBuffer), "%lld", id);
131     if (ret == -1) {
132         return dataUri;
133     }
134 
135     string newLastPath("");
136     newLastPath = string(longBuffer);
137 
138     return UriUpateLastPath(dataUri, newLastPath);
139 }
140 
141 /**
142  * @brief Does the end path of the path component of the given URI have an ID attached to it?
143  * @param dataUri based on RFC 2396( Uniform Resource Identifier ).
144  * @return bool
145  */
IsAttachedId(const Uri & dataUri)146 bool DataUriUtils::IsAttachedId(const Uri &dataUri)
147 {
148     // 1. get Path
149     string path = const_cast<Uri &>(dataUri).GetPath();
150     if (path.empty()) {
151         return false;
152     }
153 
154     std::vector<string> pathVector;
155     const_cast<Uri &>(dataUri).GetPathSegments(pathVector);
156     if (pathVector.empty()) {
157         return false;
158     }
159     string lastPath = pathVector[pathVector.size() - 1];
160 
161     return IsNumber(lastPath);
162 }
163 
164 /**
165  * @brief Determine whether the string content is a numeric string
166  * @param str indicates stirng.
167  * @return bool
168  */
IsNumber(const string & str)169 bool DataUriUtils::IsNumber(const string &str)
170 {
171     return std::regex_match(str, INTEGER_REGEX);
172 }
173 
174 /**
175  * @brief Determine whether the string content is a numeric string
176  * @param dataUri indicates Uri object
177    scheme://authority/path/aaa?query/#fragment
178  * @return Uri return is the URI after path is updated
179  */
UriUpateLastPath(const Uri & dataUri,const string & updateLastPath)180 Uri DataUriUtils::UriUpateLastPath(const Uri &dataUri, const string &updateLastPath)
181 {
182     std::string strUpdateLastPath;
183 
184     if (updateLastPath.size() > 0) {
185         strUpdateLastPath = SEPARATOR + updateLastPath;
186     }
187 
188     // 1. get Path
189     string path = const_cast<Uri &>(dataUri).GetPath();
190     if (path.empty()) {
191         return dataUri;
192     }
193 
194     std::vector<string> pathVector;
195     const_cast<Uri &>(dataUri).GetPathSegments(pathVector);
196     if (pathVector.empty()) {
197         return dataUri;
198     }
199     string lastPath = pathVector[pathVector.size() - 1];
200     if (!IsNumber(lastPath)) {
201         return dataUri;
202     }
203 
204     string uriString = dataUri.ToString();
205     // find "/+lastPath"
206     int lastPathPos = uriString.rfind(string(SEPARATOR) + lastPath);
207     if (lastPathPos == -1) {
208         return dataUri;
209     }
210 
211     // replace "/lastpath"==>""
212     uriString.replace(lastPathPos, lastPath.size() + 1, strUpdateLastPath);
213 
214     return Uri(uriString);
215 }
216 
217 }  // namespace AppExecFwk
218 }  // namespace OHOS