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 "adapter/ohos/entrance/file_asset_provider_impl.h"
17
18 #include <cstring>
19 #include <dirent.h>
20 #include <limits>
21 #include <mutex>
22 #include <sys/types.h>
23 #include "base/log/ace_trace.h"
24 #include "base/log/log.h"
25 #include "base/utils/utils.h"
26
27 namespace OHOS::Ace {
28 constexpr int64_t FOO_MAX_LEN = 20 * 1024 * 1024;
Initialize(const std::string & packagePath,const std::vector<std::string> & assetBasePaths)29 bool FileAssetProviderImpl::Initialize(const std::string& packagePath, const std::vector<std::string>& assetBasePaths)
30 {
31 ACE_SCOPED_TRACE("Initialize");
32 if (assetBasePaths.empty()) {
33 LOGE("the assetBasePath is empty");
34 return false;
35 }
36
37 if (!packagePath.empty() && packagePath.back() != '/') {
38 packagePath_ = packagePath + "/";
39 } else {
40 packagePath_ = packagePath;
41 }
42
43 assetBasePaths_ = assetBasePaths;
44 return true;
45 }
46
IsValid() const47 bool FileAssetProviderImpl::IsValid() const
48 {
49 return true;
50 }
51
GetAsMapping(const std::string & assetName) const52 std::unique_ptr<AssetMapping> FileAssetProviderImpl::GetAsMapping(const std::string& assetName) const
53 {
54 ACE_SCOPED_TRACE("GetAsMapping");
55 LOGD("assert name is: %{public}s", assetName.c_str());
56 std::lock_guard<std::mutex> lock(mutex_);
57
58 for (const auto& basePath : assetBasePaths_) {
59 std::string fileName = packagePath_ + basePath + assetName;
60 char realPath[PATH_MAX] = { 0x00 };
61 if (!RealPath(fileName, realPath)) {
62 continue;
63 }
64 std::FILE* fp = std::fopen(realPath, "r");
65 if (fp == nullptr) {
66 continue;
67 }
68
69 if (std::fseek(fp, 0, SEEK_END) != 0) {
70 LOGE("seek file tail error");
71 std::fclose(fp);
72 continue;
73 }
74
75 int64_t size = std::ftell(fp);
76 if (size == -1L || size == 0L || size > FOO_MAX_LEN) {
77 LOGE("ftell file error");
78 std::fclose(fp);
79 continue;
80 }
81
82 uint8_t* dataArray = new (std::nothrow) uint8_t[size];
83 if (dataArray == nullptr) {
84 LOGE("new uint8_t array failed");
85 std::fclose(fp);
86 continue;
87 }
88
89 rewind(fp);
90 std::unique_ptr<uint8_t[]> data(dataArray);
91 size_t result = std::fread(data.get(), 1, size, fp);
92 if (result != (size_t)size) {
93 LOGE("read file failed");
94 std::fclose(fp);
95 continue;
96 }
97
98 std::fclose(fp);
99 return std::make_unique<FileAssetImplMapping>(std::move(data), size);
100 }
101 return nullptr;
102 }
103
GetAssetPath(const std::string & assetName,bool)104 std::string FileAssetProviderImpl::GetAssetPath(const std::string& assetName, bool /* isAddHapPath */)
105 {
106 std::lock_guard<std::mutex> lock(mutex_);
107 for (const auto& basePath : assetBasePaths_) {
108 std::string assetBasePath = packagePath_ + basePath;
109 std::string fileName = assetBasePath + assetName;
110 char realPath[PATH_MAX] = { 0x00 };
111 if (!RealPath(fileName, realPath)) {
112 continue;
113 }
114 std::FILE* fp = std::fopen(realPath, "r");
115 if (fp == nullptr) {
116 continue;
117 }
118 std::fclose(fp);
119 return assetBasePath;
120 }
121 LOGE("Cannot find base path of %{public}s", assetName.c_str());
122 return "";
123 }
124
GetAssetList(const std::string & path,std::vector<std::string> & assetList)125 void FileAssetProviderImpl::GetAssetList(const std::string& path, std::vector<std::string>& assetList)
126 {
127 std::lock_guard<std::mutex> lock(mutex_);
128 for (const auto& basePath : assetBasePaths_) {
129 std::string assetPath = packagePath_ + basePath + path;
130 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(assetPath.c_str()), closedir);
131 if (dir == nullptr) {
132 continue;
133 }
134 struct dirent* dptr = nullptr;
135 while ((dptr = readdir(dir.get())) != nullptr) {
136 if (strcmp(dptr->d_name, ".") != 0 && strcmp(dptr->d_name, "..") != 0) {
137 assetList.push_back(dptr->d_name);
138 }
139 }
140 }
141 }
142 } // namespace OHOS::Ace
143