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