mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-07-20 00:33:44 -04:00
e38f35f79b
Signed-off-by: YOUR_NAME <guodongqi2@huawei.com>
477 lines
14 KiB
C
477 lines
14 KiB
C
/*
|
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
|
*
|
|
* HDF is dual licensed: you can use it either under the terms of
|
|
* the GPL, or the BSD license, at your option.
|
|
* See the LICENSE file in the root of this repository for complete details.
|
|
*/
|
|
|
|
#include "hdf_sbuf.h"
|
|
#include "hdf_log.h"
|
|
#include "hdf_sbuf_impl.h"
|
|
#include "osal_mem.h"
|
|
|
|
#define HDF_SBUF_DEFAULT_SIZE 256
|
|
#define HDF_SBUF_IMPL_CHECK_RETURN(sbuf, api, retCode) \
|
|
do { \
|
|
if (sbuf == NULL || sbuf->impl == NULL) { \
|
|
HDF_LOGE("%s: invalid sbuf object", __func__); \
|
|
return retCode; \
|
|
} \
|
|
if (sbuf->impl->api == NULL) { \
|
|
HDF_LOGE(#api " is not support on %d sbuf", sbuf->type); \
|
|
return retCode; \
|
|
} \
|
|
} while (0)
|
|
|
|
#define HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, api) \
|
|
do { \
|
|
if (sbuf == NULL || sbuf->impl == NULL) { \
|
|
HDF_LOGE("%s: invalid sbuf object", __func__); \
|
|
return; \
|
|
} \
|
|
if (sbuf->impl->api == NULL) { \
|
|
HDF_LOGE(#api " is not support on %d sbuf", sbuf->type); \
|
|
return; \
|
|
} \
|
|
} while (0)
|
|
|
|
struct HdfSBuf {
|
|
struct HdfSBufImpl *impl;
|
|
uint32_t type;
|
|
};
|
|
|
|
struct HdfSBufImpl *SbufObtainRaw(size_t capacity);
|
|
struct HdfSBufImpl *SbufBindRaw(uintptr_t base, size_t size);
|
|
struct HdfSBufImpl *SbufObtainIpc(size_t capacity) __attribute__((weak));
|
|
struct HdfSBufImpl *SbufBindIpc(uintptr_t base, size_t size) __attribute__((weak));
|
|
struct HdfSBufImpl *SbufObtainIpcHw(size_t capacity) __attribute__((weak));
|
|
struct HdfSBufImpl *SbufBindRawIpcHw(uintptr_t base, size_t size) __attribute__((weak));
|
|
|
|
static const struct HdfSbufConstructor g_sbufConstructorMap[SBUF_TYPE_MAX] = {
|
|
[SBUF_RAW] = {
|
|
.obtain = SbufObtainRaw,
|
|
.bind = SbufBindRaw,
|
|
},
|
|
[SBUF_IPC] = {
|
|
.obtain = SbufObtainIpc,
|
|
.bind = SbufBindIpc,
|
|
},
|
|
[SBUF_IPC_HW] = {
|
|
.obtain = SbufObtainIpcHw,
|
|
.bind = SbufBindRawIpcHw,
|
|
},
|
|
};
|
|
|
|
static const struct HdfSbufConstructor *HdfSbufConstructorGet(uint32_t type)
|
|
{
|
|
if (type >= SBUF_TYPE_MAX) {
|
|
return NULL;
|
|
}
|
|
|
|
return &g_sbufConstructorMap[type];
|
|
}
|
|
|
|
uint8_t *HdfSbufGetData(const struct HdfSBuf *sbuf)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getData, NULL);
|
|
return (uint8_t *)sbuf->impl->getData(sbuf->impl);
|
|
}
|
|
|
|
void HdfSbufFlush(struct HdfSBuf *sbuf)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, getData);
|
|
sbuf->impl->flush(sbuf->impl);
|
|
}
|
|
|
|
size_t HdfSbufGetCapacity(const struct HdfSBuf *sbuf)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getCapacity, HDF_FAILURE);
|
|
return (sbuf != NULL && sbuf->impl != NULL) ? sbuf->impl->getCapacity(sbuf->impl) : 0;
|
|
}
|
|
|
|
size_t HdfSbufGetDataSize(const struct HdfSBuf *sbuf)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getDataSize, HDF_FAILURE);
|
|
return sbuf->impl->getDataSize(sbuf->impl);
|
|
}
|
|
|
|
void HdfSbufSetDataSize(struct HdfSBuf *sbuf, size_t size)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, setDataSize);
|
|
sbuf->impl->setDataSize(sbuf->impl, size);
|
|
}
|
|
|
|
bool HdfSbufWriteBuffer(struct HdfSBuf *sbuf, const void *data, uint32_t writeSize)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getCapacity, false);
|
|
return sbuf->impl->writeBuffer(sbuf->impl, (const uint8_t *)data, writeSize);
|
|
}
|
|
|
|
bool HdfSbufWriteUnpadBuffer(struct HdfSBuf *sbuf, const uint8_t *data, uint32_t writeSize)
|
|
{
|
|
if (data == NULL) {
|
|
return false;
|
|
}
|
|
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUnpadBuffer, false);
|
|
return sbuf->impl->writeUnpadBuffer(sbuf->impl, data, writeSize);
|
|
}
|
|
|
|
const uint8_t *HdfSbufReadUnpadBuffer(struct HdfSBuf *sbuf, size_t length)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUnpadBuffer, NULL);
|
|
return sbuf->impl->readUnpadBuffer(sbuf->impl, length);
|
|
}
|
|
|
|
bool HdfSbufReadBuffer(struct HdfSBuf *sbuf, const void **data, uint32_t *readSize)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readBuffer, false);
|
|
return sbuf->impl->readBuffer(sbuf->impl, (const uint8_t **)data, readSize);
|
|
}
|
|
|
|
bool HdfSbufWriteUint64(struct HdfSBuf *sbuf, uint64_t value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint64, false);
|
|
return sbuf->impl->writeUint64(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufWriteUint32(struct HdfSBuf *sbuf, uint32_t value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint32, false);
|
|
return sbuf->impl->writeUint32(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufWriteUint16(struct HdfSBuf *sbuf, uint16_t value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint16, false);
|
|
return sbuf->impl->writeUint16(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufWriteUint8(struct HdfSBuf *sbuf, uint8_t value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint8, false);
|
|
return sbuf->impl->writeUint8(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufWriteInt64(struct HdfSBuf *sbuf, int64_t value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt64, false);
|
|
return sbuf->impl->writeInt64(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufWriteInt32(struct HdfSBuf *sbuf, int32_t value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt32, false);
|
|
return sbuf->impl->writeInt32(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufWriteInt16(struct HdfSBuf *sbuf, int16_t value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt16, false);
|
|
return sbuf->impl->writeInt16(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufWriteInt8(struct HdfSBuf *sbuf, int8_t value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt8, false);
|
|
return sbuf->impl->writeInt8(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufWriteString(struct HdfSBuf *sbuf, const char *value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString, false);
|
|
return sbuf->impl->writeString(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t size)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString16, false);
|
|
return sbuf->impl->writeString16(sbuf->impl, value, size);
|
|
}
|
|
|
|
bool HdfSbufReadUint64(struct HdfSBuf *sbuf, uint64_t *value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint64, false);
|
|
return sbuf->impl->readUint64(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufReadUint32(struct HdfSBuf *sbuf, uint32_t *value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint32, false);
|
|
return sbuf->impl->readUint32(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufReadUint16(struct HdfSBuf *sbuf, uint16_t *value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint16, false);
|
|
return sbuf->impl->readUint16(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufReadUint8(struct HdfSBuf *sbuf, uint8_t *value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint8, false);
|
|
return sbuf->impl->readUint8(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufReadInt64(struct HdfSBuf *sbuf, int64_t *value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt64, false);
|
|
return sbuf->impl->readInt64(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufReadInt32(struct HdfSBuf *sbuf, int32_t *value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt32, false);
|
|
return sbuf->impl->readInt32(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufReadInt16(struct HdfSBuf *sbuf, int16_t *value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt16, false);
|
|
return sbuf->impl->readInt16(sbuf->impl, value);
|
|
}
|
|
|
|
bool HdfSbufReadInt8(struct HdfSBuf *sbuf, int8_t *value)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt8, false);
|
|
return sbuf->impl->readInt8(sbuf->impl, value);
|
|
}
|
|
|
|
const char *HdfSbufReadString(struct HdfSBuf *sbuf)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString, NULL);
|
|
return sbuf->impl->readString(sbuf->impl);
|
|
}
|
|
|
|
bool HdfSBufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t size)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString16, false);
|
|
return sbuf->impl->writeString16(sbuf->impl, value, size);
|
|
}
|
|
|
|
const char16_t *HdfSbufReadString16(struct HdfSBuf *sbuf)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString16, NULL);
|
|
return sbuf->impl->readString16(sbuf->impl);
|
|
}
|
|
|
|
int32_t HdfSbufWriteRemoteService(struct HdfSBuf *sbuf, const struct HdfRemoteService *service)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeRemoteService, false);
|
|
return sbuf->impl->writeRemoteService(sbuf->impl, service);
|
|
}
|
|
|
|
struct HdfRemoteService *HdfSbufReadRemoteService(struct HdfSBuf *sbuf)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readRemoteService, NULL);
|
|
return sbuf->impl->readRemoteService(sbuf->impl);
|
|
}
|
|
|
|
bool HdfSbufWriteFloat(struct HdfSBuf *sbuf, float data)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeFloat, false);
|
|
return sbuf->impl->writeFloat(sbuf->impl, data);
|
|
}
|
|
|
|
bool HdfSbufWriteDouble(struct HdfSBuf *sbuf, double data)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeDouble, false);
|
|
return sbuf->impl->writeDouble(sbuf->impl, data);
|
|
}
|
|
|
|
bool HdfSbufWriteFileDescriptor(struct HdfSBuf *sbuf, int fd)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeFileDescriptor, false);
|
|
return sbuf->impl->writeFileDescriptor(sbuf->impl, fd);
|
|
}
|
|
|
|
int HdfSbufReadFileDescriptor(struct HdfSBuf *sbuf)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readFileDescriptor, false);
|
|
return sbuf->impl->readFileDescriptor(sbuf->impl);
|
|
}
|
|
|
|
bool HdfSbufReadDouble(struct HdfSBuf *sbuf, double *data)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readDouble, false);
|
|
return sbuf->impl->readDouble(sbuf->impl, data);
|
|
}
|
|
|
|
bool HdfSbufReadFloat(struct HdfSBuf *sbuf, float *data)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readFloat, false);
|
|
return sbuf->impl->readFloat(sbuf->impl, data);
|
|
}
|
|
|
|
struct HdfSBuf *HdfSbufTypedObtainCapacity(uint32_t type, size_t capacity)
|
|
{
|
|
struct HdfSBuf *sbuf = NULL;
|
|
const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type);
|
|
if (constructor == NULL) {
|
|
HDF_LOGE("sbuf constructor %d not implement", type);
|
|
return NULL;
|
|
}
|
|
if (constructor->obtain == NULL) {
|
|
HDF_LOGE("sbuf constructor %d obtain method not implement", type);
|
|
return NULL;
|
|
}
|
|
|
|
sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
|
|
if (sbuf == NULL) {
|
|
HDF_LOGE("instance sbuf failure");
|
|
return NULL;
|
|
}
|
|
|
|
sbuf->impl = constructor->obtain(capacity);
|
|
if (sbuf->impl == NULL) {
|
|
OsalMemFree(sbuf);
|
|
HDF_LOGE("sbuf obtain fail, size=%u", (uint32_t)capacity);
|
|
return NULL;
|
|
}
|
|
sbuf->type = type;
|
|
return sbuf;
|
|
}
|
|
|
|
struct HdfSBuf *HdfSbufTypedObtainInplace(uint32_t type, struct HdfSBufImpl *impl)
|
|
{
|
|
struct HdfSBuf *sbuf = NULL;
|
|
if (type >= SBUF_TYPE_MAX || impl == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
|
|
if (sbuf == NULL) {
|
|
HDF_LOGE("obtain in-place sbuf failure");
|
|
return NULL;
|
|
}
|
|
|
|
sbuf->impl = impl;
|
|
sbuf->type = type;
|
|
return sbuf;
|
|
}
|
|
|
|
struct HdfSBuf *HdfSbufTypedObtain(uint32_t type)
|
|
{
|
|
return HdfSbufTypedObtainCapacity(type, HDF_SBUF_DEFAULT_SIZE);
|
|
}
|
|
|
|
struct HdfSBuf *HdfSbufTypedBind(uint32_t type, uintptr_t base, size_t size)
|
|
{
|
|
struct HdfSBuf *sbuf = NULL;
|
|
const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type);
|
|
if (constructor == NULL) {
|
|
HDF_LOGE("sbuf constructor %d not implement", type);
|
|
return NULL;
|
|
}
|
|
|
|
if (constructor->bind == NULL) {
|
|
HDF_LOGE("sbuf constructor %d bind method not implement", type);
|
|
return NULL;
|
|
}
|
|
|
|
sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
|
|
if (sbuf == NULL) {
|
|
HDF_LOGE("instance sbuf failure");
|
|
return NULL;
|
|
}
|
|
|
|
sbuf->impl = constructor->bind(base, size);
|
|
if (sbuf->impl == NULL) {
|
|
OsalMemFree(sbuf);
|
|
HDF_LOGE("sbuf bind fail");
|
|
return NULL;
|
|
}
|
|
sbuf->type = type;
|
|
return sbuf;
|
|
}
|
|
|
|
struct HdfSBuf *HdfSbufObtain(size_t capacity)
|
|
{
|
|
return HdfSbufTypedObtainCapacity(SBUF_RAW, capacity);
|
|
}
|
|
|
|
struct HdfSBuf *HdfSbufObtainDefaultSize()
|
|
{
|
|
return HdfSbufObtain(HDF_SBUF_DEFAULT_SIZE);
|
|
}
|
|
|
|
struct HdfSBuf *HdfSBufObtainDefaultSize()
|
|
{
|
|
return HdfSbufObtain(HDF_SBUF_DEFAULT_SIZE);
|
|
}
|
|
|
|
struct HdfSBuf *HdfSbufBind(uintptr_t base, size_t size)
|
|
{
|
|
return HdfSbufTypedBind(SBUF_RAW, base, size);
|
|
}
|
|
|
|
struct HdfSBuf *HdfSbufCopy(const struct HdfSBuf *sbuf)
|
|
{
|
|
struct HdfSBuf *newBuf = NULL;
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, copy, NULL);
|
|
newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
|
|
if (newBuf == NULL) {
|
|
return NULL;
|
|
}
|
|
newBuf->impl = sbuf->impl->copy(sbuf->impl);
|
|
if (newBuf->impl == NULL) {
|
|
OsalMemFree(newBuf);
|
|
return NULL;
|
|
}
|
|
newBuf->type = sbuf->type;
|
|
return newBuf;
|
|
}
|
|
|
|
struct HdfSBuf *HdfSbufMove(struct HdfSBuf *sbuf)
|
|
{
|
|
struct HdfSBuf *newBuf = NULL;
|
|
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, move, NULL);
|
|
newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
|
|
if (newBuf == NULL) {
|
|
return NULL;
|
|
}
|
|
newBuf->impl = sbuf->impl->move(sbuf->impl);
|
|
if (newBuf->impl == NULL) {
|
|
OsalMemFree(newBuf);
|
|
return NULL;
|
|
}
|
|
return newBuf;
|
|
}
|
|
|
|
void HdfSbufTransDataOwnership(struct HdfSBuf *sbuf)
|
|
{
|
|
HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, transDataOwnership);
|
|
sbuf->impl->transDataOwnership(sbuf->impl);
|
|
}
|
|
|
|
void HdfSbufRecycle(struct HdfSBuf *sbuf)
|
|
{
|
|
if (sbuf != NULL) {
|
|
if (sbuf->impl != NULL && sbuf->impl->recycle != NULL) {
|
|
sbuf->impl->recycle(sbuf->impl);
|
|
sbuf->impl = NULL;
|
|
}
|
|
OsalMemFree(sbuf);
|
|
}
|
|
}
|
|
|
|
void HdfSBufRecycle(struct HdfSBuf *sbuf)
|
|
{
|
|
if (sbuf != NULL) {
|
|
if (sbuf->impl != NULL && sbuf->impl->recycle != NULL) {
|
|
sbuf->impl->recycle(sbuf->impl);
|
|
sbuf->impl = NULL;
|
|
}
|
|
OsalMemFree(sbuf);
|
|
}
|
|
}
|
|
|
|
struct HdfSBufImpl *HdfSbufGetImpl(struct HdfSBuf *sbuf)
|
|
{
|
|
if (sbuf != NULL) {
|
|
return sbuf->impl;
|
|
}
|
|
|
|
return NULL;
|
|
} |