/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "data_uri_utils.h" #include #include #include #include "securec.h" namespace OHOS { namespace AppExecFwk { namespace { const string EMPTY = ""; const std::regex INTEGER_REGEX("^[-+]?([0-9]+)([.]([0-9]+))?$"); const int BUFFER_LEN = 64; const char *SEPARATOR = "/"; }; // namespace /** * @brief Default constructor of DataUriUtils class * @return None */ DataUriUtils::DataUriUtils() {} /** * @brief Default deconstructor of DataUriUtils class * @return None */ DataUriUtils::~DataUriUtils() {} /** * @brief Attaches the given ID to the end of the path component of the given URI. * @param dataUri based on RFC 2396( Uniform Resource Identifier ). * @param id * @return Uri( scheme://authority/path1/path2/path3/updateIDNumber....) */ Uri DataUriUtils::AttachId(const Uri &dataUri, long long id) { // 1. get Path string path = const_cast(dataUri).GetPath(); if (path.empty()) { return dataUri; } string uriString = dataUri.ToString(); std::vector pathVector; const_cast(dataUri).GetPathSegments(pathVector); if (pathVector.empty()) { return dataUri; } string lastPath = pathVector[pathVector.size() - 1]; char longBuffer[BUFFER_LEN] = {0}; int ret = sprintf_s(longBuffer, sizeof(longBuffer), "%lld", id); if (ret == -1) { return dataUri; } // new path string (lastPath+SEPARATOR+number) string newLastPath(""); newLastPath = lastPath + string(SEPARATOR) + string(longBuffer); // find "/+lastPath" string tempLastPath = string(SEPARATOR) + lastPath; auto lastPathPos = uriString.rfind(tempLastPath); uriString.replace(lastPathPos + 1, tempLastPath.size() - 1, newLastPath.c_str()); return Uri(uriString); } /** * @brief Obtains the ID attached to the end of the path component of the given URI. * @param dataUri based on RFC 2396( Uniform Resource Identifier ). * @return long ID */ long long DataUriUtils::GetId(const Uri &dataUri) { // 1. get Path string path = const_cast(dataUri).GetPath(); if (path.empty()) { return -1; } std::vector pathVector; const_cast(dataUri).GetPathSegments(pathVector); if (pathVector.empty()) { return -1; } string lastPath = pathVector[pathVector.size() - 1]; if (!IsNumber(lastPath)) { return -1; } return std::atoll(lastPath.c_str()); } /** * @brief Deletes the ID from the end of the path component of the given URI. * @param dataUri based on RFC 2396( Uniform Resource Identifier ). * @return long ID */ Uri DataUriUtils::DeleteId(const Uri &dataUri) { return UriUpateLastPath(dataUri, EMPTY); } /** * @brief Updates the ID in the specified dataUri * @param dataUri based on RFC 2396( Uniform Resource Identifier ). * @param id indiates Update attached to the end of the path component of the given URI * @return Uri return is the URI after path is updated */ Uri DataUriUtils::UpdateId(const Uri &dataUri, long long id) { char longBuffer[BUFFER_LEN] = {0}; int ret = sprintf_s(longBuffer, sizeof(longBuffer), "%lld", id); if (ret == -1) { return dataUri; } string newLastPath(""); newLastPath = string(longBuffer); return UriUpateLastPath(dataUri, newLastPath); } /** * @brief Does the end path of the path component of the given URI have an ID attached to it? * @param dataUri based on RFC 2396( Uniform Resource Identifier ). * @return bool */ bool DataUriUtils::IsAttachedId(const Uri &dataUri) { // 1. get Path string path = const_cast(dataUri).GetPath(); if (path.empty()) { return false; } std::vector pathVector; const_cast(dataUri).GetPathSegments(pathVector); if (pathVector.empty()) { return false; } string lastPath = pathVector[pathVector.size() - 1]; return IsNumber(lastPath); } /** * @brief Determine whether the string content is a numeric string * @param str indicates stirng. * @return bool */ bool DataUriUtils::IsNumber(const string &str) { return std::regex_match(str, INTEGER_REGEX); } /** * @brief Determine whether the string content is a numeric string * @param dataUri indicates Uri object scheme://authority/path/aaa?query/#fragment * @return Uri return is the URI after path is updated */ Uri DataUriUtils::UriUpateLastPath(const Uri &dataUri, const string &updateLastPath) { std::string strUpdateLastPath; if (updateLastPath.size() > 0) { strUpdateLastPath = SEPARATOR + updateLastPath; } // 1. get Path string path = const_cast(dataUri).GetPath(); if (path.empty()) { return dataUri; } std::vector pathVector; const_cast(dataUri).GetPathSegments(pathVector); if (pathVector.empty()) { return dataUri; } string lastPath = pathVector[pathVector.size() - 1]; if (!IsNumber(lastPath)) { return dataUri; } string uriString = dataUri.ToString(); // find "/+lastPath" int lastPathPos = uriString.rfind(string(SEPARATOR) + lastPath); if (lastPathPos == -1) { return dataUri; } // replace "/lastpath"==>"" uriString.replace(lastPathPos, lastPath.size() + 1, strUpdateLastPath); return Uri(uriString); } } // namespace AppExecFwk } // namespace OHOS