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