• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "recording/mem_allocator.h"
17 
18 #include "securec.h"
19 #include "utils/log.h"
20 
21 namespace OHOS {
22 namespace Rosen {
23 namespace Drawing {
24 namespace {
25 constexpr size_t LARGE_MALLOC = 200000000;
26 }
27 static constexpr size_t MEM_SIZE_MAX = SIZE_MAX;
28 
MemAllocator()29 MemAllocator::MemAllocator() : isReadOnly_(false), capacity_(0), size_(0), startPtr_(nullptr) {}
30 
~MemAllocator()31 MemAllocator::~MemAllocator()
32 {
33     Clear();
34 }
35 
BuildFromData(const void * data,size_t size)36 bool MemAllocator::BuildFromData(const void* data, size_t size)
37 {
38     if (!data || size == 0 || size > MEM_SIZE_MAX) {
39         return false;
40     }
41 
42     Clear();
43     isReadOnly_ = true;
44     startPtr_ = const_cast<char*>(static_cast<const char*>(data));
45     capacity_ = size;
46     size_ = size;
47 
48     return true;
49 }
50 
BuildFromDataWithCopy(const void * data,size_t size)51 bool MemAllocator::BuildFromDataWithCopy(const void* data, size_t size)
52 {
53     if (!data || size == 0 || size > MEM_SIZE_MAX) {
54         return false;
55     }
56 
57     Clear();
58     isReadOnly_ = false;
59     Add(data, size);
60 
61     return true;
62 }
63 
Clear()64 void MemAllocator::Clear()
65 {
66     if (!isReadOnly_ && startPtr_) {
67         delete[] startPtr_;
68     }
69     isReadOnly_ = true;
70     startPtr_ = nullptr;
71     capacity_ = 0;
72     size_ = 0;
73 }
74 
ClearData()75 void MemAllocator::ClearData()
76 {
77     if (!isReadOnly_ && startPtr_) {
78         delete[] startPtr_;
79     }
80     startPtr_ = nullptr;
81     capacity_ = 0;
82     size_ = 0;
83 }
84 
Resize(size_t size)85 bool MemAllocator::Resize(size_t size)
86 {
87     if (isReadOnly_ || size == 0 || size > MEM_SIZE_MAX || size < size_) {
88         return false;
89     }
90     if (size > LARGE_MALLOC) {
91         LOGW("MemAllocator::Resize this time malloc large memory, size:%{public}zu", size);
92     }
93     char* newData = new char[size];
94     if (!newData) {
95         return false;
96     }
97 
98     if (startPtr_) {
99         if (!memcpy_s(newData, size, startPtr_, size_)) {
100             delete[] startPtr_;
101         } else {
102             delete[] newData;
103             return false;
104         }
105     }
106     startPtr_ = newData;
107     capacity_ = size;
108     return true;
109 }
110 
Add(const void * data,size_t size)111 void* MemAllocator::Add(const void* data, size_t size)
112 {
113     if (isReadOnly_ || !data || size == 0 || size > MEM_SIZE_MAX) {
114         return nullptr;
115     }
116 
117     if (capacity_ == 0 || capacity_ - size_ < size) {
118         // The capacity is not enough, expand the capacity
119         if (Resize((capacity_ + size) * MEMORY_EXPANSION_FACTOR) == false) {
120             return nullptr;
121         }
122     }
123     if (!memcpy_s(startPtr_ + size_, capacity_ - size_, data, size)) {
124         size_ += size;
125         return startPtr_ + size_ - size;
126     } else {
127         return nullptr;
128     }
129 }
130 
GetSize() const131 size_t MemAllocator::GetSize() const
132 {
133     return size_;
134 }
135 
GetData() const136 const void* MemAllocator::GetData() const
137 {
138     return startPtr_;
139 }
140 
AddrToOffset(const void * addr) const141 uint32_t MemAllocator::AddrToOffset(const void* addr) const
142 {
143     if (!addr) {
144         return 0;
145     }
146 
147     auto offset = static_cast<uint32_t>(static_cast<const char*>(addr) - startPtr_);
148     if (offset > size_) {
149         return 0;
150     }
151     return offset;
152 }
153 
OffsetToAddr(size_t offset) const154 void* MemAllocator::OffsetToAddr(size_t offset) const
155 {
156     if (offset >= size_) {
157         return nullptr;
158     }
159 
160     return static_cast<void*>(startPtr_ + offset);
161 }
162 } // namespace Drawing
163 } // namespace Rosen
164 } // namespace OHOS
165