1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hdf_log.h"
10 #include "hdf_sbuf.h"
11 #include "hdf_sbuf_impl.h"
12 #include "osal_mem.h"
13 #include "securec.h"
14
15 #define HDF_LOG_TAG hdf_sbuf_impl_raw
16 #define HDF_SBUF_GROW_SIZE_DEFAULT 256
17 #define HDF_SBUF_MAX_SIZE (512 * 1024) // 512KB
18 #define HDF_SBUF_ALIGN 4
19
20 #ifndef INT16_MAX
21 #ifdef S16_MAX
22 #define INT16_MAX S16_MAX
23 #else
24 #define INT16_MAX 32767
25 #endif // !S16_MAX
26 #endif // INT16_MAX
27
28 struct HdfSBufRaw {
29 struct HdfSBufImpl infImpl;
30 size_t writePos; /**< Current write position */
31 size_t readPos; /**< Current read position */
32 size_t capacity; /**< Storage capacity, 512 KB at most. */
33 uint8_t *data; /**< Pointer to data storage */
34 bool isBind; /**< Whether to bind the externally transferred pointer to data storage */
35 };
36
37 #define SBUF_RAW_CAST(impl) (struct HdfSBufRaw *)(impl)
38
39 static struct HdfSBufRaw *SbufRawImplNewInstance(size_t capacity);
40 static void SbufInterfaceAssign(struct HdfSBufImpl *inf);
41
SbufRawImplGetAlignSize(size_t size)42 static size_t SbufRawImplGetAlignSize(size_t size)
43 {
44 return (size + HDF_SBUF_ALIGN - 1) & (~(HDF_SBUF_ALIGN - 1));
45 }
46
SbufRawImplRecycle(struct HdfSBufImpl * impl)47 static void SbufRawImplRecycle(struct HdfSBufImpl *impl)
48 {
49 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
50 if (sbuf != NULL) {
51 if (sbuf->data != NULL && !sbuf->isBind) {
52 OsalMemFree(sbuf->data);
53 }
54 OsalMemFree(sbuf);
55 }
56 }
57
SbufRawImplGetLeftWriteSize(struct HdfSBufRaw * sbuf)58 static size_t SbufRawImplGetLeftWriteSize(struct HdfSBufRaw *sbuf)
59 {
60 return (sbuf->capacity < sbuf->writePos) ? 0 : (sbuf->capacity - sbuf->writePos);
61 }
62
SbufRawImplGetLeftReadSize(struct HdfSBufRaw * sbuf)63 static size_t SbufRawImplGetLeftReadSize(struct HdfSBufRaw *sbuf)
64 {
65 return (sbuf->writePos < sbuf->readPos) ? 0 : (sbuf->writePos - sbuf->readPos);
66 }
67
SbufRawImplWriteRollback(struct HdfSBufImpl * impl,uint32_t size)68 static bool SbufRawImplWriteRollback(struct HdfSBufImpl *impl, uint32_t size)
69 {
70 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
71 size_t alignSize;
72 if (sbuf == NULL) {
73 return false;
74 }
75
76 alignSize = SbufRawImplGetAlignSize(size);
77 if (sbuf->writePos < alignSize) {
78 return false;
79 }
80
81 sbuf->writePos -= alignSize;
82 return true;
83 }
84
SbufRawImplReadRollback(struct HdfSBufImpl * impl,uint32_t size)85 static bool SbufRawImplReadRollback(struct HdfSBufImpl *impl, uint32_t size)
86 {
87 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
88 size_t alignSize;
89 if (sbuf == NULL) {
90 return false;
91 }
92
93 alignSize = SbufRawImplGetAlignSize(size);
94 if (sbuf->readPos < alignSize) {
95 return false;
96 }
97
98 sbuf->readPos -= alignSize;
99 return true;
100 }
101
SbufRawImplGetData(const struct HdfSBufImpl * impl)102 static const uint8_t *SbufRawImplGetData(const struct HdfSBufImpl *impl)
103 {
104 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
105 if (sbuf == NULL) {
106 HDF_LOGE("The obtained data is null, and the input Sbuf is null.");
107 return NULL;
108 }
109 return (uint8_t *)sbuf->data;
110 }
111
SbufRawImplSetDataSize(struct HdfSBufImpl * impl,size_t size)112 static void SbufRawImplSetDataSize(struct HdfSBufImpl *impl, size_t size)
113 {
114 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
115 if (sbuf == NULL) {
116 return;
117 }
118 if (size <= sbuf->capacity) {
119 sbuf->readPos = 0;
120 sbuf->writePos = size;
121 }
122 }
123
SbufRawImplFlush(struct HdfSBufImpl * impl)124 static void SbufRawImplFlush(struct HdfSBufImpl *impl)
125 {
126 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
127 if (sbuf != NULL) {
128 sbuf->readPos = 0;
129 sbuf->writePos = 0;
130 }
131 }
132
SbufRawImplGetCapacity(const struct HdfSBufImpl * impl)133 static size_t SbufRawImplGetCapacity(const struct HdfSBufImpl *impl)
134 {
135 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
136 return (sbuf != NULL) ? sbuf->capacity : 0;
137 }
138
SbufRawImplGetDataSize(const struct HdfSBufImpl * impl)139 static size_t SbufRawImplGetDataSize(const struct HdfSBufImpl *impl)
140 {
141 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
142 return (sbuf != NULL) ? sbuf->writePos : 0;
143 }
144
SbufRawImplGrow(struct HdfSBufRaw * sbuf,uint32_t growSize)145 static bool SbufRawImplGrow(struct HdfSBufRaw *sbuf, uint32_t growSize)
146 {
147 uint32_t newSize;
148 uint8_t *newData = NULL;
149 if (sbuf->isBind) {
150 HDF_LOGE("%s: binded sbuf oom", __func__);
151 return false;
152 }
153
154 newSize = SbufRawImplGetAlignSize(sbuf->capacity + growSize);
155 if (newSize < sbuf->capacity) {
156 HDF_LOGE("%s: grow size overflow", __func__);
157 return false;
158 }
159 if (newSize > HDF_SBUF_MAX_SIZE) {
160 HDF_LOGE("%s: buf size over limit", __func__);
161 return false;
162 }
163
164 newData = OsalMemCalloc(newSize);
165 if (newData == NULL) {
166 HDF_LOGE("%s: oom", __func__);
167 return false;
168 }
169
170 if (sbuf->data != NULL) {
171 if (memcpy_s(newData, newSize, sbuf->data, sbuf->writePos) != EOK) {
172 OsalMemFree(newData);
173 return false;
174 }
175 OsalMemFree(sbuf->data);
176 }
177
178 sbuf->data = newData;
179 sbuf->capacity = newSize;
180
181 return true;
182 }
183
SbufRawImplWrite(struct HdfSBufImpl * impl,const uint8_t * data,uint32_t size)184 static bool SbufRawImplWrite(struct HdfSBufImpl *impl, const uint8_t *data, uint32_t size)
185 {
186 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
187 size_t alignSize;
188 size_t writeableSize;
189 uint8_t *dest = NULL;
190
191 if (sbuf == NULL || sbuf->data == NULL || data == NULL) {
192 return false;
193 }
194
195 if (size == 0) {
196 return true;
197 }
198
199 alignSize = SbufRawImplGetAlignSize(size);
200 // in case of desireCapacity overflow
201 if (alignSize < size) {
202 HDF_LOGE("desireCapacity overflow");
203 return false;
204 }
205 writeableSize = SbufRawImplGetLeftWriteSize(sbuf);
206 if (alignSize > writeableSize) {
207 size_t growSize = (alignSize > HDF_SBUF_GROW_SIZE_DEFAULT) ? (alignSize + HDF_SBUF_GROW_SIZE_DEFAULT) :
208 HDF_SBUF_GROW_SIZE_DEFAULT;
209 if (!SbufRawImplGrow(sbuf, growSize)) {
210 return false;
211 }
212 writeableSize = SbufRawImplGetLeftWriteSize(sbuf);
213 }
214
215 dest = sbuf->data + sbuf->writePos;
216 if (memcpy_s(dest, writeableSize, data, size) != EOK) {
217 return false; /* never hits */
218 }
219
220 sbuf->writePos += alignSize;
221 return true;
222 }
223
SbufRawImplRead(struct HdfSBufImpl * impl,uint8_t * data,uint32_t readSize)224 static bool SbufRawImplRead(struct HdfSBufImpl *impl, uint8_t *data, uint32_t readSize)
225 {
226 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
227 size_t alignSize;
228 if (sbuf == NULL || sbuf->data == NULL || data == NULL) {
229 return false;
230 }
231
232 if (readSize == 0) {
233 return true;
234 }
235
236 alignSize = SbufRawImplGetAlignSize(readSize);
237 if (alignSize > SbufRawImplGetLeftReadSize(sbuf)) {
238 HDF_LOGE("Read out of buffer range");
239 return false;
240 }
241
242 if (memcpy_s(data, readSize, sbuf->data + sbuf->readPos, readSize) != EOK) {
243 return false; // never hit
244 }
245 sbuf->readPos += alignSize;
246 return true;
247 }
248
SbufRawImplWriteUint64(struct HdfSBufImpl * impl,uint64_t value)249 static bool SbufRawImplWriteUint64(struct HdfSBufImpl *impl, uint64_t value)
250 {
251 return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
252 }
253
SbufRawImplWriteUint32(struct HdfSBufImpl * impl,uint32_t value)254 static bool SbufRawImplWriteUint32(struct HdfSBufImpl *impl, uint32_t value)
255 {
256 return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
257 }
258
SbufRawImplWriteUint16(struct HdfSBufImpl * impl,uint16_t value)259 static bool SbufRawImplWriteUint16(struct HdfSBufImpl *impl, uint16_t value)
260 {
261 return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
262 }
263
SbufRawImplWriteUint8(struct HdfSBufImpl * impl,uint8_t value)264 static bool SbufRawImplWriteUint8(struct HdfSBufImpl *impl, uint8_t value)
265 {
266 return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
267 }
268
SbufRawImplWriteInt64(struct HdfSBufImpl * impl,int64_t value)269 static bool SbufRawImplWriteInt64(struct HdfSBufImpl *impl, int64_t value)
270 {
271 return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
272 }
273
SbufRawImplWriteInt32(struct HdfSBufImpl * impl,int32_t value)274 static bool SbufRawImplWriteInt32(struct HdfSBufImpl *impl, int32_t value)
275 {
276 return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
277 }
278
SbufRawImplWriteInt16(struct HdfSBufImpl * impl,int16_t value)279 static bool SbufRawImplWriteInt16(struct HdfSBufImpl *impl, int16_t value)
280 {
281 return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
282 }
283
SbufRawImplWriteInt8(struct HdfSBufImpl * impl,int8_t value)284 static bool SbufRawImplWriteInt8(struct HdfSBufImpl *impl, int8_t value)
285 {
286 return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
287 }
288
SbufRawImplWriteBuffer(struct HdfSBufImpl * impl,const uint8_t * data,uint32_t writeSize)289 static bool SbufRawImplWriteBuffer(struct HdfSBufImpl *impl, const uint8_t *data, uint32_t writeSize)
290 {
291 if (impl == NULL) {
292 HDF_LOGE("Failed to write the Sbuf, invalid input params");
293 return false;
294 }
295 if (data == NULL) {
296 return SbufRawImplWriteInt32(impl, 0);
297 }
298
299 if (!SbufRawImplWriteInt32(impl, writeSize)) {
300 return false;
301 }
302 if (!SbufRawImplWrite(impl, data, writeSize)) {
303 (void)SbufRawImplWriteRollback(impl, sizeof(int32_t));
304 return false;
305 }
306
307 return true;
308 }
309
SbufRawImplWriteString(struct HdfSBufImpl * impl,const char * value)310 static bool SbufRawImplWriteString(struct HdfSBufImpl *impl, const char *value)
311 {
312 if (impl == NULL) {
313 HDF_LOGE("%s: input null", __func__);
314 return false;
315 }
316
317 return SbufRawImplWriteBuffer(impl, (const uint8_t *)value, value ? (strlen(value) + 1) : 0);
318 }
319
SbufRawImplReadUint64(struct HdfSBufImpl * impl,uint64_t * value)320 static bool SbufRawImplReadUint64(struct HdfSBufImpl *impl, uint64_t *value)
321 {
322 return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
323 }
324
SbufRawImplReadUint32(struct HdfSBufImpl * impl,uint32_t * value)325 static bool SbufRawImplReadUint32(struct HdfSBufImpl *impl, uint32_t *value)
326 {
327 return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
328 }
329
SbufRawImplReadUint16(struct HdfSBufImpl * impl,uint16_t * value)330 static bool SbufRawImplReadUint16(struct HdfSBufImpl *impl, uint16_t *value)
331 {
332 return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
333 }
334
SbufRawImplReadUint8(struct HdfSBufImpl * impl,uint8_t * value)335 static bool SbufRawImplReadUint8(struct HdfSBufImpl *impl, uint8_t *value)
336 {
337 return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
338 }
339
SbufRawImplReadInt64(struct HdfSBufImpl * impl,int64_t * value)340 static bool SbufRawImplReadInt64(struct HdfSBufImpl *impl, int64_t *value)
341 {
342 return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
343 }
344
SbufRawImplReadInt32(struct HdfSBufImpl * impl,int32_t * value)345 static bool SbufRawImplReadInt32(struct HdfSBufImpl *impl, int32_t *value)
346 {
347 return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
348 }
349
SbufRawImplReadInt16(struct HdfSBufImpl * impl,int16_t * value)350 static bool SbufRawImplReadInt16(struct HdfSBufImpl *impl, int16_t *value)
351 {
352 return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
353 }
354
SbufRawImplReadInt8(struct HdfSBufImpl * impl,int8_t * value)355 static bool SbufRawImplReadInt8(struct HdfSBufImpl *impl, int8_t *value)
356 {
357 return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
358 }
359
SbufRawImplReadBuffer(struct HdfSBufImpl * impl,const uint8_t ** data,uint32_t * readSize)360 static bool SbufRawImplReadBuffer(struct HdfSBufImpl *impl, const uint8_t **data, uint32_t *readSize)
361 {
362 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
363 int buffSize = 0;
364 size_t alignSize;
365 if (sbuf == NULL || sbuf->data == NULL || data == NULL || readSize == NULL) {
366 HDF_LOGE("%s: input invalid", __func__);
367 return false;
368 }
369
370 if (!SbufRawImplReadInt32(impl, &buffSize)) {
371 return false;
372 }
373
374 if (buffSize == 0) {
375 *data = NULL;
376 *readSize = 0;
377 return true;
378 }
379 alignSize = SbufRawImplGetAlignSize(buffSize);
380 if (alignSize > SbufRawImplGetLeftReadSize(sbuf)) {
381 HDF_LOGE("%{public}s:readBuff out of range", __func__);
382 (void)SbufRawImplReadRollback(impl, sizeof(int32_t));
383 return false;
384 }
385
386 *data = sbuf->data + sbuf->readPos;
387 *readSize = buffSize;
388 sbuf->readPos += alignSize;
389 return true;
390 }
391
SbufRawImplReadString(struct HdfSBufImpl * impl)392 static const char *SbufRawImplReadString(struct HdfSBufImpl *impl)
393 {
394 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
395 int32_t strLen = 0;
396 size_t alignSize;
397 char *str = NULL;
398 if (sbuf == NULL || sbuf->data == NULL) {
399 HDF_LOGE("%s: input null", __func__);
400 return NULL;
401 }
402 /* This length contains the '\0' at the end of the string. */
403 if (!SbufRawImplReadInt32(impl, &strLen) || strLen <= 0) {
404 return NULL;
405 }
406 alignSize = SbufRawImplGetAlignSize(strLen);
407 if (strLen > INT16_MAX || alignSize > SbufRawImplGetLeftReadSize(sbuf)) {
408 (void)SbufRawImplReadRollback(impl, sizeof(int32_t));
409 return NULL;
410 }
411
412 str = (char *)(sbuf->data + sbuf->readPos);
413 sbuf->readPos += alignSize;
414 /* Set '\0' at end of the string forcibly. */
415 str[strLen - 1] = '\0';
416 return str;
417 }
418
SbufRawImplCopy(const struct HdfSBufImpl * impl)419 static struct HdfSBufImpl *SbufRawImplCopy(const struct HdfSBufImpl *impl)
420 {
421 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
422 struct HdfSBufRaw *new = NULL;
423 if (sbuf == NULL || sbuf->data == NULL) {
424 return NULL;
425 }
426
427 new = SbufRawImplNewInstance(sbuf->capacity);
428 if (new == NULL) {
429 return NULL;
430 }
431 new->capacity = sbuf->capacity;
432 new->readPos = 0;
433 new->writePos = sbuf->writePos;
434 if (memcpy_s(new->data, new->capacity, sbuf->data, sbuf->capacity) != EOK) {
435 SbufRawImplRecycle(&new->infImpl);
436 return NULL;
437 }
438
439 return &new->infImpl;
440 }
441
SbufRawImplMove(struct HdfSBufImpl * impl)442 static struct HdfSBufImpl *SbufRawImplMove(struct HdfSBufImpl *impl)
443 {
444 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
445 struct HdfSBufRaw *new = NULL;
446 if (sbuf == NULL || sbuf->isBind) {
447 return NULL;
448 }
449
450 new = OsalMemCalloc(sizeof(struct HdfSBufRaw));
451 if (new == NULL) {
452 return NULL;
453 }
454 new->capacity = sbuf->capacity;
455 new->readPos = 0;
456 new->writePos = sbuf->writePos;
457 new->data = sbuf->data;
458
459 sbuf->data = NULL;
460 sbuf->capacity = 0;
461 SbufRawImplFlush(&sbuf->infImpl);
462 SbufInterfaceAssign(&new->infImpl);
463
464 return &new->infImpl;
465 }
466
SbufRawImplTransDataOwnership(struct HdfSBufImpl * impl)467 static void SbufRawImplTransDataOwnership(struct HdfSBufImpl *impl)
468 {
469 struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
470 if (sbuf == NULL) {
471 return;
472 }
473
474 sbuf->isBind = false;
475 }
476
SbufInterfaceAssign(struct HdfSBufImpl * inf)477 static void SbufInterfaceAssign(struct HdfSBufImpl *inf)
478 {
479 static struct HdfSBufImpl rawImpl = {
480 .writeBuffer = SbufRawImplWriteBuffer,
481 .writeUint64 = SbufRawImplWriteUint64,
482 .writeUint32 = SbufRawImplWriteUint32,
483 .writeUint16 = SbufRawImplWriteUint16,
484 .writeUint8 = SbufRawImplWriteUint8,
485 .writeInt64 = SbufRawImplWriteInt64,
486 .writeInt32 = SbufRawImplWriteInt32,
487 .writeInt16 = SbufRawImplWriteInt16,
488 .writeInt8 = SbufRawImplWriteInt8,
489 .writeString = SbufRawImplWriteString,
490 .readBuffer = SbufRawImplReadBuffer,
491 .readUint64 = SbufRawImplReadUint64,
492 .readUint32 = SbufRawImplReadUint32,
493 .readUint16 = SbufRawImplReadUint16,
494 .readUint8 = SbufRawImplReadUint8,
495 .readInt64 = SbufRawImplReadInt64,
496 .readInt32 = SbufRawImplReadInt32,
497 .readInt16 = SbufRawImplReadInt16,
498 .readInt8 = SbufRawImplReadInt8,
499 .readString = SbufRawImplReadString,
500 .getData = SbufRawImplGetData,
501 .flush = SbufRawImplFlush,
502 .getCapacity = SbufRawImplGetCapacity,
503 .getDataSize = SbufRawImplGetDataSize,
504 .setDataSize = SbufRawImplSetDataSize,
505 .recycle = SbufRawImplRecycle,
506 .move = SbufRawImplMove,
507 .copy = SbufRawImplCopy,
508 .transDataOwnership = SbufRawImplTransDataOwnership,
509 };
510
511 (void)memcpy_s(inf, sizeof(struct HdfSBufImpl), &rawImpl, sizeof(struct HdfSBufImpl));
512 }
513
SbufRawImplNewInstance(size_t capacity)514 static struct HdfSBufRaw *SbufRawImplNewInstance(size_t capacity)
515 {
516 struct HdfSBufRaw *sbuf = NULL;
517 if (capacity > HDF_SBUF_MAX_SIZE) {
518 HDF_LOGE("%s: Sbuf size exceeding max limit", __func__);
519 return NULL;
520 }
521 sbuf = (struct HdfSBufRaw *)OsalMemCalloc(sizeof(struct HdfSBufRaw));
522 if (sbuf == NULL) {
523 HDF_LOGE("Sbuf instance failure");
524 return NULL;
525 }
526
527 sbuf->data = (uint8_t *)OsalMemCalloc(capacity);
528 if (sbuf->data == NULL) {
529 OsalMemFree(sbuf);
530 HDF_LOGE("sbuf obtain memory oom, size=%u", (uint32_t)capacity);
531 return NULL;
532 }
533 sbuf->capacity = capacity;
534 sbuf->writePos = 0;
535 sbuf->readPos = 0;
536 sbuf->isBind = false;
537 SbufInterfaceAssign(&sbuf->infImpl);
538 return sbuf;
539 }
540
SbufObtainRaw(size_t capacity)541 struct HdfSBufImpl *SbufObtainRaw(size_t capacity)
542 {
543 struct HdfSBufRaw *sbuf = SbufRawImplNewInstance(capacity);
544 if (sbuf == NULL) {
545 return NULL;
546 }
547 return &sbuf->infImpl;
548 }
549
SbufBindRaw(uintptr_t base,size_t size)550 struct HdfSBufImpl *SbufBindRaw(uintptr_t base, size_t size)
551 {
552 struct HdfSBufRaw *sbuf = NULL;
553 if (base == 0 || size == 0) {
554 return NULL;
555 }
556 /* 4-byte alignment is required for base. */
557 if ((base & 0x3) != 0) {
558 HDF_LOGE("Base not in 4-byte alignment");
559 return NULL;
560 }
561 sbuf = (struct HdfSBufRaw *)OsalMemAlloc(sizeof(struct HdfSBufRaw));
562 if (sbuf == NULL) {
563 HDF_LOGE("%s: oom", __func__);
564 return NULL;
565 }
566
567 sbuf->data = (uint8_t *)base;
568 sbuf->capacity = size;
569 sbuf->writePos = size;
570 sbuf->readPos = 0;
571 sbuf->isBind = true;
572 SbufInterfaceAssign(&sbuf->infImpl);
573 return &sbuf->infImpl;
574 }