• 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 "ohos_file.h"
17 
18 #include <cstdint>
19 
20 #include <cerrno>
21 #include <dirent.h>
22 
23 #ifndef _DIRENT_HAVE_D_TYPE
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 
27 #endif
28 #include <climits>
29 #define CORE_MAX_PATH PATH_MAX
30 
31 #include <base/containers/string.h>
32 #include <base/containers/string_view.h>
33 #include <core/io/intf_file.h>
34 #include <core/log.h>
35 #include <core/namespace.h>
36 
37 #include "io/std_directory.h"
38 
39 CORE_BEGIN_NAMESPACE()
40 using BASE_NS::CloneData;
41 using BASE_NS::string;
42 using BASE_NS::string_view;
43 
44 const std::regex MEDIA_RES_ID_REGEX(R"(^\w+/([0-9]+)\.\w+$)", std::regex::icase);
45 const std::regex MEDIA_HAP_RES_PATH_REGEX(R"(^(.*)$)");
46 const std::regex MEDIA_HAP_RES_ID_REGEX(R"(^.*/([0-9]+)\.\w+$)", std::regex::icase);
47 const std::regex MEDIA_RES_NAME_REGEX(R"(^.*/(\w+)\.\w+$)", std::regex::icase);
48 
49 constexpr uint32_t OHOS_RESOURCE_MATCH_SIZE = 2;
50 
UpdateResManager(const PlatformHapInfo & hapInfo)51 void OhosResMgr::UpdateResManager(const PlatformHapInfo& hapInfo)
52 {
53     auto key = hapInfo.bundleName + "+" + hapInfo.moduleName;
54     auto resourceMgrIter = resourceManagers_.find(key);
55     if (resourceMgrIter != resourceManagers_.end()) {
56         resourceManager_ = resourceMgrIter->second;
57         return;
58     }
59 
60     if (hapInfo.resourceManager != nullptr) {
61         resourceManagers_[key] = hapInfo.resourceManager;
62         resourceManager_ = hapInfo.resourceManager;
63         CORE_LOG_D("resource manager has ready by new api");
64         return;
65     }
66 
67     std::shared_ptr<OHOS::Global::Resource::ResourceManager>
68         newResMgr(OHOS::Global::Resource::CreateResourceManager());
69     auto resRet = newResMgr->AddResource(hapInfo.hapPath.c_str());
70     resourceManagers_[key] = newResMgr;
71     resourceManager_ = newResMgr;
72 }
73 
GetResMgr() const74 std::shared_ptr<OHOS::Global::Resource::ResourceManager> OhosResMgr::GetResMgr() const
75 {
76     return resourceManager_;
77 }
78 
OhosFileDirectory(BASE_NS::refcnt_ptr<OhosResMgr> resMgr)79 OhosFileDirectory::OhosFileDirectory(BASE_NS::refcnt_ptr<OhosResMgr> resMgr) : dirResMgr_(resMgr) {}
80 
~OhosFileDirectory()81 OhosFileDirectory::~OhosFileDirectory()
82 {
83     Close();
84 }
85 
Close()86 void OhosFileDirectory::Close()
87 {
88     if (dir_) {
89         dir_.reset();
90     }
91 }
92 
IsDir(BASE_NS::string_view path,std::vector<std::string> & fileList) const93 bool OhosFileDirectory::IsDir(BASE_NS::string_view path, std::vector<std::string>& fileList) const
94 {
95     auto state = dirResMgr_->GetResMgr()->GetRawFileList(path.data(), fileList);
96     if (state != OHOS::Global::Resource::SUCCESS || fileList.empty()) {
97         CORE_LOG_E("GetRawfilepath error, filename:%s, error:%u", path.data(), state);
98         return false;
99     }
100     return true;
101 }
102 
IsFile(BASE_NS::string_view path) const103 bool OhosFileDirectory::IsFile(BASE_NS::string_view path) const
104 {
105     std::unique_ptr<uint8_t[]> data;
106     size_t dataLen = 0;
107     auto state = dirResMgr_->GetResMgr()->GetRawFileFromHap(path.data(), dataLen, data);
108     if (state != OHOS::Global::Resource::SUCCESS) {
109         return false;
110     }
111     return true;
112 }
113 
Open(const BASE_NS::string_view pathIn)114 bool OhosFileDirectory::Open(const BASE_NS::string_view pathIn)
115 {
116     auto path = pathIn;
117     if (path.back() == '/') {
118         path.remove_suffix(1);
119     }
120     if (path.front() == '/') {
121         path.remove_prefix(1);
122     }
123     std::vector<std::string> fileList;
124     if (IsDir(path, fileList)) {
125         dir_ = BASE_NS::make_unique<OhosDirImpl>(path, fileList);
126         return true;
127     }
128     return false;
129 }
130 
GetEntries() const131 BASE_NS::vector<IDirectory::Entry> OhosFileDirectory::GetEntries() const
132 {
133     CORE_ASSERT_MSG(dir_, "Dir not open");
134     BASE_NS::vector<IDirectory::Entry> result;
135     if (dir_) {
136         for (int i = 0; i < static_cast<int>(dir_->fileList_.size()); i++) {
137             auto path = dir_->path_ + "/" + BASE_NS::string(dir_->fileList_[i].c_str());
138             auto entry = GetEntry(path);
139             entry.timestamp = static_cast<uint32_t>(i);
140             entry.name = dir_->fileList_[i].c_str();
141             result.emplace_back(entry);
142         }
143     }
144     return result;
145 }
146 
GetEntry(BASE_NS::string_view uriIn) const147 IDirectory::Entry OhosFileDirectory::GetEntry(BASE_NS::string_view uriIn) const
148 {
149     if (!uriIn.empty()) {
150         IDirectory::Entry::Type type;
151         std::vector<std::string> fileList;
152         if (IsFile(uriIn)) {
153             type = IDirectory::Entry::FILE;
154         } else if (IsDir(uriIn, fileList)) {
155             type = IDirectory::Entry::DIRECTORY;
156         } else {
157             type = IDirectory::Entry::UNKNOWN;
158         }
159         // timestamp set 0
160         uint64_t timestamp = 0;
161         BASE_NS::string entryName { uriIn };
162         return IDirectory::Entry { type, entryName, timestamp };
163     }
164     return {};
165 }
166 
OhosFile(BASE_NS::refcnt_ptr<OhosResMgr> resMgr)167 OhosFile::OhosFile(BASE_NS::refcnt_ptr<OhosResMgr> resMgr) : fileResMgr_(resMgr)
168 {
169     buffer_ = std::make_shared<OhosFileStorage>(nullptr);
170 }
171 
UpdateStorage(std::shared_ptr<OhosFileStorage> buffer)172 void OhosFile::UpdateStorage(std::shared_ptr<OhosFileStorage> buffer)
173 {
174     buffer_ = BASE_NS::move(buffer);
175 }
176 
GetMode() const177 IFile::Mode OhosFile::GetMode() const
178 {
179     return IFile::Mode::READ_ONLY;
180 }
181 
Close()182 void OhosFile::Close() {}
183 
Read(void * buffer,uint64_t count)184 uint64_t OhosFile::Read(void* buffer, uint64_t count)
185 {
186     uint64_t toRead = count;
187     uint64_t sum = index_ + toRead;
188     if (sum < index_) {
189         return 0;
190     }
191     if (sum > buffer_->Size()) {
192         toRead = buffer_->Size() - index_;
193     }
194     if (toRead <= 0) {
195         return toRead;
196     }
197     if (toRead > SIZE_MAX) {
198         CORE_ASSERT_MSG(false, "Unable to read chunks bigger than (SIZE_MAX) bytes.");
199         return 0;
200     }
201     if (CloneData(buffer, static_cast<size_t>(count), &(buffer_->GetStorage()[index_]), static_cast<size_t>(toRead))) {
202         index_ += toRead;
203     }
204     return toRead;
205 }
206 
Write(const void * buffer,uint64_t count)207 uint64_t OhosFile::Write(const void* buffer, uint64_t count)
208 {
209     return 0;
210 }
211 
Append(const void * buffer,uint64_t count,uint64_t flushSize)212 uint64_t OhosFile::Append(const void* buffer, uint64_t count, uint64_t flushSize)
213 {
214     return 0;
215 }
216 
GetLength() const217 uint64_t OhosFile::GetLength() const
218 {
219     return buffer_->Size();
220 }
221 
Seek(uint64_t aOffset)222 bool OhosFile::Seek(uint64_t aOffset)
223 {
224     if (aOffset < buffer_->Size()) {
225         index_ = aOffset;
226         return true;
227     }
228     return false;
229 }
230 
GetPosition() const231 uint64_t OhosFile::GetPosition() const
232 {
233     return index_;
234 }
235 
Open(BASE_NS::string_view rawFile)236 std::shared_ptr<OhosFileStorage> OhosFile::Open(BASE_NS::string_view rawFile)
237 {
238     std::unique_ptr<uint8_t[]> data;
239     size_t dataLen = 0;
240     if (OpenRawFile(rawFile, dataLen, data)) {
241         buffer_->SetBuffer(std::move(data), static_cast<uint64_t>(dataLen));
242         return buffer_;
243     }
244     return nullptr;
245 }
246 
247 // Parsing URI
GetResourceId(const std::string & uri,uint32_t & resId) const248 bool OhosFile::GetResourceId(const std::string& uri, uint32_t& resId) const
249 {
250     std::smatch matches;
251     if (std::regex_match(uri, matches, MEDIA_RES_ID_REGEX) && matches.size() == OHOS_RESOURCE_MATCH_SIZE) {
252         resId = static_cast<uint32_t>(std::stoul(matches[1].str()));
253         return true;
254     }
255     std::smatch hapMatches;
256     if (std::regex_match(uri, hapMatches, MEDIA_HAP_RES_ID_REGEX) && hapMatches.size() == OHOS_RESOURCE_MATCH_SIZE) {
257         resId = static_cast<uint32_t>(std::stoul(hapMatches[1].str()));
258         return true;
259     }
260     return false;
261 }
262 
GetResourceId(const std::string & uri,std::string & path) const263 bool OhosFile::GetResourceId(const std::string& uri, std::string& path) const
264 {
265     std::smatch matches;
266     if (std::regex_match(uri, matches, MEDIA_HAP_RES_PATH_REGEX) && matches.size() == OHOS_RESOURCE_MATCH_SIZE) {
267         path = matches[1].str();
268         return true;
269     }
270     return false;
271 }
272 
GetResourceName(const std::string & uri,std::string & resName) const273 bool OhosFile::GetResourceName(const std::string& uri, std::string& resName) const
274 {
275     std::smatch matches;
276     if (std::regex_match(uri, matches, MEDIA_RES_NAME_REGEX) && matches.size() == OHOS_RESOURCE_MATCH_SIZE) {
277         resName = matches[1].str();
278         return true;
279     }
280     return false;
281 }
282 
OpenRawFile(BASE_NS::string_view uriIn,size_t & dataLen,std::unique_ptr<uint8_t[]> & dest)283 bool OhosFile::OpenRawFile(BASE_NS::string_view uriIn, size_t& dataLen, std::unique_ptr<uint8_t[]>& dest)
284 {
285     std::string uri(uriIn.data());
286     std::string rawFile;
287     if (GetResourceId(uri, rawFile)) {
288         auto state = fileResMgr_->GetResMgr()->GetRawFileFromHap(rawFile.c_str(), dataLen, dest);
289         if (state != OHOS::Global::Resource::SUCCESS || !dest) {
290             CORE_LOG_E("GetRawFileFromHap error, raw filename:%s, error:%u", rawFile.c_str(), state);
291             return false;
292         }
293         return true;
294     }
295     uint32_t resId = 0;
296     if (GetResourceId(uri, resId)) {
297         auto state = fileResMgr_->GetResMgr()->GetMediaDataById(resId, dataLen, dest);
298         if (state != OHOS::Global::Resource::SUCCESS || !dest) {
299             CORE_LOG_E("GetMediaDataById error, resId:%u, error:%u", resId, state);
300             return false;
301         }
302         return true;
303     }
304     std::string resName;
305     if (GetResourceName(uri, resName)) {
306         auto state = fileResMgr_->GetResMgr()->GetMediaDataByName(resName.c_str(), dataLen, dest);
307         if (state != OHOS::Global::Resource::SUCCESS || !dest) {
308             CORE_LOG_E("GetMediaDataByName error, resName:%s, error:%u", resName.c_str(), state);
309             return false;
310         }
311         return true;
312     }
313     CORE_LOG_E("load image data failed, as uri is invalid:%s", uri.c_str());
314     return false;
315 }
316 CORE_END_NAMESPACE()
317