1 /*
2  * Copyright (c) 2020-2021 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_sbuf.h"
10 #include "hdf_log.h"
11 #include "hdf_sbuf_impl.h"
12 #include "osal_mem.h"
13 
14 #define HDF_SBUF_DEFAULT_SIZE 256
15 #define HDF_SBUF_IMPL_CHECK_RETURN(sbuf, api, retCode) do {          \
16         if ((sbuf) == NULL || (sbuf)->impl == NULL) {                    \
17             HDF_LOGE("%s: invalid sbuf object", __func__);           \
18             return retCode;                                          \
19         }                                                            \
20         if ((sbuf)->impl->api == NULL) {                               \
21             HDF_LOGE(#api " is not supported on %u sbuf", (sbuf)->type); \
22             return retCode;                                          \
23         }                                                            \
24     } while (0)
25 
26 #define HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, api) do {              \
27         if ((sbuf) == NULL || (sbuf)->impl == NULL) {                    \
28             HDF_LOGE("%s: invalid sbuf object", __func__);           \
29             return;                                                  \
30         }                                                            \
31         if ((sbuf)->impl->api == NULL) {                               \
32             HDF_LOGE(#api " is not supported on %u sbuf", (sbuf)->type); \
33             return;                                                  \
34         }                                                            \
35     } while (0)
36 
37 struct HdfSBuf {
38     struct HdfSBufImpl *impl;
39     uint32_t type;
40 };
41 
42 struct HdfSBufImpl *SbufObtainRaw(size_t capacity);
43 struct HdfSBufImpl *SbufBindRaw(uintptr_t base, size_t size);
44 struct HdfSBufImpl *SbufObtainIpc(size_t capacity) __attribute__((weak));
45 struct HdfSBufImpl *SbufBindIpc(uintptr_t base, size_t size) __attribute__((weak));
46 struct HdfSBufImpl *SbufObtainIpcHw(size_t capacity) __attribute__((weak));
47 struct HdfSBufImpl *SbufBindRawIpcHw(uintptr_t base, size_t size) __attribute__((weak));
48 
49 static const struct HdfSbufConstructor g_sbufConstructorMap[SBUF_TYPE_MAX] = {
50     [SBUF_RAW] = {
51         .obtain = SbufObtainRaw,
52         .bind = SbufBindRaw,
53     },
54     [SBUF_IPC] = {
55         .obtain = SbufObtainIpc,
56         .bind = SbufBindIpc,
57     },
58     [SBUF_IPC_HW] = {
59         .obtain = SbufObtainIpcHw,
60         .bind = SbufBindRawIpcHw,
61     },
62 };
63 
HdfSbufConstructorGet(uint32_t type)64 static const struct HdfSbufConstructor *HdfSbufConstructorGet(uint32_t type)
65 {
66     if (type >= SBUF_TYPE_MAX) {
67         return NULL;
68     }
69 
70     return &g_sbufConstructorMap[type];
71 }
72 
HdfSbufGetData(const struct HdfSBuf * sbuf)73 uint8_t *HdfSbufGetData(const struct HdfSBuf *sbuf)
74 {
75     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getData, NULL);
76     return (uint8_t *)sbuf->impl->getData(sbuf->impl);
77 }
78 
HdfSbufFlush(struct HdfSBuf * sbuf)79 void HdfSbufFlush(struct HdfSBuf *sbuf)
80 {
81     HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, getData);
82     sbuf->impl->flush(sbuf->impl);
83 }
84 
HdfSbufGetCapacity(const struct HdfSBuf * sbuf)85 size_t HdfSbufGetCapacity(const struct HdfSBuf *sbuf)
86 {
87     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getCapacity, HDF_FAILURE);
88     return (sbuf != NULL && sbuf->impl != NULL) ? sbuf->impl->getCapacity(sbuf->impl) : 0;
89 }
90 
HdfSbufGetDataSize(const struct HdfSBuf * sbuf)91 size_t HdfSbufGetDataSize(const struct HdfSBuf *sbuf)
92 {
93     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getDataSize, HDF_FAILURE);
94     return sbuf->impl->getDataSize(sbuf->impl);
95 }
96 
HdfSbufSetDataSize(struct HdfSBuf * sbuf,size_t size)97 void HdfSbufSetDataSize(struct HdfSBuf *sbuf, size_t size)
98 {
99     HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, setDataSize);
100     sbuf->impl->setDataSize(sbuf->impl, size);
101 }
102 
HdfSbufWriteBuffer(struct HdfSBuf * sbuf,const void * data,uint32_t writeSize)103 bool HdfSbufWriteBuffer(struct HdfSBuf *sbuf, const void *data, uint32_t writeSize)
104 {
105     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getCapacity, false);
106     return sbuf->impl->writeBuffer(sbuf->impl, (const uint8_t *)data, writeSize);
107 }
108 
HdfSbufWriteUnpadBuffer(struct HdfSBuf * sbuf,const uint8_t * data,uint32_t writeSize)109 bool HdfSbufWriteUnpadBuffer(struct HdfSBuf *sbuf, const uint8_t *data, uint32_t writeSize)
110 {
111     if (data == NULL) {
112         return false;
113     }
114 
115     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUnpadBuffer, false);
116     return sbuf->impl->writeUnpadBuffer(sbuf->impl, data, writeSize);
117 }
118 
HdfSbufReadUnpadBuffer(struct HdfSBuf * sbuf,size_t length)119 const uint8_t *HdfSbufReadUnpadBuffer(struct HdfSBuf *sbuf, size_t length)
120 {
121     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUnpadBuffer, NULL);
122     return sbuf->impl->readUnpadBuffer(sbuf->impl, length);
123 }
124 
HdfSbufReadBuffer(struct HdfSBuf * sbuf,const void ** data,uint32_t * readSize)125 bool HdfSbufReadBuffer(struct HdfSBuf *sbuf, const void **data, uint32_t *readSize)
126 {
127     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readBuffer, false);
128     return sbuf->impl->readBuffer(sbuf->impl, (const uint8_t **)data, readSize);
129 }
130 
HdfSbufWriteUint64(struct HdfSBuf * sbuf,uint64_t value)131 bool HdfSbufWriteUint64(struct HdfSBuf *sbuf, uint64_t value)
132 {
133     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint64, false);
134     return sbuf->impl->writeUint64(sbuf->impl, value);
135 }
136 
HdfSbufWriteUint32(struct HdfSBuf * sbuf,uint32_t value)137 bool HdfSbufWriteUint32(struct HdfSBuf *sbuf, uint32_t value)
138 {
139     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint32, false);
140     return sbuf->impl->writeUint32(sbuf->impl, value);
141 }
142 
HdfSbufWriteUint16(struct HdfSBuf * sbuf,uint16_t value)143 bool HdfSbufWriteUint16(struct HdfSBuf *sbuf, uint16_t value)
144 {
145     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint16, false);
146     return sbuf->impl->writeUint16(sbuf->impl, value);
147 }
148 
HdfSbufWriteUint8(struct HdfSBuf * sbuf,uint8_t value)149 bool HdfSbufWriteUint8(struct HdfSBuf *sbuf, uint8_t value)
150 {
151     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint8, false);
152     return sbuf->impl->writeUint8(sbuf->impl, value);
153 }
154 
HdfSbufWriteInt64(struct HdfSBuf * sbuf,int64_t value)155 bool HdfSbufWriteInt64(struct HdfSBuf *sbuf, int64_t value)
156 {
157     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt64, false);
158     return sbuf->impl->writeInt64(sbuf->impl, value);
159 }
160 
HdfSbufWriteInt32(struct HdfSBuf * sbuf,int32_t value)161 bool HdfSbufWriteInt32(struct HdfSBuf *sbuf, int32_t value)
162 {
163     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt32, false);
164     return sbuf->impl->writeInt32(sbuf->impl, value);
165 }
166 
HdfSbufWriteInt16(struct HdfSBuf * sbuf,int16_t value)167 bool HdfSbufWriteInt16(struct HdfSBuf *sbuf, int16_t value)
168 {
169     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt16, false);
170     return sbuf->impl->writeInt16(sbuf->impl, value);
171 }
172 
HdfSbufWriteInt8(struct HdfSBuf * sbuf,int8_t value)173 bool HdfSbufWriteInt8(struct HdfSBuf *sbuf, int8_t value)
174 {
175     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt8, false);
176     return sbuf->impl->writeInt8(sbuf->impl, value);
177 }
178 
HdfSbufWriteString(struct HdfSBuf * sbuf,const char * value)179 bool HdfSbufWriteString(struct HdfSBuf *sbuf, const char *value)
180 {
181     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString, false);
182     return sbuf->impl->writeString(sbuf->impl, value);
183 }
184 
HdfSbufWriteString16(struct HdfSBuf * sbuf,const char16_t * value,uint32_t size)185 bool HdfSbufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t size)
186 {
187     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString16, false);
188     return sbuf->impl->writeString16(sbuf->impl, value, size);
189 }
190 
HdfSbufReadUint64(struct HdfSBuf * sbuf,uint64_t * value)191 bool HdfSbufReadUint64(struct HdfSBuf *sbuf, uint64_t *value)
192 {
193     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint64, false);
194     return sbuf->impl->readUint64(sbuf->impl, value);
195 }
196 
HdfSbufReadUint32(struct HdfSBuf * sbuf,uint32_t * value)197 bool HdfSbufReadUint32(struct HdfSBuf *sbuf, uint32_t *value)
198 {
199     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint32, false);
200     return sbuf->impl->readUint32(sbuf->impl, value);
201 }
202 
HdfSbufReadUint16(struct HdfSBuf * sbuf,uint16_t * value)203 bool HdfSbufReadUint16(struct HdfSBuf *sbuf, uint16_t *value)
204 {
205     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint16, false);
206     return sbuf->impl->readUint16(sbuf->impl, value);
207 }
208 
HdfSbufReadUint8(struct HdfSBuf * sbuf,uint8_t * value)209 bool HdfSbufReadUint8(struct HdfSBuf *sbuf, uint8_t *value)
210 {
211     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint8, false);
212     return sbuf->impl->readUint8(sbuf->impl, value);
213 }
214 
HdfSbufReadInt64(struct HdfSBuf * sbuf,int64_t * value)215 bool HdfSbufReadInt64(struct HdfSBuf *sbuf, int64_t *value)
216 {
217     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt64, false);
218     return sbuf->impl->readInt64(sbuf->impl, value);
219 }
220 
HdfSbufReadInt32(struct HdfSBuf * sbuf,int32_t * value)221 bool HdfSbufReadInt32(struct HdfSBuf *sbuf, int32_t *value)
222 {
223     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt32, false);
224     return sbuf->impl->readInt32(sbuf->impl, value);
225 }
226 
HdfSbufReadInt16(struct HdfSBuf * sbuf,int16_t * value)227 bool HdfSbufReadInt16(struct HdfSBuf *sbuf, int16_t *value)
228 {
229     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt16, false);
230     return sbuf->impl->readInt16(sbuf->impl, value);
231 }
232 
HdfSbufReadInt8(struct HdfSBuf * sbuf,int8_t * value)233 bool HdfSbufReadInt8(struct HdfSBuf *sbuf, int8_t *value)
234 {
235     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt8, false);
236     return sbuf->impl->readInt8(sbuf->impl, value);
237 }
238 
HdfSbufReadString(struct HdfSBuf * sbuf)239 const char *HdfSbufReadString(struct HdfSBuf *sbuf)
240 {
241     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString, NULL);
242     return sbuf->impl->readString(sbuf->impl);
243 }
244 
HdfSBufWriteString16(struct HdfSBuf * sbuf,const char16_t * value,uint32_t size)245 bool HdfSBufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t size)
246 {
247     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString16, false);
248     return sbuf->impl->writeString16(sbuf->impl, value, size);
249 }
250 
HdfSbufReadString16(struct HdfSBuf * sbuf)251 const char16_t *HdfSbufReadString16(struct HdfSBuf *sbuf)
252 {
253     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString16, NULL);
254     return sbuf->impl->readString16(sbuf->impl);
255 }
256 
HdfSbufWriteRemoteService(struct HdfSBuf * sbuf,const struct HdfRemoteService * service)257 int32_t HdfSbufWriteRemoteService(struct HdfSBuf *sbuf, const struct HdfRemoteService *service)
258 {
259     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeRemoteService, false);
260     return sbuf->impl->writeRemoteService(sbuf->impl, service);
261 }
262 
HdfSbufReadRemoteService(struct HdfSBuf * sbuf)263 struct HdfRemoteService *HdfSbufReadRemoteService(struct HdfSBuf *sbuf)
264 {
265     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readRemoteService, NULL);
266     return sbuf->impl->readRemoteService(sbuf->impl);
267 }
268 
HdfSbufWriteFloat(struct HdfSBuf * sbuf,float data)269 bool HdfSbufWriteFloat(struct HdfSBuf *sbuf, float data)
270 {
271     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeFloat, false);
272     return sbuf->impl->writeFloat(sbuf->impl, data);
273 }
274 
HdfSbufWriteDouble(struct HdfSBuf * sbuf,double data)275 bool HdfSbufWriteDouble(struct HdfSBuf *sbuf, double data)
276 {
277     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeDouble, false);
278     return sbuf->impl->writeDouble(sbuf->impl, data);
279 }
280 
HdfSbufWriteFileDescriptor(struct HdfSBuf * sbuf,int fd)281 bool HdfSbufWriteFileDescriptor(struct HdfSBuf *sbuf, int fd)
282 {
283     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeFileDescriptor, false);
284     return sbuf->impl->writeFileDescriptor(sbuf->impl, fd);
285 }
286 
HdfSbufReadFileDescriptor(struct HdfSBuf * sbuf)287 int HdfSbufReadFileDescriptor(struct HdfSBuf *sbuf)
288 {
289     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readFileDescriptor, false);
290     return sbuf->impl->readFileDescriptor(sbuf->impl);
291 }
292 
HdfSbufReadDouble(struct HdfSBuf * sbuf,double * data)293 bool HdfSbufReadDouble(struct HdfSBuf *sbuf, double *data)
294 {
295     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readDouble, false);
296     return sbuf->impl->readDouble(sbuf->impl, data);
297 }
298 
HdfSbufReadFloat(struct HdfSBuf * sbuf,float * data)299 bool HdfSbufReadFloat(struct HdfSBuf *sbuf, float *data)
300 {
301     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readFloat, false);
302     return sbuf->impl->readFloat(sbuf->impl, data);
303 }
304 
HdfSbufTypedObtainCapacity(uint32_t type,size_t capacity)305 struct HdfSBuf *HdfSbufTypedObtainCapacity(uint32_t type, size_t capacity)
306 {
307     struct HdfSBuf *sbuf = NULL;
308 #ifndef __KERNEL__
309     const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type);
310     if (constructor == NULL) {
311         HDF_LOGE("sbuf constructor %u not implement", type);
312         return NULL;
313     }
314     if (constructor->obtain == NULL) {
315         HDF_LOGE("sbuf constructor %u obtain method not implement", type);
316         return NULL;
317     }
318 #endif
319     sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
320     if (sbuf == NULL) {
321         HDF_LOGE("HdfSbufTypedObtainCapacity OsalMemAlloc failure");
322         return NULL;
323     }
324 #ifdef __KERNEL__
325     if (type != SBUF_RAW) {
326         OsalMemFree(sbuf);
327         HDF_LOGE("failed to obtain sbuf, unknown type %u", type);
328         return NULL;
329     }
330     sbuf->impl = SbufObtainRaw(capacity);
331 #else
332     sbuf->impl = constructor->obtain(capacity);
333 #endif
334     if (sbuf->impl == NULL) {
335         OsalMemFree(sbuf);
336         HDF_LOGE("sbuf obtain fail, size=%u", (uint32_t)capacity);
337         return NULL;
338     }
339     sbuf->type = type;
340     return sbuf;
341 }
342 
HdfSbufTypedObtainInplace(uint32_t type,struct HdfSBufImpl * impl)343 struct HdfSBuf *HdfSbufTypedObtainInplace(uint32_t type, struct HdfSBufImpl *impl)
344 {
345     struct HdfSBuf *sbuf = NULL;
346     if (type >= SBUF_TYPE_MAX || impl == NULL) {
347         return NULL;
348     }
349 
350     sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
351     if (sbuf == NULL) {
352         HDF_LOGE("obtain in-place sbuf failure");
353         return NULL;
354     }
355 
356     sbuf->impl = impl;
357     sbuf->type = type;
358     return sbuf;
359 }
360 
HdfSbufTypedObtain(uint32_t type)361 struct HdfSBuf *HdfSbufTypedObtain(uint32_t type)
362 {
363     return HdfSbufTypedObtainCapacity(type, HDF_SBUF_DEFAULT_SIZE);
364 }
365 
HdfSbufTypedBind(uint32_t type,uintptr_t base,size_t size)366 struct HdfSBuf *HdfSbufTypedBind(uint32_t type, uintptr_t base, size_t size)
367 {
368     struct HdfSBuf *sbuf = NULL;
369 #ifndef __KERNEL__
370     const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type);
371     if (constructor == NULL) {
372         HDF_LOGE("sbuf constructor %u not implement", type);
373         return NULL;
374     }
375 
376     if (constructor->bind == NULL) {
377         HDF_LOGE("sbuf constructor %u bind method not implement", type);
378         return NULL;
379     }
380 #endif
381     sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
382     if (sbuf == NULL) {
383         HDF_LOGE("HdfSbufTypedBind OsalMemAlloc failure");
384         return NULL;
385     }
386 #ifdef __KERNEL__
387     if (type != SBUF_RAW) {
388         OsalMemFree(sbuf);
389         HDF_LOGE("failed to bind sbuf, unknown type %u", type);
390         return NULL;
391     }
392     sbuf->impl = SbufBindRaw(base, size);
393 #else
394     sbuf->impl = constructor->bind(base, size);
395 #endif
396     if (sbuf->impl == NULL) {
397         OsalMemFree(sbuf);
398         HDF_LOGE("sbuf bind fail");
399         return NULL;
400     }
401     sbuf->type = type;
402     return sbuf;
403 }
404 
HdfSbufObtain(size_t capacity)405 struct HdfSBuf *HdfSbufObtain(size_t capacity)
406 {
407     return HdfSbufTypedObtainCapacity(SBUF_RAW, capacity);
408 }
409 
HdfSbufObtainDefaultSize(void)410 struct HdfSBuf *HdfSbufObtainDefaultSize(void)
411 {
412     return HdfSbufObtain(HDF_SBUF_DEFAULT_SIZE);
413 }
414 
HdfSBufObtainDefaultSize(void)415 struct HdfSBuf *HdfSBufObtainDefaultSize(void)
416 {
417     return HdfSbufObtain(HDF_SBUF_DEFAULT_SIZE);
418 }
419 
HdfSbufBind(uintptr_t base,size_t size)420 struct HdfSBuf *HdfSbufBind(uintptr_t base, size_t size)
421 {
422     return HdfSbufTypedBind(SBUF_RAW, base, size);
423 }
424 
HdfSbufCopy(const struct HdfSBuf * sbuf)425 struct HdfSBuf *HdfSbufCopy(const struct HdfSBuf *sbuf)
426 {
427     struct HdfSBuf *newBuf = NULL;
428     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, copy, NULL);
429     newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
430     if (newBuf == NULL) {
431         return NULL;
432     }
433     newBuf->impl = sbuf->impl->copy(sbuf->impl);
434     if (newBuf->impl == NULL) {
435         OsalMemFree(newBuf);
436         return NULL;
437     }
438     newBuf->type = sbuf->type;
439     return newBuf;
440 }
441 
HdfSbufMove(struct HdfSBuf * sbuf)442 struct HdfSBuf *HdfSbufMove(struct HdfSBuf *sbuf)
443 {
444     struct HdfSBuf *newBuf = NULL;
445     HDF_SBUF_IMPL_CHECK_RETURN(sbuf, move, NULL);
446     newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
447     if (newBuf == NULL) {
448         return NULL;
449     }
450     newBuf->impl = sbuf->impl->move(sbuf->impl);
451     if (newBuf->impl == NULL) {
452         OsalMemFree(newBuf);
453         return NULL;
454     }
455     return newBuf;
456 }
457 
HdfSbufTransDataOwnership(struct HdfSBuf * sbuf)458 void HdfSbufTransDataOwnership(struct HdfSBuf *sbuf)
459 {
460     HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, transDataOwnership);
461     sbuf->impl->transDataOwnership(sbuf->impl);
462 }
463 
HdfSbufRecycle(struct HdfSBuf * sbuf)464 void HdfSbufRecycle(struct HdfSBuf *sbuf)
465 {
466     if (sbuf != NULL) {
467         if (sbuf->impl != NULL && sbuf->impl->recycle != NULL) {
468             sbuf->impl->recycle(sbuf->impl);
469             sbuf->impl = NULL;
470         }
471         OsalMemFree(sbuf);
472     }
473 }
474 
HdfSBufRecycle(struct HdfSBuf * sbuf)475 void HdfSBufRecycle(struct HdfSBuf *sbuf)
476 {
477     if (sbuf != NULL) {
478         if (sbuf->impl != NULL && sbuf->impl->recycle != NULL) {
479             sbuf->impl->recycle(sbuf->impl);
480             sbuf->impl = NULL;
481         }
482         OsalMemFree(sbuf);
483     }
484 }
485 
HdfSbufGetImpl(struct HdfSBuf * sbuf)486 struct HdfSBufImpl *HdfSbufGetImpl(struct HdfSBuf *sbuf)
487 {
488     if (sbuf != NULL) {
489         return sbuf->impl;
490     }
491 
492     return NULL;
493 }