Data 精确类型
头文件:<dlt698/model/data.hpp>,命名空间 dlt698::model。
为什么是 variant 而不是泛型值
Data 用 std::variant 保存协议数据,每个标签对应一个独立的 C++ 类型。这样做的直接后果是:UInt16、Enum、array/structure 和字节串在类型层面就不可能混淆,编译器会拦住把一个当成另一个用的代码。
构造:
访问:
as<T>() 在 payload 不是 T 时抛 std::bad_variant_access。跨异步边界或需要长期保存时,请按值取出再持有,不要长期保存 as<T>() 返回的引用。
DataType
枚举值与线上标签一致。
已实现的标签覆盖和逐项测试状态见协议覆盖范围。保留或未知标签返回 unsupported_tag,不会猜测长度后跳过。
基本包装类型
Value 的 operator== 只比较存储值;标签由类型系统保证,不需要运行时再比一次。
容器类型
Array 和 Structure 存储形式相同但标签独立,比较时递归比较子节点。BitString 的有效位从每个字节的高位开始,末字节未使用的低位必须为零,解码时会检查填充位。
描述符类型
Oad::attribute保存整个线字节,包括特征位。不要自己把特征位剥掉再拼回去。ServerAddress::bytes和Tsa按线序保存,地址的低有效字节在前。ScalerUnit只保存倍率和单位,工程值换算由调用方完成,库不隐含单位语义。Ti不做单位换算,比较只比字段本身。
Tsa 的内容包含地址描述字节和地址字节,不包含 A-XDR 外层长度。
Oad 的三层含义(OI、属性标识、元素索引)如何共同定位一个测点,见对象模型与测点寻址。
RecordData
记录类查询的描述符(ROAD、Region、RSD、CSD、MS、RCSD)用 RecordData 保存:
它是不可变、拥有内存的节点,用于打断 Data 与 Rsd/Region 之间的递归定义循环。复制会共享不可变内容,不能经别名修改快照。as<T>() 在类型不符或对象已被移动时抛 std::bad_variant_access。
相等比较
operator== 比较协议类型和内容,容器类型递归比较子节点。浮点值遵循 C++ 浮点比较语义——NaN != NaN,Float32 的比较不会做特殊处理。需要业务上的"数值相等"时,请自己先取出数值再比。