• 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 "raw_file_manager.h"
17 
18 #include <cstdio>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22 
23 #include "raw_dir.h"
24 #include "raw_file.h"
25 #include "resource_manager.h"
26 #include "resource_manager_addon.h"
27 #include "resource_manager_impl.h"
28 #include "hilog/log.h"
29 
30 #ifdef __WINNT__
31 #include <shlwapi.h>
32 #include <windows.h>
33 #else
34 #include <dlfcn.h>
35 #endif
36 
37 using namespace OHOS::Global::Resource;
38 using namespace OHOS::HiviewDFX;
39 
40 namespace {
41     constexpr HiLogLabel LABEL = {LOG_CORE, 0xD001E00, "RawFile"};
42 }
43 
44 struct NativeResourceManager {
45     std::shared_ptr<ResourceManager> resManager = nullptr;
46 };
47 
48 struct FileNameCache {
49     int maxCount = 0;
50     std::vector<std::string> names;
51 };
52 
53 struct RawDir {
54     std::shared_ptr<ResourceManager> resManager = nullptr;
55     struct FileNameCache fileNameCache;
56 };
57 
58 struct RawFile {
59     const std::string filePath;
60     long offset;
61     long length;
62     FILE* pf;
63 
RawFileRawFile64     explicit RawFile(const std::string &path) : filePath(path), offset(0L), length(0L), pf(nullptr) {}
65 
~RawFileRawFile66     ~RawFile()
67     {
68         if (pf != nullptr) {
69             fclose(pf);
70             pf = nullptr;
71         }
72     }
73 
openRawFile74     bool open()
75     {
76         pf = std::fopen(filePath.c_str(), "rb");
77         return pf != nullptr;
78     }
79 };
80 
OH_ResourceManager_InitNativeResourceManager(napi_env env,napi_value jsResMgr)81 NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr)
82 {
83     napi_valuetype valueType;
84     napi_typeof(env, jsResMgr, &valueType);
85     if (valueType != napi_object) {
86         HiLog::Error(LABEL, "jsResMgr is not an object");
87         return nullptr;
88     }
89     std::shared_ptr<ResourceManagerAddon> *addonPtr = nullptr;
90     napi_status status = napi_unwrap(env, jsResMgr, reinterpret_cast<void **>(&addonPtr));
91     if (status != napi_ok) {
92         HiLog::Error(LABEL, "Failed to get native resourcemanager");
93         return nullptr;
94     }
95     std::unique_ptr<NativeResourceManager> result = std::make_unique<NativeResourceManager>();
96     result->resManager = (*addonPtr)->GetResMgr();
97     return result.release();
98 }
99 
OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager * resMgr)100 void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr)
101 {
102     if (resMgr != nullptr) {
103         delete resMgr;
104     }
105 }
106 
OH_ResourceManager_OpenRawDir(const NativeResourceManager * mgr,const char * dirName)107 RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName)
108 {
109     if (mgr == nullptr || dirName == nullptr) {
110         return nullptr;
111     }
112     ResourceManagerImpl* impl = static_cast<ResourceManagerImpl *>(mgr->resManager.get());
113     std::string tempName = dirName;
114     const std::string rawFileDirName = "rawfile/";
115     if (tempName.length() < rawFileDirName.length()
116         || (tempName.compare(0, rawFileDirName.length(), rawFileDirName) != 0)) {
117         tempName = rawFileDirName + tempName;
118     }
119     std::unique_ptr<RawDir> result = std::make_unique<RawDir>();
120     std::vector<std::string> resourcesPaths = impl->GetResourcePaths();
121     for (auto iter = resourcesPaths.begin(); iter != resourcesPaths.end(); iter++) {
122         std::string currentPath = *iter + tempName;
123         DIR* dir = opendir(currentPath.c_str());
124         if (dir == nullptr) {
125             continue;
126         }
127         struct dirent *dirp = readdir(dir);
128         while (dirp != nullptr) {
129             if (std::strcmp(dirp->d_name, ".") == 0 ||
130                 std::strcmp(dirp->d_name, "..") == 0) {
131                 dirp = readdir(dir);
132                 continue;
133             }
134             if (dirp->d_type == DT_REG) {
135                 result->fileNameCache.names.push_back(tempName + "/" + dirp->d_name);
136             }
137 
138             dirp = readdir(dir);
139         }
140         closedir(dir);
141     }
142     return result.release();
143 }
144 
OH_ResourceManager_OpenRawFile(const NativeResourceManager * mgr,const char * fileName)145 RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName)
146 {
147     if (mgr == nullptr || fileName == nullptr) {
148         return nullptr;
149     }
150 
151     std::string filePath;
152     RState state = mgr->resManager->GetRawFilePathByName(fileName, filePath);
153     if (state != SUCCESS) {
154         return nullptr;
155     }
156     std::unique_ptr<RawFile> result = std::make_unique<RawFile>(filePath);
157     if (!result->open()) {
158         return nullptr;
159     }
160 
161     std::fseek(result->pf, 0, SEEK_END);
162     result->length = ftell(result->pf);
163     std::fseek(result->pf, 0, SEEK_SET);
164     return result.release();
165 }
166 
OH_ResourceManager_GetRawFileCount(RawDir * rawDir)167 int OH_ResourceManager_GetRawFileCount(RawDir *rawDir)
168 {
169     if (rawDir == nullptr) {
170         return 0;
171     }
172     return rawDir->fileNameCache.names.size();
173 }
174 
OH_ResourceManager_GetRawFileName(RawDir * rawDir,int index)175 const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index)
176 {
177     if (rawDir == nullptr || index < 0) {
178         return nullptr;
179     }
180     uint32_t rawFileCount = rawDir->fileNameCache.names.size();
181     if (rawFileCount == 0 || index >= static_cast<int>(rawFileCount)) {
182         return nullptr;
183     }
184     return rawDir->fileNameCache.names[index].c_str();
185 }
186 
OH_ResourceManager_CloseRawDir(RawDir * rawDir)187 void OH_ResourceManager_CloseRawDir(RawDir *rawDir)
188 {
189     if (rawDir != nullptr) {
190         delete rawDir;
191     }
192 }
193 
OH_ResourceManager_ReadRawFile(const RawFile * rawFile,void * buf,size_t length)194 int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length)
195 {
196     if (rawFile == nullptr || buf == nullptr || length == 0) {
197         return 0;
198     }
199     return std::fread(buf, 1, length, rawFile->pf);
200 }
201 
OH_ResourceManager_SeekRawFile(const RawFile * rawFile,long offset,int whence)202 int OH_ResourceManager_SeekRawFile(const RawFile *rawFile, long offset, int whence)
203 {
204     if (rawFile == nullptr) {
205         return 0;
206     }
207 
208     int origin = 0;
209     int start = 0;
210     switch (whence) {
211         case SEEK_SET:
212             origin = SEEK_SET;
213             start = rawFile->offset + offset;
214             break;
215         case SEEK_CUR:
216             origin = SEEK_CUR;
217             start = offset;
218             break;
219         case SEEK_END:
220             start = rawFile->offset + rawFile->length + offset;
221             origin = SEEK_SET;
222             break;
223         default:
224             return -1;
225     }
226 
227     return std::fseek(rawFile->pf, start, origin);
228 }
229 
OH_ResourceManager_GetRawFileSize(RawFile * rawFile)230 long OH_ResourceManager_GetRawFileSize(RawFile *rawFile)
231 {
232     if (rawFile == nullptr) {
233         return 0;
234     }
235 
236     return rawFile->length;
237 }
238 
OH_ResourceManager_CloseRawFile(RawFile * rawFile)239 void OH_ResourceManager_CloseRawFile(RawFile *rawFile)
240 {
241     if (rawFile != nullptr) {
242         delete rawFile;
243     }
244 }
245 
OH_ResourceManager_GetRawFileOffset(const RawFile * rawFile)246 long OH_ResourceManager_GetRawFileOffset(const RawFile *rawFile)
247 {
248     if (rawFile == nullptr) {
249         return 0;
250     }
251     return ftell(rawFile->pf) - rawFile->offset;
252 }
253 
OH_ResourceManager_GetRawFileDescriptor(const RawFile * rawFile,RawFileDescriptor & descriptor)254 bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor)
255 {
256     if (rawFile == nullptr) {
257         return false;
258     }
259     char paths[PATH_MAX] = {0};
260 #ifdef __WINNT__
261     if (!PathCanonicalizeA(paths, rawFile->filePath.c_str())) {
262         HiLog::Error(LABEL, "failed to PathCanonicalizeA the rawFile path");
263     }
264 #else
265     if (realpath(rawFile->filePath.c_str(), paths) == nullptr) {
266         HiLog::Error(LABEL, "failed to realpath the rawFile path");
267     }
268 #endif
269     int fd = open(paths, O_RDONLY);
270     if (fd > 0) {
271         descriptor.fd = fd;
272         descriptor.length = rawFile->length;
273         descriptor.start = rawFile->offset;
274     } else {
275         return false;
276     }
277     return true;
278 }
279 
OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor & descriptor)280 bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor)
281 {
282     if (descriptor.fd > 0) {
283         return close(descriptor.fd) == 0;
284     }
285     return true;
286 }
287