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