18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#include "proxy_filesystem.h"
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <algorithm>
198bf80f4bSopenharmony_ci#include <cstring>
208bf80f4bSopenharmony_ci
218bf80f4bSopenharmony_ci#include <base/containers/iterator.h>
228bf80f4bSopenharmony_ci#include <base/containers/string.h>
238bf80f4bSopenharmony_ci#include <base/containers/string_view.h>
248bf80f4bSopenharmony_ci#include <base/containers/type_traits.h>
258bf80f4bSopenharmony_ci#include <base/containers/unique_ptr.h>
268bf80f4bSopenharmony_ci#include <base/containers/vector.h>
278bf80f4bSopenharmony_ci#include <base/namespace.h>
288bf80f4bSopenharmony_ci#include <core/io/intf_directory.h>
298bf80f4bSopenharmony_ci#include <core/io/intf_file.h>
308bf80f4bSopenharmony_ci#include <core/namespace.h>
318bf80f4bSopenharmony_ci
328bf80f4bSopenharmony_ci#include "file_manager.h"
338bf80f4bSopenharmony_ci#include "path_tools.h"
348bf80f4bSopenharmony_ci#include "proxy_directory.h"
358bf80f4bSopenharmony_ci
368bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE()
378bf80f4bSopenharmony_ciusing BASE_NS::move;
388bf80f4bSopenharmony_ciusing BASE_NS::string;
398bf80f4bSopenharmony_ciusing BASE_NS::string_view;
408bf80f4bSopenharmony_ciusing BASE_NS::vector;
418bf80f4bSopenharmony_ci
428bf80f4bSopenharmony_ciProxyFilesystem::ProxyFilesystem(FileManager& fileManager, const string_view destination)
438bf80f4bSopenharmony_ci    : fileManager_(fileManager), destinations_()
448bf80f4bSopenharmony_ci{
458bf80f4bSopenharmony_ci    AppendSearchPath(destination);
468bf80f4bSopenharmony_ci}
478bf80f4bSopenharmony_ci
488bf80f4bSopenharmony_civoid ProxyFilesystem::AppendSearchPath(string_view path)
498bf80f4bSopenharmony_ci{
508bf80f4bSopenharmony_ci    if (path.back() == '/') {
518bf80f4bSopenharmony_ci        path.remove_suffix(1);
528bf80f4bSopenharmony_ci    }
538bf80f4bSopenharmony_ci    destinations_.emplace_back(path);
548bf80f4bSopenharmony_ci}
558bf80f4bSopenharmony_ci
568bf80f4bSopenharmony_civoid ProxyFilesystem::PrependSearchPath(string_view path)
578bf80f4bSopenharmony_ci{
588bf80f4bSopenharmony_ci    if (path.back() == '/') {
598bf80f4bSopenharmony_ci        path.remove_suffix(1);
608bf80f4bSopenharmony_ci    }
618bf80f4bSopenharmony_ci    destinations_.emplace(destinations_.begin(), path);
628bf80f4bSopenharmony_ci}
638bf80f4bSopenharmony_ci
648bf80f4bSopenharmony_civoid ProxyFilesystem::RemoveSearchPath(string_view destination)
658bf80f4bSopenharmony_ci{
668bf80f4bSopenharmony_ci    if (destination.back() == '/') {
678bf80f4bSopenharmony_ci        destination.remove_suffix(1);
688bf80f4bSopenharmony_ci    }
698bf80f4bSopenharmony_ci    const auto it = std::find(destinations_.cbegin(), destinations_.cend(), destination);
708bf80f4bSopenharmony_ci    if (it != destinations_.cend()) {
718bf80f4bSopenharmony_ci        destinations_.erase(it);
728bf80f4bSopenharmony_ci    }
738bf80f4bSopenharmony_ci}
748bf80f4bSopenharmony_ci
758bf80f4bSopenharmony_ciIDirectory::Entry ProxyFilesystem::GetEntry(const string_view path)
768bf80f4bSopenharmony_ci{
778bf80f4bSopenharmony_ci    auto normalizedPath = NormalizePath(path);
788bf80f4bSopenharmony_ci    if (!normalizedPath.empty()) {
798bf80f4bSopenharmony_ci        for (auto&& destination : destinations_) {
808bf80f4bSopenharmony_ci            auto file = fileManager_.GetEntry(destination + normalizedPath);
818bf80f4bSopenharmony_ci            if (file.type != IDirectory::Entry::UNKNOWN) {
828bf80f4bSopenharmony_ci                return file;
838bf80f4bSopenharmony_ci            }
848bf80f4bSopenharmony_ci        }
858bf80f4bSopenharmony_ci    }
868bf80f4bSopenharmony_ci    return {};
878bf80f4bSopenharmony_ci}
888bf80f4bSopenharmony_ciIFile::Ptr ProxyFilesystem::OpenFile(const string_view path)
898bf80f4bSopenharmony_ci{
908bf80f4bSopenharmony_ci    auto normalizedPath = NormalizePath(path);
918bf80f4bSopenharmony_ci    if (!normalizedPath.empty()) {
928bf80f4bSopenharmony_ci        for (auto&& destination : destinations_) {
938bf80f4bSopenharmony_ci            auto file = fileManager_.OpenFile(destination + normalizedPath);
948bf80f4bSopenharmony_ci            if (file) {
958bf80f4bSopenharmony_ci                return file;
968bf80f4bSopenharmony_ci            }
978bf80f4bSopenharmony_ci        }
988bf80f4bSopenharmony_ci    }
998bf80f4bSopenharmony_ci
1008bf80f4bSopenharmony_ci    return IFile::Ptr();
1018bf80f4bSopenharmony_ci}
1028bf80f4bSopenharmony_ci
1038bf80f4bSopenharmony_ciIFile::Ptr ProxyFilesystem::CreateFile(const string_view path)
1048bf80f4bSopenharmony_ci{
1058bf80f4bSopenharmony_ci    auto normalizedPath = NormalizePath(path);
1068bf80f4bSopenharmony_ci    if (!normalizedPath.empty()) {
1078bf80f4bSopenharmony_ci        for (auto&& destination : destinations_) {
1088bf80f4bSopenharmony_ci            auto file = fileManager_.CreateFile(destination + normalizedPath);
1098bf80f4bSopenharmony_ci            if (file) {
1108bf80f4bSopenharmony_ci                return file;
1118bf80f4bSopenharmony_ci            }
1128bf80f4bSopenharmony_ci        }
1138bf80f4bSopenharmony_ci    }
1148bf80f4bSopenharmony_ci
1158bf80f4bSopenharmony_ci    return IFile::Ptr();
1168bf80f4bSopenharmony_ci}
1178bf80f4bSopenharmony_ci
1188bf80f4bSopenharmony_cibool ProxyFilesystem::DeleteFile(const string_view path)
1198bf80f4bSopenharmony_ci{
1208bf80f4bSopenharmony_ci    auto normalizedPath = NormalizePath(path);
1218bf80f4bSopenharmony_ci    if (!normalizedPath.empty()) {
1228bf80f4bSopenharmony_ci        for (auto&& destination : destinations_) {
1238bf80f4bSopenharmony_ci            if (fileManager_.DeleteFile(destination + normalizedPath)) {
1248bf80f4bSopenharmony_ci                return true;
1258bf80f4bSopenharmony_ci            }
1268bf80f4bSopenharmony_ci        }
1278bf80f4bSopenharmony_ci    }
1288bf80f4bSopenharmony_ci
1298bf80f4bSopenharmony_ci    return false;
1308bf80f4bSopenharmony_ci}
1318bf80f4bSopenharmony_ci
1328bf80f4bSopenharmony_ciIDirectory::Ptr ProxyFilesystem::OpenDirectory(const string_view path)
1338bf80f4bSopenharmony_ci{
1348bf80f4bSopenharmony_ci    IDirectory::Ptr proxyDirectory;
1358bf80f4bSopenharmony_ci    vector<IDirectory::Ptr> directories;
1368bf80f4bSopenharmony_ci    auto normalizedPath = NormalizePath(path);
1378bf80f4bSopenharmony_ci    if (!normalizedPath.empty()) {
1388bf80f4bSopenharmony_ci        for (auto&& destination : destinations_) {
1398bf80f4bSopenharmony_ci            auto directory = fileManager_.OpenDirectory(destination + normalizedPath);
1408bf80f4bSopenharmony_ci            if (directory) {
1418bf80f4bSopenharmony_ci                directories.push_back(move(directory));
1428bf80f4bSopenharmony_ci            }
1438bf80f4bSopenharmony_ci        }
1448bf80f4bSopenharmony_ci    }
1458bf80f4bSopenharmony_ci
1468bf80f4bSopenharmony_ci    if (!directories.empty()) {
1478bf80f4bSopenharmony_ci        proxyDirectory.reset(new ProxyDirectory(move(directories)));
1488bf80f4bSopenharmony_ci    }
1498bf80f4bSopenharmony_ci
1508bf80f4bSopenharmony_ci    return proxyDirectory;
1518bf80f4bSopenharmony_ci}
1528bf80f4bSopenharmony_ci
1538bf80f4bSopenharmony_ciIDirectory::Ptr ProxyFilesystem::CreateDirectory(const string_view path)
1548bf80f4bSopenharmony_ci{
1558bf80f4bSopenharmony_ci    auto normalizedPath = NormalizePath(path);
1568bf80f4bSopenharmony_ci    if (!normalizedPath.empty()) {
1578bf80f4bSopenharmony_ci        for (auto&& destination : destinations_) {
1588bf80f4bSopenharmony_ci            auto directory = fileManager_.CreateDirectory(destination + normalizedPath);
1598bf80f4bSopenharmony_ci            if (directory) {
1608bf80f4bSopenharmony_ci                return directory;
1618bf80f4bSopenharmony_ci            }
1628bf80f4bSopenharmony_ci        }
1638bf80f4bSopenharmony_ci    }
1648bf80f4bSopenharmony_ci
1658bf80f4bSopenharmony_ci    return IDirectory::Ptr();
1668bf80f4bSopenharmony_ci}
1678bf80f4bSopenharmony_ci
1688bf80f4bSopenharmony_cibool ProxyFilesystem::DeleteDirectory(const string_view path)
1698bf80f4bSopenharmony_ci{
1708bf80f4bSopenharmony_ci    auto normalizedPath = NormalizePath(path);
1718bf80f4bSopenharmony_ci    if (!normalizedPath.empty()) {
1728bf80f4bSopenharmony_ci        for (auto&& destination : destinations_) {
1738bf80f4bSopenharmony_ci            if (fileManager_.DeleteDirectory(destination + normalizedPath)) {
1748bf80f4bSopenharmony_ci                return true;
1758bf80f4bSopenharmony_ci            }
1768bf80f4bSopenharmony_ci        }
1778bf80f4bSopenharmony_ci    }
1788bf80f4bSopenharmony_ci
1798bf80f4bSopenharmony_ci    return false;
1808bf80f4bSopenharmony_ci}
1818bf80f4bSopenharmony_ci
1828bf80f4bSopenharmony_cibool ProxyFilesystem::Rename(const string_view fromPath, const string_view toPath)
1838bf80f4bSopenharmony_ci{
1848bf80f4bSopenharmony_ci    if (!fromPath.empty() && !toPath.empty()) {
1858bf80f4bSopenharmony_ci        auto pathFrom = NormalizePath(fromPath);
1868bf80f4bSopenharmony_ci        auto pathTo = NormalizePath(toPath);
1878bf80f4bSopenharmony_ci        for (auto&& destination : destinations_) {
1888bf80f4bSopenharmony_ci            if (fileManager_.Rename(destination + pathFrom, destination + pathTo)) {
1898bf80f4bSopenharmony_ci                return true;
1908bf80f4bSopenharmony_ci            }
1918bf80f4bSopenharmony_ci        }
1928bf80f4bSopenharmony_ci    }
1938bf80f4bSopenharmony_ci
1948bf80f4bSopenharmony_ci    return false;
1958bf80f4bSopenharmony_ci}
1968bf80f4bSopenharmony_ci
1978bf80f4bSopenharmony_civector<string> ProxyFilesystem::GetUriPaths(const string_view uri) const
1988bf80f4bSopenharmony_ci{
1998bf80f4bSopenharmony_ci    vector<string> paths;
2008bf80f4bSopenharmony_ci
2018bf80f4bSopenharmony_ci    auto path = NormalizePath(uri);
2028bf80f4bSopenharmony_ci    if (!path.empty()) {
2038bf80f4bSopenharmony_ci        for (auto&& destination : destinations_) {
2048bf80f4bSopenharmony_ci            auto directory = fileManager_.OpenDirectory(destination + path);
2058bf80f4bSopenharmony_ci            if (directory) {
2068bf80f4bSopenharmony_ci                paths.push_back(destination + path);
2078bf80f4bSopenharmony_ci            }
2088bf80f4bSopenharmony_ci        }
2098bf80f4bSopenharmony_ci    }
2108bf80f4bSopenharmony_ci
2118bf80f4bSopenharmony_ci    return paths;
2128bf80f4bSopenharmony_ci}
2138bf80f4bSopenharmony_ciCORE_END_NAMESPACE()
214