• 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 "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     std::lock_guard<std::mutex> lock(mutex_);
56 
57     for (const auto& basePath : assetBasePaths_) {
58         std::string fileName = packagePath_ + basePath + assetName;
59         char realPath[PATH_MAX] = { 0x00 };
60         if (!RealPath(fileName, realPath)) {
61             continue;
62         }
63         std::FILE* fp = std::fopen(realPath, "r");
64         if (fp == nullptr) {
65             continue;
66         }
67 
68         if (std::fseek(fp, 0, SEEK_END) != 0) {
69             LOGE("seek file tail error");
70             std::fclose(fp);
71             continue;
72         }
73 
74         int64_t size = std::ftell(fp);
75         if (size == -1L || size == 0L || size > FOO_MAX_LEN) {
76             LOGE("ftell file error");
77             std::fclose(fp);
78             continue;
79         }
80 
81         uint8_t* dataArray = new (std::nothrow) uint8_t[size];
82         if (dataArray == nullptr) {
83             LOGE("new uint8_t array failed");
84             std::fclose(fp);
85             continue;
86         }
87 
88         rewind(fp);
89         std::unique_ptr<uint8_t[]> data(dataArray);
90         size_t result = std::fread(data.get(), 1, size, fp);
91         if (result != (size_t)size) {
92             LOGE("read file failed");
93             std::fclose(fp);
94             continue;
95         }
96 
97         std::fclose(fp);
98         return std::make_unique<FileAssetImplMapping>(std::move(data), size);
99     }
100     return nullptr;
101 }
102 
GetAssetPath(const std::string & assetName,bool)103 std::string FileAssetProviderImpl::GetAssetPath(const std::string& assetName, bool /* isAddHapPath */)
104 {
105     std::lock_guard<std::mutex> lock(mutex_);
106     for (const auto& basePath : assetBasePaths_) {
107         std::string assetBasePath = packagePath_ + basePath;
108         std::string fileName = assetBasePath + assetName;
109         char realPath[PATH_MAX] = { 0x00 };
110         if (!RealPath(fileName, realPath)) {
111             continue;
112         }
113         std::FILE* fp = std::fopen(realPath, "r");
114         if (fp == nullptr) {
115             continue;
116         }
117         std::fclose(fp);
118         return assetBasePath;
119     }
120     LOGE("Cannot find base path of %{public}s", assetName.c_str());
121     return "";
122 }
123 
GetAssetList(const std::string & path,std::vector<std::string> & assetList)124 void FileAssetProviderImpl::GetAssetList(const std::string& path, std::vector<std::string>& assetList)
125 {
126     std::lock_guard<std::mutex> lock(mutex_);
127     for (const auto& basePath : assetBasePaths_) {
128         std::string assetPath = packagePath_ + basePath + path;
129         std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(assetPath.c_str()), closedir);
130         if (dir == nullptr) {
131             continue;
132         }
133         struct dirent* dptr = nullptr;
134         while ((dptr = readdir(dir.get())) != nullptr) {
135             if (strcmp(dptr->d_name, ".") != 0 && strcmp(dptr->d_name, "..") != 0) {
136                 assetList.push_back(dptr->d_name);
137             }
138         }
139     }
140 }
141 } // namespace OHOS::Ace
142