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