前言
用于转换 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
}
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案)
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
数据转换
/*
函数功能:数据的转换
函数参数:@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; // 返回结点的值
}
}