• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 <core/implementation_uids.h>
17 #include <core/io/intf_file_manager.h>
18 #include <core/io/intf_file_monitor.h>
19 #include <core/io/intf_filesystem_api.h>
20 #include <core/plugin/intf_class_factory.h>
21 
22 #include "dev/file_monitor.h"
23 #include "io/file_manager.h"
24 #include "io/memory_filesystem.h"
25 #include "io/path_tools.h"
26 #include "io/rofs_filesystem.h"
27 #include "io/std_filesystem.h"
28 #include "util/string_util.h"
29 
30 CORE_BEGIN_NAMESPACE();
31 namespace {
32 using BASE_NS::string;
33 using BASE_NS::string_view;
34 using BASE_NS::Uid;
35 using BASE_NS::vector;
36 
37 class FileMonitorImpl final : public IFileMonitor {
38 public:
39     const IInterface* GetInterface(const Uid& uid) const override;
40     IInterface* GetInterface(const Uid& uid) override;
41     void Ref() override;
42     void Unref() override;
43 
44     void Initialize(IFileManager&) override;
45     bool AddPath(const string_view path) override;
46     bool RemovePath(const string_view path) override;
47     void ScanModifications(vector<string>& added, vector<string>& removed, vector<string>& modified) override;
48 
49     FileMonitorImpl() = default;
FileMonitorImpl(IFileManager & manager)50     explicit FileMonitorImpl(IFileManager& manager)
51     {
52         Initialize(manager);
53     }
54     ~FileMonitorImpl();
55     FileMonitor* fileMonitor_ { nullptr };
56     uint32_t refCount_ { 0 };
57 };
58 
59 class FilesystemApi final : public IFileSystemApi {
60 public:
61     string basePath_;
62     IFilesystem::Ptr rootFs_;
FilesystemApi()63     FilesystemApi()
64     {
65         basePath_ = GetCurrentDirectory();
66         rootFs_ = CreateStdFileSystem();
67     }
68 
GetInterface(const Uid & uid) const69     const IInterface* GetInterface(const Uid& uid) const override
70     {
71         return const_cast<FilesystemApi*>(this)->GetInterface(uid);
72     }
GetInterface(const Uid & uid)73     IInterface* GetInterface(const Uid& uid) override
74     {
75         if ((uid == IInterface::UID) || (uid == IClassFactory::UID)) {
76             return this;
77         }
78         if (uid == IFileSystemApi::UID) {
79             return this;
80         }
81         return nullptr;
82     }
Ref()83     void Ref() override {}
Unref()84     void Unref() override {}
85 
CreateInstance(const Uid & uid)86     IInterface::Ptr CreateInstance(const Uid& uid) override
87     {
88         if (uid == UID_FILE_MONITOR) {
89             return IInterface::Ptr(new FileMonitorImpl());
90         }
91         if (uid == UID_FILE_MANAGER) {
92             return IInterface::Ptr(new FileManager());
93         }
94         return IInterface::Ptr();
95     }
96 
CreateFilemanager()97     IFileManager::Ptr CreateFilemanager() override
98     {
99         return IInterface::Ptr(new FileManager());
100     }
CreateFilemonitor(IFileManager & manager)101     IFileMonitor::Ptr CreateFilemonitor(IFileManager& manager) override
102     {
103         return IInterface::Ptr(new FileMonitorImpl(manager));
104     }
ResolvePath(string_view inPathRaw)105     string ResolvePath(string_view inPathRaw)
106     {
107 #if _WIN32
108         string_view cur_drive, cur_path, cur_filename, cur_ext;
109         SplitPath(basePath_, cur_drive, cur_path, cur_filename, cur_ext);
110 
111         if (inPathRaw.empty()) {
112             return {};
113         }
114         // fix slashes. (just change \\ to /)
115         string_view pathIn = inPathRaw;
116         string tmp;
117         if (pathIn.find("\\") != string_view::npos) {
118             tmp = pathIn;
119             StringUtil::FindAndReplaceAll(tmp, "\\", "/");
120             pathIn = tmp;
121         }
122 
123         string_view drive, path, filename, ext;
124         SplitPath(pathIn, drive, path, filename, ext);
125         string res = "/";
126         if (drive.empty()) {
127             // relative to current drive then
128             res += cur_drive;
129         } else {
130             res += drive;
131         }
132         res += ":";
133         string normalized_path;
134         if (path.empty()) {
135             return "";
136         } else {
137             if (path[0] != '/') {
138                 // relative path.
139                 normalized_path = NormalizePath(cur_path + path);
140             } else {
141                 normalized_path = NormalizePath(path);
142             }
143         }
144         if (normalized_path.empty()) {
145             return "";
146         }
147         return res + normalized_path;
148 #else
149         if (IsRelative(inPathRaw)) {
150             return NormalizePath(basePath_ + inPathRaw);
151         }
152         return NormalizePath(inPathRaw);
153 #endif
154     }
155 
CreateStdFileSystem()156     IFilesystem::Ptr CreateStdFileSystem() override
157     {
158         return IFilesystem::Ptr(new StdFilesystem("/"));
159     }
160 
CreateStdFileSystem(string_view rootPathIn)161     IFilesystem::Ptr CreateStdFileSystem(string_view rootPathIn) override
162     {
163         string_view protocol, path;
164         if (ParseUri(rootPathIn, protocol, path)) {
165             if (protocol != "file") {
166                 return {};
167             }
168             rootPathIn = path;
169         }
170         auto rootPath = ResolvePath(rootPathIn);
171         if (!rootPath.empty()) {
172             auto entry = rootFs_->GetEntry(rootPath);
173             if (entry.type == IDirectory::Entry::DIRECTORY) {
174                 return IFilesystem::Ptr(new StdFilesystem(rootPath));
175             }
176         }
177         return {};
178     }
CreateMemFileSystem()179     IFilesystem::Ptr CreateMemFileSystem() override
180     {
181         return IFilesystem::Ptr(new MemoryFilesystem());
182     }
CreateROFilesystem(const void * const data,uint64_t size)183     IFilesystem::Ptr CreateROFilesystem(const void* const data, uint64_t size) override
184     {
185         return IFilesystem::Ptr { new RoFileSystem(data, static_cast<size_t>(size)) };
186     }
187 };
188 } // namespace
189 
GetInterface(const Uid & uid) const190 const IInterface* FileMonitorImpl::GetInterface(const Uid& uid) const
191 {
192     if (uid == IFileMonitor::UID) {
193         return this;
194     }
195     return nullptr;
196 }
197 
GetInterface(const Uid & uid)198 IInterface* FileMonitorImpl::GetInterface(const Uid& uid)
199 {
200     if (uid == IFileMonitor::UID) {
201         return this;
202     }
203     return nullptr;
204 }
205 
Ref()206 void FileMonitorImpl::Ref()
207 {
208     refCount_++;
209 }
210 
Unref()211 void FileMonitorImpl::Unref()
212 {
213     if (--refCount_ == 0) {
214         delete this;
215     }
216 }
217 
~FileMonitorImpl()218 FileMonitorImpl::~FileMonitorImpl()
219 {
220     delete fileMonitor_;
221 }
222 
Initialize(IFileManager & manager)223 void FileMonitorImpl::Initialize(IFileManager& manager)
224 {
225     fileMonitor_ = new FileMonitor(manager);
226 }
227 
AddPath(const string_view path)228 bool FileMonitorImpl::AddPath(const string_view path)
229 {
230     if (fileMonitor_) {
231         return fileMonitor_->AddPath(path);
232     }
233     return false;
234 }
235 
RemovePath(const string_view path)236 bool FileMonitorImpl::RemovePath(const string_view path)
237 {
238     if (fileMonitor_) {
239         return fileMonitor_->RemovePath(path);
240     }
241     return false;
242 }
243 
ScanModifications(vector<string> & added,vector<string> & removed,vector<string> & modified)244 void FileMonitorImpl::ScanModifications(vector<string>& added, vector<string>& removed, vector<string>& modified)
245 {
246     added.clear();
247     removed.clear();
248     modified.clear();
249     if (fileMonitor_) {
250         fileMonitor_->ScanModifications(added, removed, modified);
251     }
252 }
253 
CreateFileMonitor(IClassFactory & registry,PluginToken token)254 IInterface* CreateFileMonitor(IClassFactory& registry, PluginToken token)
255 {
256     return new FileMonitorImpl();
257 }
GetFileApiFactory(IClassRegister & registry,PluginToken token)258 IInterface* GetFileApiFactory(IClassRegister& registry, PluginToken token)
259 {
260     static FilesystemApi fact;
261     return &fact;
262 }
263 CORE_END_NAMESPACE();