mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-07-18 15:54:30 -04:00
sync L2 code to L1 code
This commit is contained in:
+236
-19
@@ -9,10 +9,11 @@
|
||||
* @addtogroup Core
|
||||
* @{
|
||||
*
|
||||
* @brief Provides OpenHarmony Driver Foundation (HDF) APIs.
|
||||
* @brief Provides functions to use the HarmonyOS Driver Foundation (HDF).
|
||||
*
|
||||
* The HDF implements driver framework capabilities such as driver loading, service management,
|
||||
* and driver message model. You can develop drivers based on the HDF.
|
||||
* The HDF implements driver framework capabilities such as driver loading, service management, driver message model,
|
||||
* and power management.
|
||||
* You can develop drivers based on the HDF.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@@ -20,8 +21,8 @@
|
||||
/**
|
||||
* @file hdf_sbuf.h
|
||||
*
|
||||
* @brief Defines functions related to a <b>HdfSBuf</b>. The HDF provides data serialization and deserialization
|
||||
* capabilities for data transmission between user-mode applications and kernel-mode drivers.
|
||||
* @brief Declares functions related to the HDF SBUF. The HDF provides data serialization and deserialization
|
||||
* capabilities for data transmission between user-space applications and kernel-space drivers.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@@ -33,19 +34,24 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#else
|
||||
typedef uint16_t char16_t;
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct HdfSBuf;
|
||||
struct HdfSbufImpl;
|
||||
struct HdfRemoteService;
|
||||
|
||||
/**
|
||||
* @brief Defines a <b>HdfSBuf</b>.
|
||||
* @brief Enumerates HDF SBUF types.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
struct HdfSBuf {
|
||||
size_t writePos; /**< Current write position */
|
||||
size_t readPos; /**< Current read position */
|
||||
size_t capacity; /**< Storage capacity, at most 512 KB. */
|
||||
uint8_t *data; /**< Pointer to data storage */
|
||||
bool isBind; /**< Whether to bind the externally transferred pointer for data storage */
|
||||
enum HdfSbufType {
|
||||
SBUF_RAW = 0, /* SBUF used for communication between the user space and the kernel space */
|
||||
SBUF_IPC, /* SBUF used for inter-process communication (IPC) */
|
||||
SBUF_IPC_HW, /* Reserved for extension */
|
||||
SBUF_TYPE_MAX, /* Maximum value of the SBUF type */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -60,6 +66,18 @@ struct HdfSBuf {
|
||||
*/
|
||||
bool HdfSbufWriteBuffer(struct HdfSBuf *sbuf, const void *data, uint32_t writeSize);
|
||||
|
||||
/**
|
||||
* @brief Writes unpadded data to a <b>SBuf</b>. You can call {@link HdfSbufReadUnpadBuffer} to read the unpadded data.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param data Indicates the pointer to the data to write. The value cannot be a null pointer.
|
||||
* @param writeSize Indicates the size of the data to write. The value cannot be <b>0</b>.
|
||||
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
bool HdfSbufWriteUnpadBuffer(struct HdfSBuf *sbuf, const uint8_t *data, uint32_t writeSize);
|
||||
|
||||
/**
|
||||
* @brief Writes a 64-bit unsigned integer to a <b>SBuf</b>.
|
||||
*
|
||||
@@ -159,13 +177,133 @@ bool HdfSbufWriteInt8(struct HdfSBuf *sbuf, int8_t value);
|
||||
*/
|
||||
bool HdfSbufWriteString(struct HdfSBuf *sbuf, const char *value);
|
||||
|
||||
/**
|
||||
* @brief Writes a wide character string to a <b>SBuf</b>.
|
||||
* The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param value Indicates the pointer to the wide character string to write.
|
||||
* @param size Indicates the size of the wide character string to write.
|
||||
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
bool HdfSbufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Writes a floating-point number to a <b>SBuf</b>.
|
||||
* The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param value Indicates the floating-point number to write.
|
||||
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
bool HdfSbufWriteFloat(struct HdfSBuf *sbuf, float value);
|
||||
|
||||
/**
|
||||
* @brief Writes a double-precision floating-point number to a <b>SBuf</b>.
|
||||
* The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param value Indicates the double-precision floating-point number to write.
|
||||
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
bool HdfSbufWriteDouble(struct HdfSBuf *sbuf, double value);
|
||||
|
||||
/**
|
||||
* @brief Writes a file descriptor to a <b>SBuf</b>.
|
||||
* The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param fd Indicates the file descriptor to write.
|
||||
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
bool HdfSbufWriteFileDescriptor(struct HdfSBuf *sbuf, int fd);
|
||||
|
||||
/**
|
||||
* @brief Writes an IPC service to a <b>SBuf</b>. The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param service Indicates the pointer to the IPC service to write.
|
||||
* @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdfSBufWriteRemoteService(struct HdfSBuf *sbuf, const struct HdfRemoteService *service);
|
||||
|
||||
/**
|
||||
* @brief Reads an IPC service from a <b>SBuf</b>.
|
||||
* The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @return Returns the pointer to the IPC service object if the operation is successful;
|
||||
* returns a null pointer otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
struct HdfRemoteService *HdfSBufReadRemoteService(struct HdfSBuf *sbuf);
|
||||
|
||||
/**
|
||||
* @brief Reads a file descriptor from a <b>SBuf</b>.
|
||||
* The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @return Returns a valid file descriptor if the operation is successful; returns a negative value otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int HdfSbufReadFileDescriptor(struct HdfSBuf *sbuf);
|
||||
|
||||
/**
|
||||
* @brief Reads a double-precision floating-point number from a <b>SBuf</b>.
|
||||
* The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param value Indicates the pointer to the double-precision floating-point number read,
|
||||
* which is requested by the caller.
|
||||
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
bool HdfSbufReadDouble(struct HdfSBuf *sbuf, double *value);
|
||||
|
||||
/**
|
||||
* @brief Reads a floating-point number from a <b>SBuf</b>.
|
||||
* The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param value Indicates the pointer to the floating-point number read, which is requested by the caller.
|
||||
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
bool HdfSbufReadFloat(struct HdfSBuf *sbuf, float *value);
|
||||
|
||||
/**
|
||||
* @brief Reads a wide character string from a <b>SBuf</b>.
|
||||
* The SBUF of the <b>SBUF_RAW</b> type does not support this function.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @return Returns the pointer to the wide character string if the operation is successful;
|
||||
* returns a null pointer otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
const char16_t *HdfSBufReadString16(struct HdfSBuf *sbuf);
|
||||
|
||||
/**
|
||||
* @brief Reads a data segment from a <b>SBuf</b>.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param data Indicates the double pointer to the data read. The data read is stored in <b>*data</b>,
|
||||
* which is requested by the caller. The memory pointed to by <b>*data</b> is managed by the <b>SBuf</b>
|
||||
* and they share the same lifecycle.
|
||||
* which is requested by the caller. The memory pointed to by <b>*data</b> is managed by
|
||||
* the <b>SBuf</b> and they share the same lifecycle.
|
||||
* @param readSize Indicates the pointer to the size of the data read.
|
||||
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
|
||||
*
|
||||
@@ -173,6 +311,17 @@ bool HdfSbufWriteString(struct HdfSBuf *sbuf, const char *value);
|
||||
*/
|
||||
bool HdfSbufReadBuffer(struct HdfSBuf *sbuf, const void **data, uint32_t *readSize);
|
||||
|
||||
/**
|
||||
* @brief Reads unpadded data from a <b>SBuf</b>.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param length Indicates the length of the data to read.
|
||||
* @return Returns the pointer to the unpadded data if the operation is successful; returns a null pointer otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
const uint8_t *HdfSbufReadUnpadBuffer(struct HdfSBuf *sbuf, size_t length);
|
||||
|
||||
/**
|
||||
* @brief Reads a 64-bit unsigned integer from a <b>SBuf</b>.
|
||||
*
|
||||
@@ -273,10 +422,11 @@ bool HdfSbufReadInt8(struct HdfSBuf *sbuf, int8_t *value);
|
||||
const char *HdfSbufReadString(struct HdfSBuf *sbuf);
|
||||
|
||||
/**
|
||||
* @brief Obtains the pointer to the data stored in a<b>SBuf</b>.
|
||||
* @brief Obtains the pointer to the data stored in a <b>SBuf</b>.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @return Returns the pointer to the data stored in the target <b>SBuf</b>.
|
||||
* @return Returns the pointer to the data stored in the target <b>SBuf</b> if the operation is successful;
|
||||
* returns a null pointer otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@@ -296,6 +446,7 @@ void HdfSbufFlush(struct HdfSBuf *sbuf);
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @return Returns the <b>SBuf</b> capacity.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
size_t HdfSbufGetCapacity(const struct HdfSBuf *sbuf);
|
||||
@@ -310,10 +461,20 @@ size_t HdfSbufGetCapacity(const struct HdfSBuf *sbuf);
|
||||
*/
|
||||
size_t HdfSbufGetDataSize(const struct HdfSBuf *sbuf);
|
||||
|
||||
/**
|
||||
* @brief Sets the data size of a <b>SBuf</b>.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @param size Indicates the data size to set, which cannot exceed the size obtained via {@link HdfSbufGetDataSize}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void HdfSbufSetDataSize(struct HdfSBuf *sbuf, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Obtains a <b>SBuf</b> instance.
|
||||
*
|
||||
* @param capacity Indicates the initial capacity of the<b>SBuf</b>.
|
||||
* @param capacity Indicates the initial capacity of the <b>SBuf</b>.
|
||||
* @return Returns the <b>SBuf</b> instance.
|
||||
*
|
||||
* @since 1.0
|
||||
@@ -343,9 +504,9 @@ struct HdfSBuf *HdfSBufObtainDefaultSize(void);
|
||||
struct HdfSBuf *HdfSBufBind(uintptr_t base, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Releases a <b>SBuf </b>.
|
||||
* @brief Releases a <b>SBuf</b>.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the <b>SBuf</b> to release.
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@@ -383,6 +544,62 @@ struct HdfSBuf *HdfSBufCopy(const struct HdfSBuf *sbuf);
|
||||
*/
|
||||
void HdfSbufTransDataOwnership(struct HdfSBuf *sbuf);
|
||||
|
||||
/**
|
||||
* @brief Obtains a <b>SBuf</b> instance of a specified type.
|
||||
*
|
||||
* @param type Indicates the SBUF type, which is defined in {@link HdfSbufType}.
|
||||
* @return Returns the <b>SBuf</b> instance.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
struct HdfSBuf *HdfSBufTypedObtain(uint32_t type);
|
||||
|
||||
/**
|
||||
* @brief Obtains a <b>SBuf</b> instance of a specified type based on the implementation of an existing <b>SBuf</b>.
|
||||
*
|
||||
* @param type Indicates the SBUF type, which is defined in {@link HdfSbufType}.
|
||||
* @param impl Indicates the pointer to the implementation of an existing <b>SBuf</b>.
|
||||
* @return Returns the new <b>SBuf</b> instance.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
struct HdfSBuf *HdfSBufTypedObtainInplace(uint32_t type, struct HdfSbufImpl *impl);
|
||||
|
||||
/**
|
||||
* @brief Obtains a <b>SBuf</b> instance of a specified type with the given initial capacity.
|
||||
*
|
||||
* @param type Indicates the SBUF type, which is defined in {@link HdfSbufType}.
|
||||
* @param capacity Indicates the initial capacity of the <b>SBuf</b>.
|
||||
* @return Returns the new <b>SBuf</b> instance.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
struct HdfSBuf *HdfSBufTypedObtainCapacity(uint32_t type, size_t capacity);
|
||||
|
||||
/**
|
||||
* @brief Creates a <b>SBuf</b> instance of a specified type with the specified data and size.
|
||||
* The pointer to the data stored in the <b>SBuf</b> is released by the caller,
|
||||
* and the written data size should not exceed the specified value of <b>size</b>.
|
||||
*
|
||||
* @param type Indicates the SBUF type, which is defined in {@link HdfSbufType}.
|
||||
* @param base Indicates the base of the data to use.
|
||||
* @param size Indicates the size of the data to use.
|
||||
* @return Returns the <b>SBuf</b> instance.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
struct HdfSBuf *HdfSBufTypedBind(uint32_t type, uintptr_t base, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Obtains the implementation of a <b>SBuf</b>.
|
||||
*
|
||||
* @param sbuf Indicates the pointer to the target <b>SBuf</b>.
|
||||
* @return Returns the pointer to the implementation of the <b>SBuf</b>.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
struct HdfSbufImpl *HdfSbufGetImpl(struct HdfSBuf *sbuf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef HDF_SBU_IMPL_H
|
||||
#define HDF_SBU_IMPL_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct HdfSbufConstructor {
|
||||
struct HdfSbufImpl *(*obtain)(size_t capacity);
|
||||
struct HdfSbufImpl *(*bind)(uintptr_t base, size_t size);
|
||||
};
|
||||
|
||||
struct HdfRemoteService;
|
||||
|
||||
struct HdfSbufImpl {
|
||||
bool (*writeBuffer)(struct HdfSbufImpl *sbuf, const uint8_t *data, uint32_t writeSize);
|
||||
bool (*writeUnpadBuffer)(struct HdfSbufImpl *sbuf, const uint8_t *data, uint32_t writeSize);
|
||||
bool (*writeUint64)(struct HdfSbufImpl *sbuf, uint64_t value);
|
||||
bool (*writeUint32)(struct HdfSbufImpl *sbuf, uint32_t value);
|
||||
bool (*writeUint16)(struct HdfSbufImpl *sbuf, uint16_t value);
|
||||
bool (*writeUint8)(struct HdfSbufImpl *sbuf, uint8_t value);
|
||||
bool (*writeInt64)(struct HdfSbufImpl *sbuf, int64_t value);
|
||||
bool (*writeInt32)(struct HdfSbufImpl *sbuf, int32_t value);
|
||||
bool (*writeInt16)(struct HdfSbufImpl *sbuf, int16_t value);
|
||||
bool (*writeInt8)(struct HdfSbufImpl *sbuf, int8_t value);
|
||||
bool (*writeString)(struct HdfSbufImpl *sbuf, const char *value);
|
||||
bool (*writeFileDescriptor)(struct HdfSbufImpl *sbuf, int fd);
|
||||
bool (*writeFloat)(struct HdfSbufImpl *sbuf, float value);
|
||||
bool (*writeDouble)(struct HdfSbufImpl *sbuf, double value);
|
||||
bool (*readDouble)(struct HdfSbufImpl *sbuf, double *value);
|
||||
bool (*readFloat)(struct HdfSbufImpl *sbuf, float *value);
|
||||
int (*readFileDescriptor)(struct HdfSbufImpl *sbuf);
|
||||
bool (*writeString16)(struct HdfSbufImpl *sbuf, const char16_t *value, uint32_t size);
|
||||
bool (*readBuffer)(struct HdfSbufImpl *sbuf, const uint8_t **data, uint32_t *readSize);
|
||||
const uint8_t *(*readUnpadBuffer)(struct HdfSbufImpl *sbuf, size_t length);
|
||||
bool (*readUint64)(struct HdfSbufImpl *sbuf, uint64_t *value);
|
||||
bool (*readUint32)(struct HdfSbufImpl *sbuf, uint32_t *value);
|
||||
bool (*readUint16)(struct HdfSbufImpl *sbuf, uint16_t *value);
|
||||
bool (*readUint8)(struct HdfSbufImpl *sbuf, uint8_t *value);
|
||||
bool (*readInt64)(struct HdfSbufImpl *sbuf, int64_t *value);
|
||||
bool (*readInt32)(struct HdfSbufImpl *sbuf, int32_t *value);
|
||||
bool (*readInt16)(struct HdfSbufImpl *sbuf, int16_t *value);
|
||||
bool (*readInt8)(struct HdfSbufImpl *sbuf, int8_t *value);
|
||||
const char *(*readString)(struct HdfSbufImpl *sbuf);
|
||||
const char16_t *(*readString16)(struct HdfSbufImpl *sbuf);
|
||||
int32_t (*writeRemoteService)(struct HdfSbufImpl *sbuf, const struct HdfRemoteService *service);
|
||||
struct HdfRemoteService *(*readRemoteService)(struct HdfSbufImpl *sbuf);
|
||||
const uint8_t *(*getData)(const struct HdfSbufImpl *sbuf);
|
||||
void (*flush)(struct HdfSbufImpl *sbuf);
|
||||
size_t (*getCapacity)(const struct HdfSbufImpl *sbuf);
|
||||
size_t (*getDataSize)(const struct HdfSbufImpl *sbuf);
|
||||
void (*setDataSize)(struct HdfSbufImpl *sbuf, size_t size);
|
||||
void (*recycle)(struct HdfSbufImpl *sbuf);
|
||||
struct HdfSbufImpl *(*move)(struct HdfSbufImpl *sbuf);
|
||||
struct HdfSbufImpl *(*copy)(const struct HdfSbufImpl *sbuf);
|
||||
void (*transDataOwnership)(struct HdfSbufImpl *sbuf);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDF_SBUF_H */
|
||||
/** @} */
|
||||
+296
-304
@@ -6,459 +6,451 @@
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "securec.h"
|
||||
#include "osal_mem.h"
|
||||
#include "hdf_log.h"
|
||||
#include "hdf_sbuf.h"
|
||||
#include "hdf_log.h"
|
||||
#include "hdf_sbuf_impl.h"
|
||||
#include "osal_mem.h"
|
||||
|
||||
#define HDF_SBUF_GROW_SIZE_DEFAULT 256
|
||||
#define HDF_SBUF_MAX_SIZE (512 * 1024) // 512kB
|
||||
#define HDF_SBUF_ALIGN 4
|
||||
#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)
|
||||
|
||||
#ifndef INT16_MAX
|
||||
#ifdef S16_MAX
|
||||
#define INT16_MAX S16_MAX
|
||||
#else
|
||||
#define INT16_MAX 32767
|
||||
#endif // !S16_MAX
|
||||
#endif // INT16_MAX
|
||||
#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)
|
||||
|
||||
static inline size_t HdfSbufGetAlignSize(size_t size)
|
||||
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)
|
||||
{
|
||||
return (size + HDF_SBUF_ALIGN - 1) & (~(HDF_SBUF_ALIGN - 1));
|
||||
}
|
||||
|
||||
static size_t HdfSbufGetLeftWriteSize(struct HdfSBuf *sbuf)
|
||||
{
|
||||
return (sbuf->capacity < sbuf->writePos) ? 0 : (sbuf->capacity - sbuf->writePos);
|
||||
}
|
||||
|
||||
static size_t HdfSbufGetLeftReadSize(struct HdfSBuf *sbuf)
|
||||
{
|
||||
return (sbuf->writePos < sbuf->readPos) ? 0 : (sbuf->writePos - sbuf->readPos);
|
||||
}
|
||||
|
||||
static bool HdfSbufWriteRollback(struct HdfSBuf *sbuf, uint32_t size)
|
||||
{
|
||||
size_t alignSize = HdfSbufGetAlignSize(size);
|
||||
if (sbuf->writePos < alignSize) {
|
||||
return false;
|
||||
if (type >= SBUF_TYPE_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sbuf->writePos -= alignSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HdfSbufReadRollback(struct HdfSBuf *sbuf, uint32_t size)
|
||||
{
|
||||
size_t alignSize = HdfSbufGetAlignSize(size);
|
||||
if (sbuf->readPos < alignSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sbuf->readPos -= alignSize;
|
||||
return true;
|
||||
return &g_sbufConstructorMap[type];
|
||||
}
|
||||
|
||||
uint8_t *HdfSbufGetData(const struct HdfSBuf *sbuf)
|
||||
{
|
||||
if (sbuf == NULL) {
|
||||
HDF_LOGE("Get data is null, input sbuf is null");
|
||||
return NULL;
|
||||
}
|
||||
return (uint8_t *)sbuf->data;
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getData, NULL);
|
||||
return (uint8_t *)sbuf->impl->getData(sbuf->impl);
|
||||
}
|
||||
|
||||
void HdfSbufFlush(struct HdfSBuf *sbuf)
|
||||
{
|
||||
if (sbuf != NULL) {
|
||||
sbuf->readPos = 0;
|
||||
sbuf->writePos = 0;
|
||||
}
|
||||
HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, getData);
|
||||
sbuf->impl->flush(sbuf->impl);
|
||||
}
|
||||
|
||||
size_t HdfSbufGetCapacity(const struct HdfSBuf *sbuf)
|
||||
{
|
||||
return (sbuf != NULL) ? sbuf->capacity : 0;
|
||||
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)
|
||||
{
|
||||
return (sbuf != NULL) ? sbuf->writePos : 0;
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getDataSize, HDF_FAILURE);
|
||||
return sbuf->impl->getDataSize(sbuf->impl);
|
||||
}
|
||||
|
||||
static bool HdfSbufGrow(struct HdfSBuf *sbuf, uint32_t growSize)
|
||||
void HdfSbufSetDataSize(struct HdfSBuf *sbuf, size_t size)
|
||||
{
|
||||
if (sbuf->isBind) {
|
||||
HDF_LOGE("%s: binded sbuf oom", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t newSize = HdfSbufGetAlignSize(sbuf->capacity + growSize);
|
||||
if (newSize < sbuf->capacity) {
|
||||
HDF_LOGE("%s: grow size overflow", __func__);
|
||||
return false;
|
||||
}
|
||||
if (newSize > HDF_SBUF_MAX_SIZE) {
|
||||
HDF_LOGE("%s: buf size over limit", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t *newData = OsalMemCalloc(newSize);
|
||||
if (newData == NULL) {
|
||||
HDF_LOGE("%s: oom", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sbuf->data != NULL) {
|
||||
if (memcpy_s(newData, newSize, sbuf->data, sbuf->writePos) != EOK) {
|
||||
OsalMemFree(newData);
|
||||
return false;
|
||||
}
|
||||
OsalMemFree(sbuf->data);
|
||||
}
|
||||
|
||||
sbuf->data = newData;
|
||||
sbuf->capacity = newSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HdfSbufWrite(struct HdfSBuf *sbuf, const uint8_t *data, uint32_t size)
|
||||
{
|
||||
if (sbuf == NULL || sbuf->data == NULL || data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t alignSize = HdfSbufGetAlignSize(size);
|
||||
// in case of desireCapacity overflow
|
||||
if (alignSize < size) {
|
||||
HDF_LOGE("desireCapacity is overflow");
|
||||
return false;
|
||||
}
|
||||
size_t writeableSize = HdfSbufGetLeftWriteSize(sbuf);
|
||||
if (alignSize > writeableSize) {
|
||||
size_t growSize = (alignSize > HDF_SBUF_GROW_SIZE_DEFAULT) ? (alignSize + HDF_SBUF_GROW_SIZE_DEFAULT) :
|
||||
HDF_SBUF_GROW_SIZE_DEFAULT;
|
||||
if (!HdfSbufGrow(sbuf, growSize)) {
|
||||
return false;
|
||||
}
|
||||
writeableSize = HdfSbufGetLeftWriteSize(sbuf);
|
||||
}
|
||||
|
||||
uint8_t *dest = sbuf->data + sbuf->writePos;
|
||||
if (memcpy_s(dest, writeableSize, data, size) != EOK) {
|
||||
return false; /* never hits */
|
||||
}
|
||||
|
||||
sbuf->writePos += alignSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HdfSbufRead(struct HdfSBuf *sbuf, uint8_t *data, uint32_t readSize)
|
||||
{
|
||||
if (sbuf == NULL || sbuf->data == NULL || data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (readSize == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t alignSize = HdfSbufGetAlignSize(readSize);
|
||||
if (alignSize > HdfSbufGetLeftReadSize(sbuf)) {
|
||||
HDF_LOGE("Read out of buffer range");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcpy_s(data, readSize, sbuf->data + sbuf->readPos, readSize) != EOK) {
|
||||
return false; // never hits
|
||||
}
|
||||
sbuf->readPos += alignSize;
|
||||
return true;
|
||||
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)
|
||||
{
|
||||
if (sbuf == NULL) {
|
||||
HDF_LOGE("Write buffer failed, input param is invalid");
|
||||
return false;
|
||||
}
|
||||
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 HdfSbufWriteInt32(sbuf, 0);
|
||||
}
|
||||
|
||||
if (!HdfSbufWriteInt32(sbuf, writeSize)) {
|
||||
return false;
|
||||
}
|
||||
if (!HdfSbufWrite(sbuf, data, writeSize)) {
|
||||
(void)HdfSbufWriteRollback(sbuf, sizeof(int32_t));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
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, false);
|
||||
return sbuf->impl->readUnpadBuffer(sbuf->impl, length);
|
||||
}
|
||||
|
||||
bool HdfSbufReadBuffer(struct HdfSBuf *sbuf, const void **data, uint32_t *readSize)
|
||||
{
|
||||
if (sbuf == NULL || sbuf->data == NULL || data == NULL || readSize == NULL) {
|
||||
HDF_LOGE("%s:input invalid", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
int buffSize = 0;
|
||||
if (!HdfSbufReadInt32(sbuf, &buffSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buffSize == 0) {
|
||||
*data = NULL;
|
||||
*readSize = 0;
|
||||
return true;
|
||||
}
|
||||
size_t alignSize = HdfSbufGetAlignSize(buffSize);
|
||||
if (alignSize > HdfSbufGetLeftReadSize(sbuf)) {
|
||||
HDF_LOGE("%s:readBuff out of range", __func__);
|
||||
(void)HdfSbufReadRollback(sbuf, sizeof(int32_t));
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = sbuf->data + sbuf->readPos;
|
||||
*readSize = buffSize;
|
||||
sbuf->readPos += alignSize;
|
||||
return true;
|
||||
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)
|
||||
{
|
||||
return HdfSbufWrite(sbuf, (uint8_t *)(&value), sizeof(value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint64, false);
|
||||
return sbuf->impl->writeUint64(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufWriteUint32(struct HdfSBuf *sbuf, uint32_t value)
|
||||
{
|
||||
return HdfSbufWrite(sbuf, (uint8_t *)(&value), sizeof(value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint32, false);
|
||||
return sbuf->impl->writeUint32(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufWriteUint16(struct HdfSBuf *sbuf, uint16_t value)
|
||||
{
|
||||
return HdfSbufWrite(sbuf, (uint8_t *)(&value), sizeof(value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint16, false);
|
||||
return sbuf->impl->writeUint16(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufWriteUint8(struct HdfSBuf *sbuf, uint8_t value)
|
||||
{
|
||||
return HdfSbufWrite(sbuf, (uint8_t *)(&value), sizeof(value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint8, false);
|
||||
return sbuf->impl->writeUint8(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufWriteInt64(struct HdfSBuf *sbuf, int64_t value)
|
||||
{
|
||||
return HdfSbufWrite(sbuf, (uint8_t *)(&value), sizeof(value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt64, false);
|
||||
return sbuf->impl->writeInt64(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufWriteInt32(struct HdfSBuf *sbuf, int32_t value)
|
||||
{
|
||||
return HdfSbufWrite(sbuf, (uint8_t *)(&value), sizeof(value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt32, false);
|
||||
return sbuf->impl->writeInt32(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufWriteInt16(struct HdfSBuf *sbuf, int16_t value)
|
||||
{
|
||||
return HdfSbufWrite(sbuf, (uint8_t *)(&value), sizeof(value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt16, false);
|
||||
return sbuf->impl->writeInt16(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufWriteInt8(struct HdfSBuf *sbuf, int8_t value)
|
||||
{
|
||||
return HdfSbufWrite(sbuf, (uint8_t *)(&value), sizeof(value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt8, false);
|
||||
return sbuf->impl->writeInt8(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufWriteString(struct HdfSBuf *sbuf, const char *value)
|
||||
{
|
||||
if (sbuf == NULL) {
|
||||
HDF_LOGE("%s:input null", __func__);
|
||||
return false;
|
||||
}
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString, false);
|
||||
return sbuf->impl->writeString(sbuf->impl, value);
|
||||
}
|
||||
|
||||
return HdfSbufWriteBuffer(sbuf, value, value ? (strlen(value) + 1) : 0);
|
||||
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)
|
||||
{
|
||||
return HdfSbufRead(sbuf, (uint8_t *)(value), sizeof(*value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint64, false);
|
||||
return sbuf->impl->readUint64(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufReadUint32(struct HdfSBuf *sbuf, uint32_t *value)
|
||||
{
|
||||
return HdfSbufRead(sbuf, (uint8_t *)(value), sizeof(*value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint32, false);
|
||||
return sbuf->impl->readUint32(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufReadUint16(struct HdfSBuf *sbuf, uint16_t *value)
|
||||
{
|
||||
return HdfSbufRead(sbuf, (uint8_t *)(value), sizeof(*value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint16, false);
|
||||
return sbuf->impl->readUint16(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufReadUint8(struct HdfSBuf *sbuf, uint8_t *value)
|
||||
{
|
||||
return HdfSbufRead(sbuf, (uint8_t *)(value), sizeof(*value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint8, false);
|
||||
return sbuf->impl->readUint8(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufReadInt64(struct HdfSBuf *sbuf, int64_t *value)
|
||||
{
|
||||
return HdfSbufRead(sbuf, (uint8_t *)(value), sizeof(*value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt64, false);
|
||||
return sbuf->impl->readInt64(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufReadInt32(struct HdfSBuf *sbuf, int32_t *value)
|
||||
{
|
||||
return HdfSbufRead(sbuf, (uint8_t *)(value), sizeof(*value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt32, false);
|
||||
return sbuf->impl->readInt32(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufReadInt16(struct HdfSBuf *sbuf, int16_t *value)
|
||||
{
|
||||
return HdfSbufRead(sbuf, (uint8_t *)(value), sizeof(*value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt16, false);
|
||||
return sbuf->impl->readInt16(sbuf->impl, value);
|
||||
}
|
||||
|
||||
bool HdfSbufReadInt8(struct HdfSBuf *sbuf, int8_t *value)
|
||||
{
|
||||
return HdfSbufRead(sbuf, (uint8_t *)(value), sizeof(*value));
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt8, false);
|
||||
return sbuf->impl->readInt8(sbuf->impl, value);
|
||||
}
|
||||
|
||||
const char *HdfSbufReadString(struct HdfSBuf *sbuf)
|
||||
{
|
||||
if (sbuf == NULL || sbuf->data == NULL) {
|
||||
HDF_LOGE("%s:input null", __func__);
|
||||
return NULL;
|
||||
}
|
||||
/* this length contains '\0' at the end. */
|
||||
int32_t strLen = 0;
|
||||
if (!HdfSbufReadInt32(sbuf, &strLen) || strLen <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
size_t alignSize = HdfSbufGetAlignSize(strLen);
|
||||
if (strLen > INT16_MAX || alignSize > HdfSbufGetLeftReadSize(sbuf)) {
|
||||
(void)HdfSbufReadRollback(sbuf, sizeof(int32_t));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *str = (char *)(sbuf->data + sbuf->readPos);
|
||||
sbuf->readPos += alignSize;
|
||||
/* force set '\0' at end of the string */
|
||||
str[strLen - 1] = '\0';
|
||||
return str;
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString, false);
|
||||
return sbuf->impl->readString(sbuf->impl);
|
||||
}
|
||||
|
||||
struct HdfSBuf *HdfSBufObtainDefaultSize()
|
||||
bool HdfSBufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t size)
|
||||
{
|
||||
return HdfSBufObtain(HDF_SBUF_GROW_SIZE_DEFAULT);
|
||||
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, false);
|
||||
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, false);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
struct HdfSBuf *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)
|
||||
{
|
||||
if (type >= SBUF_TYPE_MAX || impl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct HdfSBuf *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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
struct HdfSBuf *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)
|
||||
{
|
||||
if (capacity > HDF_SBUF_MAX_SIZE) {
|
||||
HDF_LOGE("%s: buf size over limit", __func__);
|
||||
return NULL;
|
||||
}
|
||||
struct HdfSBuf *sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
|
||||
if (sbuf == NULL) {
|
||||
HDF_LOGE("instance usbuf failure");
|
||||
return NULL;
|
||||
}
|
||||
return HdfSBufTypedObtainCapacity(SBUF_RAW, capacity);
|
||||
}
|
||||
|
||||
sbuf->data = (uint8_t *)OsalMemCalloc(capacity);
|
||||
if (sbuf->data == NULL) {
|
||||
OsalMemFree(sbuf);
|
||||
HDF_LOGE("sbuf obtain oom, size=%u", (uint32_t)capacity);
|
||||
return NULL;
|
||||
}
|
||||
sbuf->capacity = capacity;
|
||||
sbuf->writePos = 0;
|
||||
sbuf->readPos = 0;
|
||||
sbuf->isBind = false;
|
||||
return sbuf;
|
||||
struct HdfSBuf *HdfSBufObtainDefaultSize()
|
||||
{
|
||||
return HdfSBufObtain(HDF_SBUF_DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
struct HdfSBuf *HdfSBufBind(uintptr_t base, size_t size)
|
||||
{
|
||||
if (base == 0 || size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
/* require 4 byte alignment for base */
|
||||
if ((base & 0x3) != 0) {
|
||||
HDF_LOGE("Base is not align for 4-byte");
|
||||
return NULL;
|
||||
}
|
||||
struct HdfSBuf *sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
|
||||
if (sbuf == NULL) {
|
||||
HDF_LOGE("%s: oom", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sbuf->data = (uint8_t *)base;
|
||||
sbuf->capacity = size;
|
||||
sbuf->writePos = size;
|
||||
sbuf->readPos = 0;
|
||||
sbuf->isBind = true;
|
||||
return sbuf;
|
||||
return HdfSBufTypedBind(SBUF_RAW, base, size);
|
||||
}
|
||||
|
||||
struct HdfSBuf *HdfSBufCopy(const struct HdfSBuf *sbuf)
|
||||
{
|
||||
if (sbuf == NULL || sbuf->data == NULL) {
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, copy, NULL);
|
||||
struct HdfSBuf *newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
|
||||
if (newBuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct HdfSBuf *new = HdfSBufObtain(sbuf->capacity);
|
||||
if (new == NULL) {
|
||||
newBuf->impl = sbuf->impl->copy(sbuf->impl);
|
||||
if (newBuf->impl == NULL) {
|
||||
OsalMemFree(newBuf);
|
||||
return NULL;
|
||||
}
|
||||
new->capacity = sbuf->capacity;
|
||||
new->readPos = 0;
|
||||
new->writePos = sbuf->writePos;
|
||||
if (memcpy_s(new->data, new->capacity, sbuf->data, sbuf->writePos) != EOK) {
|
||||
HdfSBufRecycle(new);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new;
|
||||
newBuf->type = sbuf->type;
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
struct HdfSBuf *HdfSBufMove(struct HdfSBuf *sbuf)
|
||||
{
|
||||
if (sbuf == NULL || sbuf->isBind) {
|
||||
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, move, NULL);
|
||||
struct HdfSBuf *newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
|
||||
if (newBuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct HdfSBuf *new = OsalMemCalloc(sizeof(struct HdfSBuf));
|
||||
if (new == NULL) {
|
||||
newBuf->impl = sbuf->impl->move(sbuf->impl);
|
||||
if (newBuf->impl == NULL) {
|
||||
OsalMemFree(newBuf);
|
||||
return NULL;
|
||||
}
|
||||
new->capacity = sbuf->capacity;
|
||||
new->readPos = 0;
|
||||
new->writePos = sbuf->writePos;
|
||||
new->data = sbuf->data;
|
||||
|
||||
sbuf->data = NULL;
|
||||
sbuf->capacity = 0;
|
||||
HdfSbufFlush(sbuf);
|
||||
|
||||
return new;
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
void HdfSbufTransDataOwnership(struct HdfSBuf *sbuf)
|
||||
{
|
||||
if (sbuf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbuf->isBind = false;
|
||||
HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, transDataOwnership);
|
||||
sbuf->impl->transDataOwnership(sbuf->impl);
|
||||
}
|
||||
|
||||
void HdfSBufRecycle(struct HdfSBuf *sbuf)
|
||||
{
|
||||
if (sbuf != NULL) {
|
||||
if (sbuf->data != NULL && !sbuf->isBind) {
|
||||
OsalMemFree(sbuf->data);
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
/*
|
||||
* Copyright (c) 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_log.h"
|
||||
#include "hdf_sbuf.h"
|
||||
#include "hdf_sbuf_impl.h"
|
||||
#include "osal_mem.h"
|
||||
#include "securec.h"
|
||||
|
||||
#define HDF_SBUF_GROW_SIZE_DEFAULT 256
|
||||
#define HDF_SBUF_MAX_SIZE (512 * 1024) // 512KB
|
||||
#define HDF_SBUF_ALIGN 4
|
||||
|
||||
#ifndef INT16_MAX
|
||||
#ifdef S16_MAX
|
||||
#define INT16_MAX S16_MAX
|
||||
#else
|
||||
#define INT16_MAX 32767
|
||||
#endif // !S16_MAX
|
||||
#endif // INT16_MAX
|
||||
|
||||
struct HdfSBufRaw {
|
||||
struct HdfSbufImpl infImpl;
|
||||
size_t writePos; /**< Current write position */
|
||||
size_t readPos; /**< Current read position */
|
||||
size_t capacity; /**< Storage capacity, 512 KB at most. */
|
||||
uint8_t *data; /**< Pointer to data storage */
|
||||
bool isBind; /**< Whether to bind the externally transferred pointer to data storage */
|
||||
};
|
||||
|
||||
#define SBUF_RAW_CAST(impl) (struct HdfSBufRaw *)(impl)
|
||||
|
||||
static struct HdfSBufRaw *SbufRawImplNewInstance(size_t capacity);
|
||||
static void SbufInterfaceAssign(struct HdfSbufImpl *inf);
|
||||
|
||||
static size_t SbufRawImplGetAlignSize(size_t size)
|
||||
{
|
||||
return (size + HDF_SBUF_ALIGN - 1) & (~(HDF_SBUF_ALIGN - 1));
|
||||
}
|
||||
|
||||
static void SbufRawImplRecycle(struct HdfSbufImpl *impl)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf != NULL) {
|
||||
if (sbuf->data != NULL && !sbuf->isBind) {
|
||||
OsalMemFree(sbuf->data);
|
||||
}
|
||||
OsalMemFree(sbuf);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t SbufRawImplGetLeftWriteSize(struct HdfSBufRaw *sbuf)
|
||||
{
|
||||
return (sbuf->capacity < sbuf->writePos) ? 0 : (sbuf->capacity - sbuf->writePos);
|
||||
}
|
||||
|
||||
static size_t SbufRawImplGetLeftReadSize(struct HdfSBufRaw *sbuf)
|
||||
{
|
||||
return (sbuf->writePos < sbuf->readPos) ? 0 : (sbuf->writePos - sbuf->readPos);
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteRollback(struct HdfSbufImpl *impl, uint32_t size)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t alignSize = SbufRawImplGetAlignSize(size);
|
||||
if (sbuf->writePos < alignSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sbuf->writePos -= alignSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadRollback(struct HdfSbufImpl *impl, uint32_t size)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t alignSize = SbufRawImplGetAlignSize(size);
|
||||
if (sbuf->readPos < alignSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sbuf->readPos -= alignSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const uint8_t *SbufRawImplGetData(const struct HdfSbufImpl *impl)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL) {
|
||||
HDF_LOGE("The obtained data is null, and the input Sbuf is null.");
|
||||
return NULL;
|
||||
}
|
||||
return (uint8_t *)sbuf->data;
|
||||
}
|
||||
|
||||
static void SbufRawImplSetDataSize(struct HdfSbufImpl *impl, size_t size)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL) {
|
||||
return;
|
||||
}
|
||||
if (size <= sbuf->capacity) {
|
||||
sbuf->readPos = 0;
|
||||
sbuf->writePos = size;
|
||||
}
|
||||
}
|
||||
|
||||
static void SbufRawImplFlush(struct HdfSbufImpl *impl)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf != NULL) {
|
||||
sbuf->readPos = 0;
|
||||
sbuf->writePos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t SbufRawImplGetCapacity(const struct HdfSbufImpl *impl)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
return (sbuf != NULL) ? sbuf->capacity : 0;
|
||||
}
|
||||
|
||||
static size_t SbufRawImplGetDataSize(const struct HdfSbufImpl *impl)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
return (sbuf != NULL) ? sbuf->writePos : 0;
|
||||
}
|
||||
|
||||
static bool SbufRawImplGrow(struct HdfSBufRaw *sbuf, uint32_t growSize)
|
||||
{
|
||||
if (sbuf->isBind) {
|
||||
HDF_LOGE("%s: binded sbuf oom", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t newSize = SbufRawImplGetAlignSize(sbuf->capacity + growSize);
|
||||
if (newSize < sbuf->capacity) {
|
||||
HDF_LOGE("%s: grow size overflow", __func__);
|
||||
return false;
|
||||
}
|
||||
if (newSize > HDF_SBUF_MAX_SIZE) {
|
||||
HDF_LOGE("%s: buf size over limit", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t *newData = OsalMemCalloc(newSize);
|
||||
if (newData == NULL) {
|
||||
HDF_LOGE("%s: oom", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sbuf->data != NULL) {
|
||||
if (memcpy_s(newData, newSize, sbuf->data, sbuf->writePos) != EOK) {
|
||||
OsalMemFree(newData);
|
||||
return false;
|
||||
}
|
||||
OsalMemFree(sbuf->data);
|
||||
}
|
||||
|
||||
sbuf->data = newData;
|
||||
sbuf->capacity = newSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SbufRawImplWrite(struct HdfSbufImpl *impl, const uint8_t *data, uint32_t size)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL || sbuf->data == NULL || data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t alignSize = SbufRawImplGetAlignSize(size);
|
||||
// in case of desireCapacity overflow
|
||||
if (alignSize < size) {
|
||||
HDF_LOGE("desireCapacity overflow");
|
||||
return false;
|
||||
}
|
||||
size_t writeableSize = SbufRawImplGetLeftWriteSize(sbuf);
|
||||
if (alignSize > writeableSize) {
|
||||
size_t growSize = (alignSize > HDF_SBUF_GROW_SIZE_DEFAULT) ? (alignSize + HDF_SBUF_GROW_SIZE_DEFAULT)
|
||||
: HDF_SBUF_GROW_SIZE_DEFAULT;
|
||||
if (!SbufRawImplGrow(sbuf, growSize)) {
|
||||
return false;
|
||||
}
|
||||
writeableSize = SbufRawImplGetLeftWriteSize(sbuf);
|
||||
}
|
||||
|
||||
uint8_t *dest = sbuf->data + sbuf->writePos;
|
||||
if (memcpy_s(dest, writeableSize, data, size) != EOK) {
|
||||
return false; /* never hits */
|
||||
}
|
||||
|
||||
sbuf->writePos += alignSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SbufRawImplRead(struct HdfSbufImpl *impl, uint8_t *data, uint32_t readSize)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL || sbuf->data == NULL || data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (readSize == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t alignSize = SbufRawImplGetAlignSize(readSize);
|
||||
if (alignSize > SbufRawImplGetLeftReadSize(sbuf)) {
|
||||
HDF_LOGE("Read out of buffer range");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcpy_s(data, readSize, sbuf->data + sbuf->readPos, readSize) != EOK) {
|
||||
return false; // never hit
|
||||
}
|
||||
sbuf->readPos += alignSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteUint64(struct HdfSbufImpl *impl, uint64_t value)
|
||||
{
|
||||
return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteUint32(struct HdfSbufImpl *impl, uint32_t value)
|
||||
{
|
||||
return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteUint16(struct HdfSbufImpl *impl, uint16_t value)
|
||||
{
|
||||
return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteUint8(struct HdfSbufImpl *impl, uint8_t value)
|
||||
{
|
||||
return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteInt64(struct HdfSbufImpl *impl, int64_t value)
|
||||
{
|
||||
return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteInt32(struct HdfSbufImpl *impl, int32_t value)
|
||||
{
|
||||
return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteInt16(struct HdfSbufImpl *impl, int16_t value)
|
||||
{
|
||||
return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteInt8(struct HdfSbufImpl *impl, int8_t value)
|
||||
{
|
||||
return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteBuffer(struct HdfSbufImpl *impl, const uint8_t *data, uint32_t writeSize)
|
||||
{
|
||||
if (impl == NULL) {
|
||||
HDF_LOGE("Failed to write the Sbuf, invalid input params");
|
||||
return false;
|
||||
}
|
||||
if (data == NULL) {
|
||||
return SbufRawImplWriteInt32(impl, 0);
|
||||
}
|
||||
|
||||
if (!SbufRawImplWriteInt32(impl, writeSize)) {
|
||||
return false;
|
||||
}
|
||||
if (!SbufRawImplWrite(impl, data, writeSize)) {
|
||||
(void)SbufRawImplWriteRollback(impl, sizeof(int32_t));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SbufRawImplWriteString(struct HdfSbufImpl *impl, const char *value)
|
||||
{
|
||||
if (impl == NULL) {
|
||||
HDF_LOGE("%s: input null", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
return SbufRawImplWriteBuffer(impl, (const uint8_t *)value, value ? (strlen(value) + 1) : 0);
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadUint64(struct HdfSbufImpl *impl, uint64_t *value)
|
||||
{
|
||||
return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadUint32(struct HdfSbufImpl *impl, uint32_t *value)
|
||||
{
|
||||
return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadUint16(struct HdfSbufImpl *impl, uint16_t *value)
|
||||
{
|
||||
return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadUint8(struct HdfSbufImpl *impl, uint8_t *value)
|
||||
{
|
||||
return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadInt64(struct HdfSbufImpl *impl, int64_t *value)
|
||||
{
|
||||
return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadInt32(struct HdfSbufImpl *impl, int32_t *value)
|
||||
{
|
||||
return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadInt16(struct HdfSbufImpl *impl, int16_t *value)
|
||||
{
|
||||
return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadInt8(struct HdfSbufImpl *impl, int8_t *value)
|
||||
{
|
||||
return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
|
||||
}
|
||||
|
||||
static bool SbufRawImplReadBuffer(struct HdfSbufImpl *impl, const uint8_t **data, uint32_t *readSize)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL || sbuf->data == NULL || data == NULL || readSize == NULL) {
|
||||
HDF_LOGE("%s: input invalid", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
int buffSize = 0;
|
||||
if (!SbufRawImplReadInt32(impl, &buffSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buffSize == 0) {
|
||||
*data = NULL;
|
||||
*readSize = 0;
|
||||
return true;
|
||||
}
|
||||
size_t alignSize = SbufRawImplGetAlignSize(buffSize);
|
||||
if (alignSize > SbufRawImplGetLeftReadSize(sbuf)) {
|
||||
HDF_LOGE("%s:readBuff out of range", __func__);
|
||||
(void)SbufRawImplReadRollback(impl, sizeof(int32_t));
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = sbuf->data + sbuf->readPos;
|
||||
*readSize = buffSize;
|
||||
sbuf->readPos += alignSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *SbufRawImplReadString(struct HdfSbufImpl *impl)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL || sbuf->data == NULL) {
|
||||
HDF_LOGE("%s: input null", __func__);
|
||||
return NULL;
|
||||
}
|
||||
/* This length contains the '\0' at the end of the string. */
|
||||
int32_t strLen = 0;
|
||||
if (!SbufRawImplReadInt32(impl, &strLen) || strLen <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
size_t alignSize = SbufRawImplGetAlignSize(strLen);
|
||||
if (strLen > INT16_MAX || alignSize > SbufRawImplGetLeftReadSize(sbuf)) {
|
||||
(void)SbufRawImplReadRollback(impl, sizeof(int32_t));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *str = (char *)(sbuf->data + sbuf->readPos);
|
||||
sbuf->readPos += alignSize;
|
||||
/* Set '\0' at end of the string forcibly. */
|
||||
str[strLen - 1] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
static struct HdfSbufImpl *SbufRawImplCopy(const struct HdfSbufImpl *impl)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL || sbuf->data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct HdfSBufRaw *new = SbufRawImplNewInstance(sbuf->capacity);
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new->capacity = sbuf->capacity;
|
||||
new->readPos = 0;
|
||||
new->writePos = sbuf->writePos;
|
||||
if (memcpy_s(new->data, new->capacity, sbuf->data, sbuf->capacity) != EOK) {
|
||||
SbufRawImplRecycle(&new->infImpl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &new->infImpl;
|
||||
}
|
||||
|
||||
static struct HdfSbufImpl *SbufRawImplMove(struct HdfSbufImpl *impl)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL || sbuf->isBind) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct HdfSBufRaw *new = OsalMemCalloc(sizeof(struct HdfSBufRaw));
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new->capacity = sbuf->capacity;
|
||||
new->readPos = 0;
|
||||
new->writePos = sbuf->writePos;
|
||||
new->data = sbuf->data;
|
||||
|
||||
sbuf->data = NULL;
|
||||
sbuf->capacity = 0;
|
||||
SbufRawImplFlush(&sbuf->infImpl);
|
||||
SbufInterfaceAssign(&new->infImpl);
|
||||
|
||||
return &new->infImpl;
|
||||
}
|
||||
|
||||
static void SbufRawImplTransDataOwnership(struct HdfSbufImpl *impl)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
|
||||
if (sbuf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbuf->isBind = false;
|
||||
}
|
||||
|
||||
static void SbufInterfaceAssign(struct HdfSbufImpl *inf)
|
||||
{
|
||||
inf->writeBuffer = SbufRawImplWriteBuffer;
|
||||
inf->writeUint64 = SbufRawImplWriteUint64;
|
||||
inf->writeUint32 = SbufRawImplWriteUint32;
|
||||
inf->writeUint16 = SbufRawImplWriteUint16;
|
||||
inf->writeUint8 = SbufRawImplWriteUint8;
|
||||
inf->writeInt64 = SbufRawImplWriteInt64;
|
||||
inf->writeInt32 = SbufRawImplWriteInt32;
|
||||
inf->writeInt16 = SbufRawImplWriteInt16;
|
||||
inf->writeInt8 = SbufRawImplWriteInt8;
|
||||
inf->writeString = SbufRawImplWriteString;
|
||||
inf->readBuffer = SbufRawImplReadBuffer;
|
||||
inf->readUint64 = SbufRawImplReadUint64;
|
||||
inf->readUint32 = SbufRawImplReadUint32;
|
||||
inf->readUint16 = SbufRawImplReadUint16;
|
||||
inf->readUint8 = SbufRawImplReadUint8;
|
||||
inf->readInt64 = SbufRawImplReadInt64;
|
||||
inf->readInt32 = SbufRawImplReadInt32;
|
||||
inf->readInt16 = SbufRawImplReadInt16;
|
||||
inf->readInt8 = SbufRawImplReadInt8;
|
||||
inf->readString = SbufRawImplReadString;
|
||||
inf->getData = SbufRawImplGetData;
|
||||
inf->flush = SbufRawImplFlush;
|
||||
inf->getCapacity = SbufRawImplGetCapacity;
|
||||
inf->getDataSize = SbufRawImplGetDataSize;
|
||||
inf->setDataSize = SbufRawImplSetDataSize;
|
||||
inf->recycle = SbufRawImplRecycle;
|
||||
inf->move = SbufRawImplMove;
|
||||
inf->copy = SbufRawImplCopy;
|
||||
inf->transDataOwnership = SbufRawImplTransDataOwnership;
|
||||
}
|
||||
|
||||
static struct HdfSBufRaw *SbufRawImplNewInstance(size_t capacity)
|
||||
{
|
||||
if (capacity > HDF_SBUF_MAX_SIZE) {
|
||||
HDF_LOGE("%s: Sbuf size exceeding max limit", __func__);
|
||||
return NULL;
|
||||
}
|
||||
struct HdfSBufRaw *sbuf = (struct HdfSBufRaw *)OsalMemCalloc(sizeof(struct HdfSBufRaw));
|
||||
if (sbuf == NULL) {
|
||||
HDF_LOGE("Sbuf instance failure");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sbuf->data = (uint8_t *)OsalMemCalloc(capacity);
|
||||
if (sbuf->data == NULL) {
|
||||
OsalMemFree(sbuf);
|
||||
HDF_LOGE("sbuf obtain memory oom, size=%u", (uint32_t)capacity);
|
||||
return NULL;
|
||||
}
|
||||
sbuf->capacity = capacity;
|
||||
sbuf->writePos = 0;
|
||||
sbuf->readPos = 0;
|
||||
sbuf->isBind = false;
|
||||
SbufInterfaceAssign(&sbuf->infImpl);
|
||||
return sbuf;
|
||||
}
|
||||
|
||||
struct HdfSbufImpl *SbufObtainRaw(size_t capacity)
|
||||
{
|
||||
struct HdfSBufRaw *sbuf = SbufRawImplNewInstance(capacity);
|
||||
if (sbuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return &sbuf->infImpl;
|
||||
}
|
||||
|
||||
struct HdfSbufImpl *SbufBindRaw(uintptr_t base, size_t size)
|
||||
{
|
||||
if (base == 0 || size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
/* 4-byte alignment is required for base. */
|
||||
if ((base & 0x3) != 0) {
|
||||
HDF_LOGE("Base not in 4-byte alignment");
|
||||
return NULL;
|
||||
}
|
||||
struct HdfSBufRaw *sbuf = (struct HdfSBufRaw *)OsalMemAlloc(sizeof(struct HdfSBufRaw));
|
||||
if (sbuf == NULL) {
|
||||
HDF_LOGE("%s: oom", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sbuf->data = (uint8_t *)base;
|
||||
sbuf->capacity = size;
|
||||
sbuf->writePos = size;
|
||||
sbuf->readPos = 0;
|
||||
sbuf->isBind = true;
|
||||
SbufInterfaceAssign(&sbuf->infImpl);
|
||||
return &sbuf->infImpl;
|
||||
}
|
||||
Reference in New Issue
Block a user