• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "serial_buffer.h"
17 #include <new>
18 #include "securec.h"
19 #include "db_errno.h"
20 #include "communicator_type_define.h"
21 #include "log_print.h"
22 
23 namespace DistributedDB {
~SerialBuffer()24 SerialBuffer::~SerialBuffer()
25 {
26     if (!isExternalStackMemory_ && oringinalBytes_ != nullptr) {
27         delete[] oringinalBytes_;
28     }
29     oringinalBytes_ = nullptr;
30     bytes_ = nullptr;
31     externalBytes_ = nullptr;
32 }
33 
SetExtendHeadLength(uint32_t extendHeaderLen)34 void SerialBuffer::SetExtendHeadLength(uint32_t extendHeaderLen)
35 {
36     extendHeadLen_ = extendHeaderLen;
37 }
38 
GetExtendHeadLength() const39 uint32_t SerialBuffer::GetExtendHeadLength() const
40 {
41     return extendHeadLen_;
42 }
43 
44 // In case buffer be directly send out, so padding is needed
AllocBufferByPayloadLength(uint32_t inPayloadLen,uint32_t inHeaderLen)45 int SerialBuffer::AllocBufferByPayloadLength(uint32_t inPayloadLen, uint32_t inHeaderLen)
46 {
47     if (oringinalBytes_ != nullptr || bytes_ != nullptr || externalBytes_ != nullptr) {
48         return -E_NOT_PERMIT;
49     }
50 
51     payloadLen_ = inPayloadLen;
52     headerLen_ = inHeaderLen;
53     totalLen_ = BYTE_8_ALIGN(payloadLen_ + headerLen_);
54     paddingLen_ = totalLen_ - payloadLen_ - headerLen_;
55     if (totalLen_ == 0 || totalLen_ > MAX_TOTAL_LEN) {
56         return -E_INVALID_ARGS;
57     }
58     oringinalBytes_ = new (std::nothrow) uint8_t[totalLen_ + extendHeadLen_]();
59     if (oringinalBytes_ == nullptr) {
60         return -E_OUT_OF_MEMORY;
61     }
62     bytes_ = oringinalBytes_ + extendHeadLen_;
63     return E_OK;
64 }
65 
66 // In case assemble fragment to frame, so no padding is needed, using frameLen as inTotalLen
AllocBufferByTotalLength(uint32_t inTotalLen,uint32_t inHeaderLen)67 int SerialBuffer::AllocBufferByTotalLength(uint32_t inTotalLen, uint32_t inHeaderLen)
68 {
69     if (bytes_ != nullptr || externalBytes_ != nullptr) {
70         return -E_NOT_PERMIT;
71     }
72     if (inTotalLen == 0 || inTotalLen > MAX_TOTAL_LEN || inTotalLen < inHeaderLen) {
73         return -E_INVALID_ARGS;
74     }
75 
76     totalLen_ = inTotalLen;
77     headerLen_ = inHeaderLen;
78     payloadLen_ = totalLen_ - headerLen_;
79     paddingLen_ = 0;
80     bytes_ = new (std::nothrow) uint8_t[inTotalLen]();
81     if (bytes_ == nullptr) {
82         return -E_OUT_OF_MEMORY;
83     }
84     oringinalBytes_ = bytes_;
85     return E_OK;
86 }
87 
88 // In case directly received, inTotalLen not include the padding, using frameLen as inTotalLen
SetExternalBuff(const uint8_t * buff,uint32_t inTotalLen,uint32_t inHeaderLen)89 int SerialBuffer::SetExternalBuff(const uint8_t *buff, uint32_t inTotalLen, uint32_t inHeaderLen)
90 {
91     if (bytes_ != nullptr || externalBytes_ != nullptr) {
92         return -E_NOT_PERMIT;
93     }
94     if (buff == nullptr || inTotalLen == 0 || inTotalLen > MAX_TOTAL_LEN || inTotalLen < inHeaderLen) {
95         return -E_INVALID_ARGS;
96     }
97 
98     totalLen_ = inTotalLen;
99     headerLen_ = inHeaderLen;
100     payloadLen_ = totalLen_ - headerLen_;
101     paddingLen_ = 0;
102     isExternalStackMemory_ = true;
103     externalBytes_ = buff;
104     return E_OK;
105 }
106 
Clone(int & outErrorNo)107 SerialBuffer *SerialBuffer::Clone(int &outErrorNo)
108 {
109     SerialBuffer *twinBuffer = new (std::nothrow) SerialBuffer();
110     if (twinBuffer == nullptr) {
111         outErrorNo = -E_OUT_OF_MEMORY;
112         return nullptr;
113     }
114     if (bytes_ == nullptr) {
115         twinBuffer->bytes_ = nullptr;
116     } else {
117         twinBuffer->bytes_ = new (std::nothrow) uint8_t[totalLen_];
118         if (twinBuffer->bytes_ == nullptr) {
119             outErrorNo = -E_OUT_OF_MEMORY;
120             delete twinBuffer;
121             twinBuffer = nullptr;
122             return nullptr;
123         }
124         errno_t errCode = memcpy_s(twinBuffer->bytes_, totalLen_, bytes_, totalLen_);
125         if (errCode != EOK) {
126             outErrorNo = -E_SECUREC_ERROR;
127             delete twinBuffer;
128             twinBuffer = nullptr;
129             return nullptr;
130         }
131     }
132     twinBuffer->oringinalBytes_ = twinBuffer->bytes_;
133     twinBuffer->externalBytes_ = externalBytes_;
134     twinBuffer->totalLen_ = totalLen_;
135     twinBuffer->headerLen_ = headerLen_;
136     twinBuffer->payloadLen_ = payloadLen_;
137     twinBuffer->paddingLen_ = paddingLen_;
138     twinBuffer->isExternalStackMemory_ = isExternalStackMemory_;
139     twinBuffer->extendHeadLen_ = extendHeadLen_;
140     outErrorNo = E_OK;
141     return twinBuffer;
142 }
143 
ConvertForCrossThread()144 int SerialBuffer::ConvertForCrossThread()
145 {
146     if (externalBytes_ == nullptr) {
147         // No associated external stack memory. Do nothing and return E_OK.
148         return E_OK;
149     }
150     // Logic guarantee all the member value: isExternalStackMemory_ is true; bytes_ is nullptr; totalLen_ is correct.
151     bytes_ = new (std::nothrow) uint8_t[totalLen_];
152     if (bytes_ == nullptr) {
153         return -E_OUT_OF_MEMORY;
154     }
155     errno_t errCode = memcpy_s(bytes_, totalLen_, externalBytes_, totalLen_);
156     if (errCode != EOK) {
157         delete[] bytes_;
158         bytes_ = nullptr;
159         return -E_SECUREC_ERROR;
160     }
161     // Reset external related info
162     externalBytes_ = nullptr;
163     isExternalStackMemory_ = false;
164     oringinalBytes_ = bytes_;
165     extendHeadLen_ = 0;
166     return E_OK;
167 }
168 
GetSize() const169 uint32_t SerialBuffer::GetSize() const
170 {
171     if (bytes_ == nullptr && externalBytes_ == nullptr) {
172         return 0;
173     }
174     return totalLen_;
175 }
176 
GetOringinalAddr() const177 uint8_t *SerialBuffer::GetOringinalAddr() const
178 {
179     return oringinalBytes_;
180 }
181 
GetWritableBytesForEntireBuffer()182 std::pair<uint8_t *, uint32_t> SerialBuffer::GetWritableBytesForEntireBuffer()
183 {
184     if (bytes_ == nullptr) {
185         return std::make_pair(nullptr, 0);
186     } else {
187         return std::make_pair(bytes_, totalLen_);
188     }
189 }
190 
GetWritableBytesForEntireFrame()191 std::pair<uint8_t *, uint32_t> SerialBuffer::GetWritableBytesForEntireFrame()
192 {
193     if (bytes_ == nullptr) {
194         return std::make_pair(nullptr, 0);
195     } else {
196         return std::make_pair(bytes_, totalLen_ - paddingLen_);
197     }
198 }
199 
GetWritableBytesForHeader()200 std::pair<uint8_t *, uint32_t> SerialBuffer::GetWritableBytesForHeader()
201 {
202     if (bytes_ == nullptr) {
203         return std::make_pair(nullptr, 0);
204     } else {
205         return std::make_pair(bytes_, headerLen_);
206     }
207 }
208 
GetWritableBytesForPayload()209 std::pair<uint8_t *, uint32_t> SerialBuffer::GetWritableBytesForPayload()
210 {
211     if (bytes_ == nullptr) {
212         return std::make_pair(nullptr, 0);
213     } else {
214         return std::make_pair(bytes_ + headerLen_, payloadLen_);
215     }
216 }
217 
218 // For receive case, using Const Function
GetReadOnlyBytesForEntireBuffer() const219 std::pair<const uint8_t *, uint32_t> SerialBuffer::GetReadOnlyBytesForEntireBuffer() const
220 {
221     if (isExternalStackMemory_) {
222         return std::make_pair(externalBytes_, totalLen_);
223     } else if (bytes_ != nullptr) {
224         return std::make_pair(bytes_, totalLen_);
225     } else {
226         return std::make_pair(nullptr, 0);
227     }
228 }
229 
GetReadOnlyBytesForEntireFrame() const230 std::pair<const uint8_t *, uint32_t> SerialBuffer::GetReadOnlyBytesForEntireFrame() const
231 {
232     if (isExternalStackMemory_) {
233         return std::make_pair(externalBytes_, totalLen_ - paddingLen_);
234     } else if (bytes_ != nullptr) {
235         return std::make_pair(bytes_, totalLen_ - paddingLen_);
236     } else {
237         return std::make_pair(nullptr, 0);
238     }
239 }
240 
GetReadOnlyBytesForHeader() const241 std::pair<const uint8_t *, uint32_t> SerialBuffer::GetReadOnlyBytesForHeader() const
242 {
243     if (isExternalStackMemory_) {
244         return std::make_pair(externalBytes_, headerLen_);
245     } else if (bytes_ != nullptr) {
246         return std::make_pair(bytes_, headerLen_);
247     } else {
248         return std::make_pair(nullptr, 0);
249     }
250 }
251 
GetReadOnlyBytesForPayload() const252 std::pair<const uint8_t *, uint32_t> SerialBuffer::GetReadOnlyBytesForPayload() const
253 {
254     if (isExternalStackMemory_) {
255         return std::make_pair(externalBytes_ + headerLen_, payloadLen_);
256     } else if (bytes_ != nullptr) {
257         return std::make_pair(bytes_ + headerLen_, payloadLen_);
258     } else {
259         return std::make_pair(nullptr, 0);
260     }
261 }
262 }
263