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