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