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