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 "file_mapper.h"
17 #include <memory>
18 #include <sys/mman.h>
19
20 #include "ability_base_log_wrapper.h"
21 #include "zip_file_reader.h"
22
23 namespace OHOS {
24 namespace AbilityBase {
25 namespace {
26 long g_pageSize = 0;
27 const int32_t MAP_XPM = 0x40;
28 }
FileMapper()29 FileMapper::FileMapper()
30 {
31 if (g_pageSize <= 0) {
32 g_pageSize = sysconf(_SC_PAGESIZE);
33 }
34 }
35
~FileMapper()36 FileMapper::~FileMapper()
37 {
38 if (basePtr_ != nullptr && type_ == FileMapperType::SHARED_MMAP) {
39 munmap(basePtr_, baseLen_);
40 }
41 }
42
CreateFileMapper(const std::string & fileName,bool compress,int32_t fd,size_t offset,size_t len,FileMapperType type)43 bool FileMapper::CreateFileMapper(const std::string &fileName, bool compress,
44 int32_t fd, size_t offset, size_t len, FileMapperType type)
45 {
46 if (fd < 0 || len == 0 || type == FileMapperType::NORMAL_MEM) {
47 ABILITYBASE_LOGE("Invalid param fileName: %{public}s", fileName.c_str());
48 return false;
49 }
50 if (g_pageSize <= 0) {
51 ABILITYBASE_LOGE("Wrong Pagesize: %{public}ld", g_pageSize);
52 return false;
53 }
54 if (dataLen_ > 0) {
55 ABILITYBASE_LOGE("data not empty fileName: %{public}s", fileName_.c_str());
56 return false;
57 }
58
59 size_t adjust = offset % static_cast<size_t>(g_pageSize);
60 size_t adjOffset = offset - adjust;
61 baseLen_ = len + adjust;
62 int32_t mmapFlag = MAP_PRIVATE | MAP_XPM;
63 if (type == FileMapperType::SHARED_MMAP) {
64 mmapFlag = MAP_SHARED;
65 }
66 basePtr_ = (uint8_t*)mmap(nullptr, baseLen_, PROT_READ,
67 mmapFlag, fd, adjOffset);
68 if (basePtr_ == MAP_FAILED) {
69 ABILITYBASE_LOGE("mmap failed, errno[%{public}d]. fileName: %{public}s, "
70 "offset: %{public}zu, pageSize: %{public}ld, mmapFlag: %{public}d",
71 errno, fileName.c_str(), offset, g_pageSize, mmapFlag);
72 baseLen_ = 0;
73 return false;
74 }
75
76 isCompressed = compress;
77 fileName_ = fileName;
78 offset_ = offset;
79 dataLen_ = len;
80 usePtr_ = reinterpret_cast<uint8_t *>(basePtr_) + adjust;
81 type_ = type;
82 return true;
83 }
84
CreateFileMapper(std::shared_ptr<ZipFileReader> fileReader,const std::string & fileName,size_t offset,size_t len,bool compress)85 bool FileMapper::CreateFileMapper(std::shared_ptr<ZipFileReader> fileReader, const std::string &fileName,
86 size_t offset, size_t len, bool compress)
87 {
88 if (!fileReader) {
89 ABILITYBASE_LOGE("file null fileName: %{public}s", fileName.c_str());
90 return false;
91 }
92 if (!fileName_.empty()) {
93 ABILITYBASE_LOGE("data not empty fileName: %{public}s", fileName_.c_str());
94 return false;
95 }
96
97 dataPtr_ = std::make_unique<uint8_t[]>(len);
98 if (!fileReader->ReadBuffer(dataPtr_.get(), offset, len)) {
99 ABILITYBASE_LOGE("read failed, len[%{public}zu]. fileName: %{public}s, "
100 "offset: %{public}zu", len, fileName.c_str(), offset);
101 dataPtr_.reset();
102 return false;
103 }
104 isCompressed = compress;
105 dataLen_ = len;
106 offset_ = offset;
107 fileName_ = fileName;
108
109 return true;
110 }
111
IsCompressed()112 bool FileMapper::IsCompressed()
113 {
114 return isCompressed;
115 }
116
GetDataPtr()117 uint8_t* FileMapper::GetDataPtr()
118 {
119 return dataPtr_ ? dataPtr_.get() : usePtr_;
120 }
121
GetDataLen()122 size_t FileMapper::GetDataLen()
123 {
124 return dataLen_;
125 }
126
GetFileName()127 std::string FileMapper::GetFileName()
128 {
129 return fileName_;
130 }
131
GetOffset()132 int32_t FileMapper::GetOffset()
133 {
134 return offset_;
135 }
136 } // namespace AbilityBase
137 } // namespace OHOS
138