📌往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)

📃 鸿蒙(HarmonyOS)北向开发知识点记录~

📃 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

📃 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

📃 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

📃 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

📃 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

📃 记录一场鸿蒙开发岗位面试经历~

📃 持续更新中……


前言

用于转换 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;  // 返回结点的值
    }
}

在这里插入图片描述

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐