往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- OpenHarmony轻量系统服务管理|samgr_server功能详解(一)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(二)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(三)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(四)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(五)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(六)
- OpenHarmony分布式调度详解|dmslite.c
- OpenHarmony分布式调度详解|dmslite_feature.c 源码阅读
- OpenHarmony分布式调度详解|dmslite_session.c
- OpenHarmony分布式调度详解|dmslite_tlv_common.c
- 持续更新中……
前言
用于转换 tlv 数据,处理 tlv 的结点情况,将不同类型的数据进行整合。
函数实现详解
通过类型获取结点
/*
函数功能:获取结点
函数参数:@nodeType:结点的类型
@tlvHead: tlv 格式数据
函数返回:成功就返回查找到的 tlv 结点,否则返回空
*/
TlvNode* GetNodeByType(uint8_t nodeType, const TlvNode *tlvHead)
{
TlvNode* tlvNode = (TlvNode *)tlvHead; // 强制转型,将常量指针转为非常量指针
while (tlvNode != NULL) { // 参数校验
if (tlvNode->type == nodeType) { // 通过结点的类型查找
return tlvNode; // 返回查找到的结点
}
tlvNode = tlvNode->next; // 当前结点不符合,向下寻找
}
return NULL; // 未找到,返回空
}
将数据转化为小端模式
/*
函数功能:转换 int 类型数据,从大端转为小端模式
函数参数:@dataIn:输入的数据
@typeSize:数据的类型大小
函数返回:小端模式的数据
*/
static uint64_t ConvertIntDataBig2Little(const uint8_t *dataIn, uint8_t typeSize)
{
uint64_t dataOut = 0; // 初始化
switch (typeSize) { // 根据类型选择转换的函数
case INT_16: // 输入的数据如果是两个字节
Convert16DataBig2Little(dataIn, (uint16_t*)&dataOut); // 两个字节大小的数据,从大端转小端
break;
case INT_32: // 输入的数据如果是四个字节
Convert32DataBig2Little(dataIn, (uint32_t*)&dataOut); // 四个字节大小的数据,从大端转小端
break;
case INT_64: // 输入的数据如果是八个字节
Convert64DataBig2Little(dataIn, (uint64_t*)&dataOut); // 八个字节大小的数据,从大端转小端
break;
default:
break; // 其他情况不处理
}
return dataOut; // 处理后为小端模式的结果
}
类型转换
/*
函数功能:默认 int 类型数据转为所需的类型数据
函数参数:@dataIn:输入的数据首地址
@typeSize:类型的大小
函数返回:返回所需的类型数据
*/
static uint64_t ConvertIntByDefault(const uint8_t *dataIn, uint8_t typeSize)
{
switch (typeSize) {
case INT_8:
return *((int8_t*)dataIn); // 返回强制转型为1个字节类型数据
case INT_16:
return *((int16_t*)dataIn); // 返回强制转型为2个字节类型数据
case INT_32:
return *((int32_t*)dataIn); // 返回强制转型为4个字节类型数据
case INT_64:
return *((int64_t*)dataIn); // 返回强制转型为8个字节类型数据
default:
return 0; // 其他情况下,默认为 0
}
}
数据转换
/*
函数功能:数据的转换
函数参数:@tlvHead:tlv 结点数据
@nodeType:结点类型
@fieldSize:变量所占的字节数目
函数返回:状态码
*/
static uint64_t UnMarshallInt(const TlvNode *tlvHead, uint8_t nodeType, uint8_t fieldSize)
{
if (tlvHead == NULL) { // 链表的参数校验
return 0;
}
TlvNode* tlvNode = GetNodeByType(nodeType, tlvHead); // 通过结点的类型查找结点
if (tlvNode == NULL || tlvNode->value == NULL) { // 结点参数校验
HILOGE("[Bad node type %d]", nodeType);
return 0;
}
if (fieldSize != tlvNode->length) { // 参数校验
HILOGE("[Mismatched fieldSize=%d while nodeLength=%d]", fieldSize, tlvNode->length);
return 0;
}
// 判断是否为大端存储,是就转为小端存储,如果本来就是小端存储了,那么需要将 int 转为相应的类型数据
return IsBigEndian() ? ConvertIntByDefault(tlvNode->value, fieldSize)
: ConvertIntDataBig2Little(tlvNode->value, fieldSize);
}
uint8_t UnMarshallUint8(const TlvNode *tlvHead, uint8_t nodeType)
{
return UnMarshallInt(tlvHead, nodeType, sizeof(uint8_t)); // 将 int 类型数据转为无符号1字节数据
}
uint16_t UnMarshallUint16(const TlvNode *tlvHead, uint8_t nodeType)
{
return UnMarshallInt(tlvHead, nodeType, sizeof(uint16_t)); // 将 int 类型数据转为无符号2字节数据
}
uint32_t UnMarshallUint32(const TlvNode *tlvHead, uint8_t nodeType)
{
return UnMarshallInt(tlvHead, nodeType, sizeof(uint32_t)); // 将 int 类型数据转为无符号4字节数据
}
uint64_t UnMarshallUint64(const TlvNode *tlvHead, uint8_t nodeType)
{
return UnMarshallInt(tlvHead, nodeType, sizeof(uint64_t)); // 将 int 类型数据转为无符号8字节数据
}
int8_t UnMarshallInt8(const TlvNode *tlvHead, uint8_t nodeType)
{
return UnMarshallInt(tlvHead, nodeType, sizeof(int8_t)); // 将 int 类型数据转为有符号 1字节数据
}
int16_t UnMarshallInt16(const TlvNode *tlvHead, uint8_t nodeType)
{
return UnMarshallInt(tlvHead, nodeType, sizeof(int16_t)); // 将 int 类型数据转为有符号2字节数据
}
int32_t UnMarshallInt32(const TlvNode *tlvHead, uint8_t nodeType)
{
return UnMarshallInt(tlvHead, nodeType, sizeof(int32_t)); // 将 int 类型数据转为有符号4字节数据
}
int64_t UnMarshallInt64(const TlvNode *tlvHead, uint8_t nodeType)
{
return UnMarshallInt(tlvHead, nodeType, sizeof(int64_t)); // 将 int 类型数据转为有符号8字节数据
}
获取Tlv数据
/*
函数功能:获取 Tlv 格式数据的值
函数参数:@tlvHead:tlv 格式数据
@nodeType:结点的类型
函数返回:tlv 格式数据的字符串
*/
const char* UnMarshallString(const TlvNode *tlvHead, uint8_t nodeType)
{
HILOGI("[Get string value for node %d]", nodeType);
if (tlvHead == NULL) { // 参数校验
return "";
}
TlvNode* tlvNode = GetNodeByType(nodeType, tlvHead); // 通过结点的类型获取结点
if (tlvNode == NULL || tlvNode->value == NULL) { // 校验是否存在符合类型的 tlv 结点
HILOGE("[Bad node type %d]", nodeType);
return ""; // 出错,返回空
}
// 结点的值
const char* value = (const char*)tlvNode->value; // 强制转型
if (value[tlvNode->length - 1] != '\0') { // 字符串不已 '\0' 结尾,判定出错
HILOGE("[Non-zero ending string, length:%d, ending:%d]", tlvNode->length, value[tlvNode->length - 1]);
return ""; // 出错返回为空
} else {
return value; // 返回结点的值
}
}
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示: