• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #include "proxy_filesystem.h"
17 
18 #include <algorithm>
19 #include <cstring>
20 
21 #include <base/containers/iterator.h>
22 #include <base/containers/string.h>
23 #include <base/containers/string_view.h>
24 #include <base/containers/type_traits.h>
25 #include <base/containers/unique_ptr.h>
26 #include <base/containers/vector.h>
27 #include <base/namespace.h>
28 #include <core/io/intf_directory.h>
29 #include <core/io/intf_file.h>
30 #include <core/namespace.h>
31 
32 #include "file_manager.h"
33 #include "path_tools.h"
34 #include "proxy_directory.h"
35 
36 CORE_BEGIN_NAMESPACE()
37 using BASE_NS::move;
38 using BASE_NS::string;
39 using BASE_NS::string_view;
40 using BASE_NS::vector;
41 
ProxyFilesystem(FileManager & fileManager,const string_view destination)42 ProxyFilesystem::ProxyFilesystem(FileManager& fileManager, const string_view destination)
43     : fileManager_(fileManager), destinations_()
44 {
45     AppendSearchPath(destination);
46 }
47 
AppendSearchPath(string_view path)48 void ProxyFilesystem::AppendSearchPath(string_view path)
49 {
50     if (path.empty()) {
51         return;
52     }
53     if (path.back() == '/') {
54         path.remove_suffix(1);
55     }
56     destinations_.emplace_back(path);
57 }
58 
PrependSearchPath(string_view path)59 void ProxyFilesystem::PrependSearchPath(string_view path)
60 {
61     if (path.empty()) {
62         return;
63     }
64     if (path.back() == '/') {
65         path.remove_suffix(1);
66     }
67     destinations_.emplace(destinations_.begin(), path);
68 }
69 
RemoveSearchPath(string_view destination)70 void ProxyFilesystem::RemoveSearchPath(string_view destination)
71 {
72     if (destination.empty()) {
73         return;
74     }
75     if (destination.back() == '/') {
76         destination.remove_suffix(1);
77     }
78     const auto it = std::find(destinations_.cbegin(), destinations_.cend(), destination);
79     if (it != destinations_.cend()) {
80         destinations_.erase(it);
81     }
82 }
83 
GetEntry(const string_view path)84 IDirectory::Entry ProxyFilesystem::GetEntry(const string_view path)
85 {
86     auto normalizedPath = NormalizePath(path);
87     if (!normalizedPath.empty()) {
88         for (auto&& destination : destinations_) {
89             auto file = fileManager_.GetEntry(destination + normalizedPath);
90             if (file.type != IDirectory::Entry::UNKNOWN) {
91                 return file;
92             }
93         }
94     }
95     return {};
96 }
97 
OpenFile(const string_view path,const IFile::Mode mode)98 IFile::Ptr ProxyFilesystem::OpenFile(const string_view path, const IFile::Mode mode)
99 {
100     auto normalizedPath = NormalizePath(path);
101     if (!normalizedPath.empty()) {
102         for (auto&& destination : destinations_) {
103             auto file = fileManager_.OpenFile(destination + normalizedPath, mode);
104             if (file) {
105                 return file;
106             }
107         }
108     }
109 
110     return {};
111 }
112 
CreateFile(const string_view path)113 IFile::Ptr ProxyFilesystem::CreateFile(const string_view path)
114 {
115     auto normalizedPath = NormalizePath(path);
116     if (!normalizedPath.empty()) {
117         for (auto&& destination : destinations_) {
118             auto file = fileManager_.CreateFile(destination + normalizedPath);
119             if (file) {
120                 return file;
121             }
122         }
123     }
124 
125     return {};
126 }
127 
DeleteFile(const string_view path)128 bool ProxyFilesystem::DeleteFile(const string_view path)
129 {
130     auto normalizedPath = NormalizePath(path);
131     if (!normalizedPath.empty()) {
132         for (auto&& destination : destinations_) {
133             if (fileManager_.DeleteFile(destination + normalizedPath)) {
134                 return true;
135             }
136         }
137     }
138 
139     return false;
140 }
141 
FileExists(const string_view path) const142 bool ProxyFilesystem::FileExists(const string_view path) const
143 {
144     auto normalizedPath = NormalizePath(path);
145     if (!normalizedPath.empty()) {
146         for (auto&& destination : destinations_) {
147             if (fileManager_.FileExists(destination + normalizedPath)) {
148                 return true;
149             }
150         }
151     }
152 
153     return false;
154 }
155 
OpenDirectory(const string_view path)156 IDirectory::Ptr ProxyFilesystem::OpenDirectory(const string_view path)
157 {
158     IDirectory::Ptr proxyDirectory;
159     vector<IDirectory::Ptr> directories;
160     auto normalizedPath = NormalizePath(path);
161     if (!normalizedPath.empty()) {
162         for (auto&& destination : destinations_) {
163             auto directory = fileManager_.OpenDirectory(destination + normalizedPath);
164             if (directory) {
165                 directories.push_back(move(directory));
166             }
167         }
168     }
169 
170     if (!directories.empty()) {
171         proxyDirectory.reset(new ProxyDirectory(move(directories)));
172     }
173 
174     return proxyDirectory;
175 }
176 
CreateDirectory(const string_view path)177 IDirectory::Ptr ProxyFilesystem::CreateDirectory(const string_view path)
178 {
179     auto normalizedPath = NormalizePath(path);
180     if (!normalizedPath.empty()) {
181         for (auto&& destination : destinations_) {
182             auto directory = fileManager_.CreateDirectory(destination + normalizedPath);
183             if (directory) {
184                 return directory;
185             }
186         }
187     }
188 
189     return {};
190 }
191 
DeleteDirectory(const string_view path)192 bool ProxyFilesystem::DeleteDirectory(const string_view path)
193 {
194     auto normalizedPath = NormalizePath(path);
195     if (!normalizedPath.empty()) {
196         for (auto&& destination : destinations_) {
197             if (fileManager_.DeleteDirectory(destination + normalizedPath)) {
198                 return true;
199             }
200         }
201     }
202 
203     return false;
204 }
205 
DirectoryExists(const string_view path) const206 bool ProxyFilesystem::DirectoryExists(const string_view path) const
207 {
208     auto normalizedPath = NormalizePath(path);
209     if (!normalizedPath.empty()) {
210         for (auto&& destination : destinations_) {
211             if (fileManager_.DirectoryExists(destination + normalizedPath)) {
212                 return true;
213             }
214         }
215     }
216 
217     return false;
218 }
219 
Rename(const string_view fromPath,const string_view toPath)220 bool ProxyFilesystem::Rename(const string_view fromPath, const string_view toPath)
221 {
222     if (!fromPath.empty() && !toPath.empty()) {
223         auto pathFrom = NormalizePath(fromPath);
224         auto pathTo = NormalizePath(toPath);
225         for (auto&& destination : destinations_) {
226             if (fileManager_.Rename(destination + pathFrom, destination + pathTo)) {
227                 return true;
228             }
229         }
230     }
231 
232     return false;
233 }
234 
GetUriPaths(const string_view uri) const235 vector<string> ProxyFilesystem::GetUriPaths(const string_view uri) const
236 {
237     vector<string> paths;
238 
239     auto path = NormalizePath(uri);
240     if (!path.empty()) {
241         for (auto&& destination : destinations_) {
242             auto directory = fileManager_.OpenDirectory(destination + path);
243             if (directory) {
244                 paths.push_back(destination + path);
245             }
246         }
247     }
248 
249     return paths;
250 }
251 CORE_END_NAMESPACE()
252