1 /*
2 * Copyright (C) 2021 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 "buffer_object.h"
17
18 #include "ipc_debug.h"
19 #include "log_tags.h"
20 #include "securec.h"
21 #include "sys_binder.h"
22
23 namespace OHOS {
BufferObject()24 BufferObject::BufferObject()
25 {
26 }
27
~BufferObject()28 BufferObject::~BufferObject()
29 {
30 if (receiveBuffer_ != nullptr) {
31 delete[] receiveBuffer_;
32 receiveBuffer_ = nullptr;
33 }
34 if (sendBuffer_ != nullptr) {
35 delete[] sendBuffer_;
36 sendBuffer_ = nullptr;
37 }
38 }
39
40 /* update buffer need get mutex first */
UpdateSendBuffer(uint32_t userDataSize)41 void BufferObject::UpdateSendBuffer(uint32_t userDataSize)
42 {
43 if (sendBufferCursorW_ <= sendBufferCursorR_) {
44 sendBufferCursorW_ = 0;
45 sendBufferCursorR_ = 0;
46 return;
47 }
48 /* buffer is not enough, means need expand buffer */
49 if (sendBuffSize_ - sendBufferCursorW_ <= userDataSize) {
50 ExpandSendBuffer(sendBuffSize_ + sendBuffSize_);
51 }
52 /* check whether buffer size is enough, if not, move write/read cursor to head */
53 /* writeCursor always bigger than readCursor */
54 if (sendBuffSize_ - sendBufferCursorW_ < SOCKET_BUFF_RESERVED_SIZE &&
55 sendBufferCursorW_ - sendBufferCursorR_ < sendBufferCursorR_) {
56 auto memcpyResult = memmove_s(sendBuffer_, sendBufferCursorW_ - sendBufferCursorR_,
57 sendBuffer_ + sendBufferCursorR_, sendBufferCursorW_ - sendBufferCursorR_);
58 if (memcpyResult != EOK) {
59 sendBufferCursorW_ = 0; // drop data in buffer, if memmove failed
60 } else {
61 sendBufferCursorW_ = sendBufferCursorW_ - sendBufferCursorR_;
62 }
63 sendBufferCursorR_ = 0;
64 }
65 }
66
67 /* update buffer need get mutex first */
68 // LCOV_EXCL_START
UpdateReceiveBuffer()69 void BufferObject::UpdateReceiveBuffer()
70 {
71 if (recvBufferCursorW_ <= recvBufferCursorR_) {
72 recvBufferCursorR_ = 0;
73 recvBufferCursorW_ = 0;
74 return;
75 }
76 /* check whether buffer size is enough, if not, move write/read cursor to head */
77 /* writeCursor always bigger than readCursor */
78 if (recvBuffSize_ - recvBufferCursorW_ < SOCKET_BUFF_RESERVED_SIZE &&
79 recvBufferCursorW_ - recvBufferCursorR_ < recvBufferCursorR_) {
80 auto memcpyResult = memmove_s(receiveBuffer_, recvBufferCursorW_ - recvBufferCursorR_,
81 receiveBuffer_ + recvBufferCursorR_, recvBufferCursorW_ - recvBufferCursorR_);
82 if (memcpyResult != EOK) {
83 recvBufferCursorW_ = 0; // drop data in buffer, if memmove failed
84 } else {
85 recvBufferCursorW_ = recvBufferCursorW_ - recvBufferCursorR_;
86 }
87 recvBufferCursorR_ = 0;
88 }
89 }
90 // LCOV_EXCL_STOP
91
GetSendBufferAndLock(uint32_t size)92 char *BufferObject::GetSendBufferAndLock(uint32_t size)
93 {
94 uint32_t needSize = GetNeedBufferSize(size);
95 if (needSize == 0) {
96 return nullptr;
97 }
98 sendMutex_.lock();
99 if (!ExpandSendBuffer(size)) {
100 sendMutex_.unlock();
101 return nullptr;
102 }
103
104 /* attention: need unlock mutex by caller */
105 return sendBuffer_;
106 }
107
108 /* this function should be call in mutex locked */
ExpandSendBuffer(uint32_t size)109 bool BufferObject::ExpandSendBuffer(uint32_t size)
110 {
111 uint32_t needSize = GetNeedBufferSize(size);
112 if (needSize == 0) {
113 return true;
114 }
115 if (needSize > sendBuffSize_) {
116 char *newBuffer_ = new (std::nothrow) char[needSize];
117 if (newBuffer_ == nullptr) {
118 return false;
119 }
120
121 if ((sendBuffer_ != nullptr) && (sendBuffSize_ != 0)) {
122 int memcpyResult = memcpy_s(newBuffer_, needSize, sendBuffer_, sendBuffSize_);
123 if (memcpyResult != 0) {
124 delete[] newBuffer_;
125 return false;
126 }
127 }
128
129 delete[] sendBuffer_;
130 sendBuffer_ = newBuffer_;
131 sendBuffSize_ = needSize;
132 }
133 return true;
134 }
135
GetReceiveBufferAndLock(uint32_t size)136 char *BufferObject::GetReceiveBufferAndLock(uint32_t size)
137 {
138 uint32_t needSize = GetNeedBufferSize(size);
139 if (needSize == 0) {
140 return nullptr;
141 }
142 recvMutex_.lock();
143 if (needSize > recvBuffSize_) {
144 char *newBuffer_ = new (std::nothrow) char[needSize];
145 if (newBuffer_ == nullptr) {
146 recvMutex_.unlock();
147 return nullptr;
148 }
149
150 if ((receiveBuffer_ != nullptr) && (recvBuffSize_ != 0)) {
151 int memcpyResult = memcpy_s(newBuffer_, needSize, receiveBuffer_, recvBuffSize_);
152 if (memcpyResult != 0) {
153 delete[] newBuffer_;
154 recvMutex_.unlock();
155 return nullptr;
156 }
157 }
158
159 delete[] receiveBuffer_;
160 receiveBuffer_ = newBuffer_;
161 recvBuffSize_ = needSize;
162 }
163
164 /* attention: need unlock mutex by caller */
165 return receiveBuffer_;
166 }
167
ReleaseSendBufferLock()168 void BufferObject::ReleaseSendBufferLock()
169 {
170 sendMutex_.unlock();
171 }
172
ReleaseReceiveBufferLock()173 void BufferObject::ReleaseReceiveBufferLock()
174 {
175 recvMutex_.unlock();
176 }
177
GetReceiveBufferWriteCursor() const178 ssize_t BufferObject::GetReceiveBufferWriteCursor() const
179 {
180 return recvBufferCursorW_;
181 }
182
SetReceiveBufferWriteCursor(ssize_t newWriteCursor)183 void BufferObject::SetReceiveBufferWriteCursor(ssize_t newWriteCursor)
184 {
185 recvBufferCursorW_ = newWriteCursor;
186 }
187
GetReceiveBufferReadCursor() const188 ssize_t BufferObject::GetReceiveBufferReadCursor() const
189 {
190 return recvBufferCursorR_;
191 }
192
SetReceiveBufferReadCursor(ssize_t newReadCursor)193 void BufferObject::SetReceiveBufferReadCursor(ssize_t newReadCursor)
194 {
195 recvBufferCursorR_ = newReadCursor;
196 }
197
GetSendBufferWriteCursor() const198 ssize_t BufferObject::GetSendBufferWriteCursor() const
199 {
200 return sendBufferCursorW_;
201 }
202
SetSendBufferWriteCursor(ssize_t newWriteCursor)203 void BufferObject::SetSendBufferWriteCursor(ssize_t newWriteCursor)
204 {
205 sendBufferCursorW_ = newWriteCursor;
206 }
207
GetSendBufferReadCursor() const208 ssize_t BufferObject::GetSendBufferReadCursor() const
209 {
210 return sendBufferCursorR_;
211 }
212
SetSendBufferReadCursor(ssize_t newReadCursor)213 void BufferObject::SetSendBufferReadCursor(ssize_t newReadCursor)
214 {
215 sendBufferCursorR_ = newReadCursor;
216 }
217
GetNeedBufferSize(uint32_t size) const218 uint32_t BufferObject::GetNeedBufferSize(uint32_t size) const
219 {
220 if (size <= SOCKET_BUFF_SIZE_USER_S) {
221 return SOCKET_BUFF_SIZE_USER_S;
222 } else if (size <= SOCKET_BUFF_SIZE_USER_M) {
223 return SOCKET_BUFF_SIZE_USER_M;
224 } else if (size <= SOCKET_BUFF_SIZE_USER_L) {
225 return SOCKET_BUFF_SIZE_USER_L;
226 } else if (size <= SOCKET_BUFF_SIZE_USER_HUGE) {
227 return SOCKET_BUFF_SIZE_USER_HUGE;
228 } else {
229 return 0;
230 }
231 }
232
GetSendBufferSize() const233 uint32_t BufferObject::GetSendBufferSize() const
234 {
235 return sendBuffSize_;
236 }
237
GetRecvBufferSize() const238 uint32_t BufferObject::GetRecvBufferSize() const
239 {
240 return recvBuffSize_;
241 }
242 } // namespace OHOS
243