diff --git a/interfaces/innerkits/native/file_uri/include/file_uri.h b/interfaces/innerkits/native/file_uri/include/file_uri.h index 66b22e8b4bd827da3b00fdf86f64e24e892ff44a..37dcc448fa673030cfbc0500035e13d273284761 100644 --- a/interfaces/innerkits/native/file_uri/include/file_uri.h +++ b/interfaces/innerkits/native/file_uri/include/file_uri.h @@ -29,12 +29,14 @@ public: std::string GetRealPath(); std::string ToString(); std::string GetFullDirectoryUri(); + std::string GetOriginStr(); explicit FileUri(const std::string &uriOrPath); ~FileUri() = default; private: Uri uri_; + std::string originStr_; }; } // ModuleFileUri } // namespace AppFileService diff --git a/interfaces/innerkits/native/file_uri/src/file_uri.cpp b/interfaces/innerkits/native/file_uri/src/file_uri.cpp index fe9591efbd12dd1252b1b0a496d20e27af948cb0..d345b9c0d6faafcf2398b20f0aba1a7adbcf0dc9 100644 --- a/interfaces/innerkits/native/file_uri/src/file_uri.cpp +++ b/interfaces/innerkits/native/file_uri/src/file_uri.cpp @@ -109,9 +109,14 @@ string FileUri::GetFullDirectoryUri() return ""; } +string FileUri::GetOriginStr() +{ + return originStr_; +} + FileUri::FileUri(const string &uriOrPath): uri_( (uriOrPath.find(FILE_SCHEME_PREFIX) == 0) ? uriOrPath : CommonFunc::GetUriFromPath(uriOrPath) -) +), originStr_(uriOrPath) {} } } // namespace AppFileService diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index ee1a7758bfeacf36173dac4576abcf81e97d47f1..892912221ec92694c40d80d9e4f017ff6a293310 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -103,6 +103,7 @@ ohos_shared_library("fileuri") { "../../common/src/sandbox_helper.cpp", "file_uri/file_uri_n_exporter.cpp", "file_uri/get_uri_from_path.cpp", + "file_uri/js_fileuri.cpp", "file_uri/module.cpp", "file_uri/prop_n_exporter.cpp", ] diff --git a/interfaces/kits/js/file_uri/file_uri_n_exporter.cpp b/interfaces/kits/js/file_uri/file_uri_n_exporter.cpp index 498e8f0afccc30cf3cd89543d0590cd4aca1931e..ee516d0ef98234216ff8bd69daadf36625bce662 100644 --- a/interfaces/kits/js/file_uri/file_uri_n_exporter.cpp +++ b/interfaces/kits/js/file_uri/file_uri_n_exporter.cpp @@ -16,6 +16,7 @@ #include "file_uri_entity.h" #include "file_utils.h" +#include "js_fileuri.h" #include "log.h" namespace OHOS { @@ -67,7 +68,7 @@ napi_value FileUriNExporter::UriToString(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.ToString()).val_; + return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.GetOriginStr()).val_; } napi_value FileUriNExporter::GetFileUriName(napi_env env, napi_callback_info info) @@ -126,6 +127,222 @@ napi_value FileUriNExporter::GetFileUriPath(napi_env env, napi_callback_info inf return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.GetPath()).val_; } +napi_value FileUriNExporter::Normalize(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateUTF8String(env, uri.Normalize()).val_; +} + +napi_value FileUriNExporter::Equals(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + LOGE("Number of arguments unmatched"); + NError(E_PARAMS).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(E_PARAMS).ThrowErr(env); + return nullptr; + } + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + + auto otherEntity = NClass::GetEntityOf(env, funcArg[NARG_POS::FIRST]); + if (!otherEntity) { + LOGE("Failed to get other entity"); + NError(E_PARAMS).ThrowErr(env); + return nullptr; + } + JsFileUri otherUri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateBool(env, uri.Equals(otherUri)).val_; +} + +napi_value FileUriNExporter::IsAbsolute(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateBool(env, uri.IsAbsolute()).val_; +} + +napi_value FileUriNExporter::GetScheme(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateUTF8String(env, uri.GetScheme()).val_; +} + +napi_value FileUriNExporter::GetAuthority(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateUTF8String(env, uri.GetAuthority()).val_; +} + +napi_value FileUriNExporter::GetSsp(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateUTF8String(env, uri.GetSsp()).val_; +} + +napi_value FileUriNExporter::GetUserinfo(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateUTF8String(env, uri.GetUserinfo()).val_; +} + +napi_value FileUriNExporter::GetHost(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateUTF8String(env, uri.GetHost()).val_; +} + +napi_value FileUriNExporter::GetPort(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateUTF8String(env, uri.GetPort()).val_; +} + +napi_value FileUriNExporter::GetQuery(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateUTF8String(env, uri.GetQuery()).val_; +} + +napi_value FileUriNExporter::GetFragment(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + LOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto fileuriEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!fileuriEntity) { + LOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + JsFileUri uri(fileuriEntity->fileUri_.GetOriginStr()); + return NVal::CreateUTF8String(env, uri.GetFragment()).val_; +} + bool FileUriNExporter::Export() { vector props = { @@ -133,6 +350,17 @@ bool FileUriNExporter::Export() NVal::DeclareNapiGetter("name", GetFileUriName), NVal::DeclareNapiGetter("path", GetFileUriPath), NVal::DeclareNapiFunction("getFullDirectoryUri", GetFullDirectoryUri), + NVal::DeclareNapiFunction("normalize", Normalize), + NVal::DeclareNapiFunction("equals", Equals), + NVal::DeclareNapiFunction("checkIsAbsolute", IsAbsolute), + NVal::DeclareNapiGetter("scheme", GetScheme), + NVal::DeclareNapiGetter("authority", GetAuthority), + NVal::DeclareNapiGetter("ssp", GetSsp), + NVal::DeclareNapiGetter("userInfo", GetUserinfo), + NVal::DeclareNapiGetter("host", GetHost), + NVal::DeclareNapiGetter("port", GetPort), + NVal::DeclareNapiGetter("query", GetQuery), + NVal::DeclareNapiGetter("fragment", GetFragment), }; auto [succ, classValue] = NClass::DefineClass(exports_.env_, className, Constructor, std::move(props)); diff --git a/interfaces/kits/js/file_uri/file_uri_n_exporter.h b/interfaces/kits/js/file_uri/file_uri_n_exporter.h index 90ba26917cc21d49b471b4d8ec5a02abed396edc..166fe814bf08f56430e69570f36143e91854fa09 100644 --- a/interfaces/kits/js/file_uri/file_uri_n_exporter.h +++ b/interfaces/kits/js/file_uri/file_uri_n_exporter.h @@ -32,6 +32,17 @@ public: static napi_value GetFileUriName(napi_env env, napi_callback_info info); static napi_value GetFileUriPath(napi_env env, napi_callback_info info); static napi_value GetFullDirectoryUri(napi_env env, napi_callback_info info); + static napi_value Normalize(napi_env env, napi_callback_info info); + static napi_value Equals(napi_env env, napi_callback_info cbinfo); + static napi_value IsAbsolute(napi_env env, napi_callback_info info); + static napi_value GetScheme(napi_env env, napi_callback_info info); + static napi_value GetAuthority(napi_env env, napi_callback_info info); + static napi_value GetSsp(napi_env env, napi_callback_info info); + static napi_value GetUserinfo(napi_env env, napi_callback_info info); + static napi_value GetHost(napi_env env, napi_callback_info info); + static napi_value GetPort(napi_env env, napi_callback_info info); + static napi_value GetQuery(napi_env env, napi_callback_info info); + static napi_value GetFragment(napi_env env, napi_callback_info info); FileUriNExporter(napi_env env, napi_value exports); ~FileUriNExporter() override; diff --git a/interfaces/kits/js/file_uri/js_fileuri.cpp b/interfaces/kits/js/file_uri/js_fileuri.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c38d58509041af1d83ee4b363bb62007be9419ba --- /dev/null +++ b/interfaces/kits/js/file_uri/js_fileuri.cpp @@ -0,0 +1,530 @@ +/* + * Copyright (c) 2022 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 "js_fileuri.h" +#include "utils/log.h" +namespace OHOS::AppFileService::ModuleFileUri { + std::bitset g_ruleAlpha; + std::bitset g_ruleScheme; + std::bitset g_ruleUrlc; + std::bitset g_rulePath; + std::bitset g_ruleUserInfo; + std::bitset g_ruleDigit; + std::bitset g_rulePort; + void JsFileUri ::PreliminaryWork() const + { + std::string digitAggregate = "0123456789"; + for (size_t i = 0; i < digitAggregate.size(); ++i) { + g_ruleDigit.set(digitAggregate[i]); + } + + std::string alphasAggregate = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + for (size_t i = 0; i < alphasAggregate.size(); ++i) { + g_ruleAlpha.set(alphasAggregate[i]); + } + + std::string schemeAggregate = digitAggregate + alphasAggregate + "+-."; + for (size_t i = 0; i < schemeAggregate.size(); ++i) { + g_ruleScheme.set(schemeAggregate[i]); + } + + std::string uricAggregate = schemeAggregate + ";/?:@&=$,[]_!~*'()%"; + for (size_t i = 0; i < uricAggregate.size(); ++i) { + g_ruleUrlc.set(uricAggregate[i]); + } + + std::string pathAggregate = schemeAggregate + ";/:@&=$,_!~*'()%"; + for (size_t i = 0; i < pathAggregate.size(); ++i) { + g_rulePath.set(pathAggregate[i]); + } + + std::string userInfoAggregate = schemeAggregate + ";:&=$,_!~*'()%"; + for (size_t i = 0; i < userInfoAggregate.size(); ++i) { + g_ruleUserInfo.set(userInfoAggregate[i]); + } + + std::string portAggregate = digitAggregate + alphasAggregate + ".:@-;&=+$,-_!~*'()"; + for (size_t i = 0; i < portAggregate.size(); ++i) { + g_rulePort.set(portAggregate[i]); + } + } + + JsFileUri::JsFileUri(const std::string input) + { + PreliminaryWork(); + errStr_ = ""; + if (input.empty()) { + errStr_ = "uri is empty"; + return; + } + inputUri_ = input; + AnalysisUri(); + } + + void JsFileUri::AnalysisUri() + { + data_ = inputUri_; + size_t pos = data_.find('#'); // Fragment + if (pos != std::string::npos) { + AnalysisFragment(pos); + if (!errStr_.empty()) { + return; + } + } + pos = data_.find('?'); // Query + if (pos != std::string::npos) { + AnalysisQuery(pos); + if (!errStr_.empty()) { + return; + } + } + pos = data_.find(':'); // Scheme + if (pos != std::string::npos) { + AnalysisScheme(pos); + if (!errStr_.empty()) { + return; + } + } else { + SpecialPath(); + if (!errStr_.empty()) { + return; + } + uriData_.schemeSpecificPart = data_ + "?" + uriData_.query; + return; + } + pos = data_.find("//"); // userInfo path host port ipv4 or ipv6 + if (pos != std::string::npos && pos == 0) { + uriData_.schemeSpecificPart = data_ + "?" + uriData_.query; + data_ = data_.substr(2); // 2:Intercept the string from the second subscript + AnalysisHostAndPath(); + if (!errStr_.empty()) { + return; + } + } else if (data_[0] == '/') { + uriData_.path = data_; + uriData_.schemeSpecificPart = data_ + uriData_.query; + data_ = ""; + } else if (!data_.empty()) { + uriData_.schemeSpecificPart = data_ + uriData_.query; + uriData_.query = ""; + data_ = ""; + } + } + + bool JsFileUri::CheckCharacter(std::string data, std::bitset rule, bool flag) const + { + size_t dataLen = data.size(); + for (size_t i = 0; i < dataLen; ++i) { + if (static_cast(data[i]) >= 0 && static_cast(data[i]) < 128) { // 128:ASCII Max Number + bool isLegal = rule.test(data[i]); + if (!isLegal) { + return false; + } + } else if (!flag) { + return false; + } + } + return true; + } + + void JsFileUri::SpecialPath() + { + if (!CheckCharacter(data_, g_rulePath, true)) { + errStr_ = "SpecialPath does not conform to the rule"; + return; + } + uriData_.path = data_; + data_ = ""; + } + + void JsFileUri::AnalysisFragment(size_t pos) + { + if (pos == 0) { + errStr_ = "#It can't be the first"; + return; + } + std::string fragment = data_.substr(pos + 1); + if (!CheckCharacter(fragment, g_ruleUrlc, true)) { + errStr_ = "Fragment does not conform to the rule"; + return; + } + uriData_.fragment = fragment; + data_ = data_.substr(0, pos); + } + + void JsFileUri::AnalysisQuery(size_t pos) + { + std::string query = data_.substr(pos + 1); + if (!CheckCharacter(query, g_ruleUrlc, true)) { + errStr_ = "Query does not conform to the rule"; + return; + } + uriData_.query = query; + data_ = data_.substr(0, pos); + } + + void JsFileUri::AnalysisScheme(size_t pos) + { + size_t slashPos = data_.find('/'); + if (slashPos != std::string::npos && slashPos < pos) { + SpecialPath(); + uriData_.schemeSpecificPart = uriData_.path + "?" + uriData_.query; + data_ = ""; + } else { + if (!g_ruleAlpha.test(data_[0])) { + errStr_ = "Scheme the first character must be a letter"; + return; + } + std::string scheme = data_.substr(0, pos); + if (!CheckCharacter(scheme, g_ruleScheme, false)) { + errStr_ = "scheme does not conform to the rule"; + return; + } + uriData_.scheme = scheme; + data_ = data_.substr(pos + 1); + } + } + + void JsFileUri::AnalysisHostAndPath() + { + if (data_.empty()) { + return; + } + // find path + size_t pos = data_.find('/'); + if (pos != std::string::npos) { + AnalysisPath(pos); + if (!errStr_.empty()) { + return; + } + } + + uriData_.authority = data_; + + // find UserInfo + pos = data_.find('@'); + if (pos != std::string::npos) { + AnalysisUserInfo(pos); + if (!errStr_.empty()) { + return; + } + } + bool isLawfulProt = true; + // find port + pos = data_.rfind(':'); + if (pos != std::string::npos) { + size_t pos1 = data_.rfind(']'); + if (pos1 == std::string::npos || pos > pos1) { + isLawfulProt = AnalysisPort(pos); + } + if (!errStr_.empty()) { + return; + } + } + + // find ipv4 or ipv6 or host + if (data_[0] == '[') { + if (data_[data_.size() - 1] == ']') { + // IPV6 + if (!isLawfulProt) { + errStr_ = "Prot does not conform to the rule"; + return; + } + AnalysisIPV6(); + } else { + errStr_ = "IPv6 is missing a closing bracket"; + return; + } + } else { + // ipv4 + if (!isLawfulProt || !AnalysisIPV4()) { + uriData_.port = -1; + uriData_.host = ""; + uriData_.userInfo = ""; + } + } + } + + void JsFileUri::AnalysisPath(size_t pos) + { + std::string path = data_.substr(pos); + if (!CheckCharacter(path, g_rulePath, true)) { + errStr_ = "path does not conform to the rule"; + return; + } + uriData_.path = path; + data_ = data_.substr(0, pos); + } + + void JsFileUri::AnalysisUserInfo(size_t pos) + { + std::string userInfo = data_.substr(0, pos); + if (!CheckCharacter(userInfo, g_ruleUserInfo, true)) { + errStr_ = "userInfo does not conform to the rule"; + return; + } + uriData_.userInfo = userInfo; + data_ = data_.substr(pos + 1); + } + + bool JsFileUri::AnalysisPort(size_t pos) + { + std::string port = data_.substr(pos + 1); + if (!CheckCharacter(port, g_rulePort, true)) { + errStr_ = "port does not conform to the rule"; + return false; + } else if (CheckCharacter(port, g_ruleDigit, false)) { + if (port.size() == 0) { + return false; + } + uriData_.port = std::stoi(port); + data_ = data_.substr(0, pos); + return true; + } else { + data_ = data_.substr(0, pos); + return false; + } + return false; + } + + bool JsFileUri::AnalysisIPV4() + { + std::regex ipv4("((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"); + std::regex hostname("(([a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?\\.)+([a-zA-Z]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?))|" + "([a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)"); + bool isIpv4 = std::regex_match(data_, ipv4); + bool isHosName = std::regex_match(data_, hostname); + if (!isIpv4 && !isHosName) { + return false; + } else { + uriData_.host = data_; + data_ = ""; + return true; + } + } + + void JsFileUri::AnalysisIPV6() + { + std::string str = data_.substr(1, data_.size() - 2); // 2:Intercept the string from the second subscript + std::regex ipv6("(::|(:((:[0-9A-Fa-f]{1,4}){1,7}))|(([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|" + "(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|:))|(([0-9A-Fa-f]{1,4}:){2}" + "(((:[0-9A-Fa-f]{1,4}){1,5})|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})" + "|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|:))|(([0-9A-Fa-f]{1,4}:){5}" + "(((:[0-9A-Fa-f]{1,4}){1,2})|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|" + "(((:(:[0-9A-Fa-f]{1,4}){0,5}:)|(([0-9A-Fa-f]{1,4}:){1}(:[0-9A-Fa-f]{1,4}){0,4}:)" + "|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}:)|(([0-9A-Fa-f]{1,4}:){3}" + "(:[0-9A-Fa-f]{1,4}){0,2}:)|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4})?:)|" + "(([0-9A-Fa-f]{1,4}:){5}:)|(([0-9A-Fa-f]{1,4}:){6}))((25[0-5]|2[0-4]\\d|1\\d{2}|" + "[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)))(%[a-zA-Z0-9._]+)?"); + if (!std::regex_match(str, ipv6)) { + errStr_ = "ipv6 does not conform to the rule"; + return; + } + uriData_.host = data_; + data_ = ""; + } + + bool JsFileUri::Equals(const JsFileUri other) const + { + if (uriData_.port != other.uriData_.port) { + return false; + } + if (uriData_.scheme != other.uriData_.scheme) { + return false; + } + if (uriData_.userInfo != other.uriData_.userInfo) { + return false; + } + if (uriData_.host != other.uriData_.host) { + return false; + } + if (uriData_.query != other.uriData_.query) { + return false; + } + if (uriData_.fragment != other.uriData_.fragment) { + return false; + } + if (uriData_.path != other.uriData_.path) { + return false; + } + if (uriData_.authority != other.uriData_.authority) { + return false; + } + if (uriData_.schemeSpecificPart != other.uriData_.schemeSpecificPart) { + return false; + } + return true; + } + + std::string JsFileUri::ToString() const + { + return inputUri_; + } + + bool JsFileUri::IsAbsolute() const + { + return !uriData_.scheme.empty(); + } + + std::string JsFileUri::IsFailed() const + { + return errStr_; + } + + std::string JsFileUri::Normalize() const + { + std::vector temp; + size_t pathLen = uriData_.path.size(); + if (pathLen == 0) { + return this->inputUri_; + } + size_t pos = 0; + size_t left = 0; + while ((pos = uriData_.path.find('/', left)) != std::string::npos) { + temp.push_back(uriData_.path.substr(left, pos - left)); + left = pos + 1; + } + if (left != pathLen) { + temp.push_back(uriData_.path.substr(left)); + } + size_t tempLen = temp.size(); + std::vector normalizeTemp; + for (size_t i = 0; i < tempLen; ++i) { + if (!temp[i].empty() && !(temp[i] == ".") && !(temp[i] == "..")) { + normalizeTemp.push_back(temp[i]); + } + if (temp[i] == "..") { + if (!normalizeTemp.empty() && normalizeTemp.back() != "..") { + normalizeTemp.pop_back(); + } else { + normalizeTemp.push_back(temp[i]); + } + } + } + std::string normalizePath = ""; + tempLen = normalizeTemp.size(); + if (tempLen == 0) { + normalizePath = "/"; + } else { + for (size_t i = 0; i < tempLen; ++i) { + normalizePath += "/" + normalizeTemp[i]; + } + } + return Split(normalizePath); + } + + + std::string JsFileUri::Split(const std::string &path) const + { + std::string normalizeUri = ""; + if (!uriData_.scheme.empty()) { + normalizeUri += uriData_.scheme + ":"; + } + if (uriData_.path.empty()) { + normalizeUri += uriData_.schemeSpecificPart; + } else { + if (!uriData_.host.empty()) { + normalizeUri += "//"; + if (!uriData_.userInfo.empty()) { + normalizeUri += uriData_.userInfo + "@"; + } + normalizeUri += uriData_.host; + if (uriData_.port != -1) { + normalizeUri += ":" + std::to_string(uriData_.port); + } + } else if (!uriData_.authority.empty()) { + normalizeUri += "//" + uriData_.authority; + } + normalizeUri += path; + } + if (!uriData_.query.empty()) { + normalizeUri += "?" + uriData_.query; + } + if (!uriData_.fragment.empty()) { + normalizeUri += "#" + uriData_.fragment; + } + return normalizeUri; + } + + + std::string JsFileUri::GetScheme() const + { + if (uriData_.scheme.empty()) { + return "null"; + } + return uriData_.scheme; + } + + std::string JsFileUri::GetAuthority() const + { + if (uriData_.authority.empty()) { + return "null"; + } + return uriData_.authority; + } + + std::string JsFileUri::GetSsp() const + { + if (uriData_.schemeSpecificPart.empty()) { + return "null"; + } + return uriData_.schemeSpecificPart; + } + + std::string JsFileUri::GetUserinfo() const + { + if (uriData_.userInfo.empty()) { + return "null"; + } + return uriData_.userInfo; + } + + std::string JsFileUri::GetHost() const + { + if (uriData_.host.empty()) { + return "null"; + } + return uriData_.host; + } + + std::string JsFileUri::GetPort() const + { + return std::to_string(uriData_.port); + } + + std::string JsFileUri::GetPath() const + { + if (uriData_.path.empty()) { + return "null"; + } + return uriData_.path; + } + + std::string JsFileUri::GetQuery() const + { + if (uriData_.query.empty()) { + return "null"; + } + return uriData_.query; + } + + std::string JsFileUri::GetFragment() const + { + if (uriData_.fragment.empty()) { + return "null"; + } + return uriData_.fragment; + } +} // namespace OHOS::JsFileUri diff --git a/interfaces/kits/js/file_uri/js_fileuri.h b/interfaces/kits/js/file_uri/js_fileuri.h new file mode 100644 index 0000000000000000000000000000000000000000..40b87c30532788d2850d33e98c8b4854a5889367 --- /dev/null +++ b/interfaces/kits/js/file_uri/js_fileuri.h @@ -0,0 +1,150 @@ + /* + * Copyright (c) 2022 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. + */ + +#ifndef FILEURI_JS_FILEURI_H +#define FILEURI_JS_FILEURI_H + +#include +#include +#include +#include +#include + +namespace OHOS::AppFileService::ModuleFileUri { + constexpr int MAX_BIT_SIZE = 128; + struct UriData { + int port = -1; + std::string scheme = ""; + std::string userInfo = ""; + std::string host = ""; + std::string query = ""; + std::string fragment = ""; + std::string path = ""; + std::string authority = ""; + std::string schemeSpecificPart = ""; + }; + + class JsFileUri { + public: + /** + * URI constructor, which is used to instantiate a URI object. + * + * @param input Constructs a URI by parsing a given string. + */ + explicit JsFileUri(const std::string input); + + /** + * The destructor of the Uri. + */ + virtual ~JsFileUri() {} + + /** + * Tests whether this URI is equivalent to other URI objects. + * + * @param other URI object to be compared + */ + bool Equals(const JsFileUri other) const; + + /** + * Indicates whether this URI is an absolute URI. + */ + bool IsAbsolute() const; + + /** + * Determine whether parsing failed. + */ + std::string IsFailed() const; + + /** + * Returns the serialized URI as a string. + */ + std::string ToString() const; + + /** + * Normalize the path of this URI. + */ + std::string Normalize() const; + + /** + * Gets the protocol part of the URI. + */ + std::string GetScheme() const; + + /** + * Gets the decoding permission component part of this URI. + */ + std::string GetAuthority() const; + + /** + * Gets the decoding scheme-specific part of the URI. + */ + std::string GetSsp() const; + + /** + * Obtains the user information part of the URI. + */ + std::string GetUserinfo() const; + + /** + * Gets the hostname portion of the URI without a port. + */ + std::string GetHost() const; + + /** + * Gets the hostname portion of the URI without a port. + */ + std::string GetPort() const; + + /** + * Gets the path portion of the URI. + */ + std::string GetPath() const; + + /** + * Gets the query portion of the URI. + */ + std::string GetQuery() const; + + /** + * Gets the fragment part of the URI. + */ + std::string GetFragment() const; + + private: + void PreliminaryWork() const; + void AnalysisUri(); + void SpecialPath(); + void AnalysisFragment(size_t pos); + void AnalysisQuery(size_t pos); + void AnalysisScheme(size_t pos); + void AnalysisHostAndPath(); + void AnalysisPath(size_t pos); + void AnalysisUserInfo(size_t pos); + void AnalysisIPV6(); + + bool CheckCharacter(std::string data, std::bitset rule, bool flag) const; + bool AnalysisPort(size_t pos); + bool AnalysisIPV4(); + + std::string Split(const std::string &path) const; + + private: + UriData uriData_; + std::string data_ {}; + std::string inputUri_ {}; + std::string errStr_ {}; + }; +} // namespace OHOS::Uri +#endif // URI_JS_URI_H