CARLA
 
载入中...
搜索中...
未找到
TransformStampedPubSubTypes.cpp
浏览该文件的文档.
1#include <fastcdr/FastBuffer.h>
2#include <fastcdr/Cdr.h>
3
5
6// 使用类型别名,将eprosima::fastrtps::rtps::SerializedPayload_t简化为SerializedPayload_t,方便后续代码书写和阅读
7using SerializedPayload_t = eprosima::fastrtps::rtps::SerializedPayload_t;
8// 使用类型别名,将eprosima::fastrtps::rtps::InstanceHandle_t简化为InstanceHandle_t
9using InstanceHandle_t = eprosima::fastrtps::rtps::InstanceHandle_t;
10
11namespace geometry_msgs {
12 namespace msg {
13 // TransformStampedPubSubType类的构造函数定义
15 {
16 // 设置该类型的名称,此处设置为"geometry_msgs::msg::dds_::TransformStamped_",可能用于标识该类型在系统中的唯一性等用途
17 setName("geometry_msgs::msg::dds_::TransformStamped_");
18
19 // 获取TransformStamped类型能够达到的最大CDR序列化大小,CDR可能是一种特定的数据序列化格式
21 // 对获取到的类型大小进行字节对齐操作,以满足可能的子消息对齐要求(按4字节对齐),确保数据存储符合某种规范,便于后续处理
22 type_size += eprosima::fastcdr::Cdr::alignment(type_size, 4); /* possible submessage alignment */
23 // 计算最终的类型大小,额外加上4字节,可能是用于封装(encapsulation)相关的数据开销,比如添加一些头部等信息来包裹实际序列化的数据
24 m_typeSize = static_cast<uint32_t>(type_size) + 4; /*encapsulation*/
25
26 // 判断TransformStamped类型是否定义了获取键(key)的相关操作,将结果赋值给成员变量m_isGetKeyDefined,后续在获取键的操作中可能会依据这个变量来判断是否能执行相应逻辑
27 m_isGetKeyDefined = TransformStamped::isKeyDefined();
28
29 // 根据TransformStamped类型获取最大键(key)的CDR序列化大小来确定用于存储键数据的缓冲区大小
30 // 如果获取到的最大键序列化大小大于16字节,就使用实际的最大键序列化大小作为缓冲区大小,否则使用16字节作为缓冲区大小
31 size_t keyLength = TransformStamped::getKeyMaxCdrSerializedSize() > 16?
33 // 通过malloc动态分配内存来创建用于存储键数据的缓冲区,将分配的内存地址转换为无符号字符指针(unsigned char*)后赋值给m_keyBuffer成员变量
34 m_keyBuffer = reinterpret_cast<unsigned char*>(malloc(keyLength));
35 // 使用memset将刚分配的缓冲区内存初始化为0,确保缓冲区中的数据初始状态是已知且干净的
36 memset(m_keyBuffer, 0, keyLength);
37 }
38
39 // TransformStampedPubSubType类的析构函数定义,用于释放构造函数中动态分配的内存资源
41 {
42 // 判断m_keyBuffer指针是否为空,如果不为空,说明之前有分配内存,需要调用free函数来释放该内存,避免内存泄漏
43 if (m_keyBuffer!= nullptr)
44 {
45 free(m_keyBuffer);
46 }
47 }
48
49 // 用于将给定的数据对象序列化到SerializedPayload_t结构中的函数
51 void* data,
52 SerializedPayload_t* payload)
53 {
54 // 将传入的void*类型数据指针转换为TransformStamped*类型指针,方便后续操作,假设传入的数据实际就是TransformStamped类型的对象
55 TransformStamped* p_type = static_cast<TransformStamped*>(data);
56
57 // 创建一个FastBuffer对象,用于管理原始缓冲区,它包装了payload->data所指向的内存区域,并且指定了该缓冲区的最大可用大小为payload->max_size
58 // 这个FastBuffer对象可能提供了一些方便的缓冲区操作接口,供后续序列化操作使用
59 eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload->data), payload->max_size);
60 // 创建一个Cdr对象,用于执行实际的数据序列化操作
61 // 传入刚刚创建的FastBuffer对象作为底层数据存储,指定默认字节序(DEFAULT_ENDIAN)以及DDS_CDR模式(可能是与DDS相关的特定CDR序列化模式)
62 eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, eprosima::fastcdr::Cdr::DDS_CDR);
63 // 根据Cdr对象当前的字节序设置SerializedPayload_t结构中的封装(encapsulation)字段,表示数据是大端序(BIG_ENDIANNESS)还是小端序(LITTLE_ENDIANNESS)
64 payload->encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS? CDR_BE : CDR_LE;
65 // 调用Cdr对象的serialize_encapsulation函数,执行封装相关的数据序列化操作,可能是写入一些头部等用于标识序列化格式、字节序等信息
66 ser.serialize_encapsulation();
67
68 try
69 {
70 // 调用TransformStamped对象的serialize函数,通过传入的Cdr对象ser,将该对象自身的数据序列化到之前创建的FastBuffer所管理的缓冲区中
71 p_type->serialize(ser);
72 }
73 catch (eprosima::fastcdr::exception::NotEnoughMemoryException& /*exception*/)
74 {
75 // 如果在序列化过程中出现内存不足的异常情况,直接返回false,表示序列化失败
76 return false;
77 }
78
79 // 获取已经序列化的数据的实际长度,通过Cdr对象的getSerializedDataLength函数获取,并将其赋值给SerializedPayload_t结构中的length字段,用于记录实际序列化后的数据长度
80 payload->length = static_cast<uint32_t>(ser.getSerializedDataLength());
81 // 如果序列化过程没有出现异常且顺利完成,返回true表示序列化成功
82 return true;
83 }
84
85 // 用于将SerializedPayload_t结构中的数据反序列化到指定的数据对象中的函数
87 SerializedPayload_t* payload,
88 void* data)
89 {
90 try
91 {
92 // 将传入的void*类型数据指针转换为TransformStamped*类型指针,以便后续按照TransformStamped类型来进行反序列化操作,假设传入的数据接收对象就是该类型
93 TransformStamped* p_type = static_cast<TransformStamped*>(data);
94
95 // 创建一个FastBuffer对象,用于管理原始缓冲区,它包装了payload->data所指向的内存区域,并且指定了该缓冲区的可用大小为payload->length(即实际接收到的序列化数据的长度)
96 eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload->data), payload->length);
97 // 创建一个Cdr对象,用于执行实际的数据反序列化操作
98 // 传入刚刚创建的FastBuffer对象作为底层数据存储,指定默认字节序(DEFAULT_ENDIAN)以及DDS_CDR模式(与序列化时相对应的特定模式)
99 eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, eprosima::fastcdr::Cdr::DDS_CDR);
100
101 // 调用Cdr对象的read_encapsulation函数,执行反序列化中与封装相关的操作,比如读取并解析之前序列化时写入的头部等标识信息,以获取字节序等相关信息
102 deser.read_encapsulation();
103 // 根据Cdr对象当前解析出的字节序设置SerializedPayload_t结构中的封装(encapsulation)字段,与序列化时的处理相对应
104 payload->encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS? CDR_BE : CDR_LE;
105
106 // 调用TransformStamped对象的deserialize函数,通过传入的Cdr对象deser,将FastBuffer中存储的序列化数据反序列化为该对象自身的数据
107 p_type->deserialize(deser);
108 }
109 catch (eprosima::fastcdr::exception::NotEnoughMemoryException& /*exception*/)
110 {
111 // 如果在反序列化过程中出现内存不足的异常情况,直接返回false,表示反序列化失败
112 return false;
113 }
114
115 // 如果反序列化过程没有出现异常且顺利完成,返回true表示反序列化成功
116 return true;
117 }
118
119 // 返回一个函数对象,该函数对象用于获取给定数据对象序列化后的大小(包含封装等开销)
121 void* data)
122 {
123 return [data]() -> uint32_t
124 {
125 // 先获取TransformStamped类型对象的CDR序列化大小(不包含封装开销),再加上4字节的封装开销,返回最终的序列化后大小
126 return static_cast<uint32_t>(type::getCdrSerializedSize(*static_cast<TransformStamped*>(data))) +
127 4u /*encapsulation*/;
128 };
129 }
130
131 // 创建一个新的TransformStamped类型的数据对象,并返回其void*类型的指针,用于后续操作,比如作为要序列化的数据对象等
133 {
134 return reinterpret_cast<void*>(new TransformStamped());
135 }
136
137 // 用于删除通过createData函数创建的TransformStamped类型的数据对象,释放其占用的内存资源,避免内存泄漏
139 void* data)
140 {
141 delete(reinterpret_cast<TransformStamped*>(data));
142 }
143
144 // 用于获取给定数据对象对应的键(key)信息,并填充到InstanceHandle_t结构中的函数
146 void* data,
147 InstanceHandle_t* handle,
148 bool force_md5)
149 {
150 // 如果之前判断TransformStamped类型没有定义获取键的操作(m_isGetKeyDefined为false),则直接返回false,表示无法获取键信息
151 if (!m_isGetKeyDefined)
152 {
153 return false;
154 }
155
156 // 将传入的void*类型数据指针转换为TransformStamped*类型指针,方便后续按照该类型来获取键相关的操作
157 TransformStamped* p_type = static_cast<TransformStamped*>(data);
158
159 // 创建一个FastBuffer对象,用于管理原始缓冲区,它包装了m_keyBuffer所指向的内存区域,并且指定了该缓冲区的大小为TransformStamped类型获取最大键的CDR序列化大小
160 eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(m_keyBuffer),
162
163 // 创建一个Cdr对象,用于执行将键数据序列化到FastBuffer所管理的缓冲区中的操作,这里指定了大端序(BIG_ENDIANNESS)
164 eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS);
165 // 调用TransformStamped对象的serializeKey函数,通过传入的Cdr对象ser,将该对象的键数据序列化到FastBuffer所管理的缓冲区中
166 p_type->serializeKey(ser);
167
168 // 如果force_md5为true(可能是强制使用MD5算法处理键数据的情况)或者TransformStamped类型获取的最大键的CDR序列化大小大于16字节
169 if (force_md5 || TransformStamped::getKeyMaxCdrSerializedSize() > 16)
170 {
171 // 初始化MD5相关的操作对象(可能是用于计算MD5哈希值的类实例)
172 m_md5.init();
173 // 使用MD5操作对象更新要计算哈希值的数据范围,传入m_keyBuffer指针以及已经序列化的键数据的实际长度
174 m_md5.update(m_keyBuffer, static_cast<unsigned int>(ser.getSerializedDataLength()));
175 // 完成MD5哈希值的计算
176 m_md5.finalize();
177 // 将计算得到的MD5哈希值的每一个字节依次赋值给InstanceHandle_t结构中的value数组,用于后续通过键来标识或查找等操作
178 for (uint8_t i = 0; i < 16; ++i)
179 {
180 handle->value[i] = m_md5.digest[i];
181 }
182 }
183 else
184 {
185 // 如果不需要使用MD5算法处理键数据且键数据长度小于等于16字节,直接将缓冲区中的键数据逐字节赋值给InstanceHandle_t结构中的value数组
186 for (uint8_t i = 0; i < 16; ++i)
187 {
188 handle->value[i] = m_keyBuffer[i];
189 }
190 }
191 // 如果键获取及相关处理操作成功完成,返回true表示获取键信息成功
192 return true;
193 }
194 }
195}
eprosima::fastrtps::rtps::InstanceHandle_t InstanceHandle_t
eprosima::fastrtps::rtps::SerializedPayload_t SerializedPayload_t
virtual eProsima_user_DllExport void deleteData(void *data) override
virtual eProsima_user_DllExport bool getKey(void *data, eprosima::fastrtps::rtps::InstanceHandle_t *ihandle, bool force_md5=false) override
virtual eProsima_user_DllExport std::function< uint32_t()> getSerializedSizeProvider(void *data) override
virtual eProsima_user_DllExport bool serialize(void *data, eprosima::fastrtps::rtps::SerializedPayload_t *payload) override
virtual eProsima_user_DllExport bool deserialize(eprosima::fastrtps::rtps::SerializedPayload_t *payload, void *data) override
virtual eProsima_user_DllExport void * createData() override
virtual eProsima_user_DllExport ~TransformStampedPubSubType() override
此类表示用户在 IDL 文件中定义的 TransformStamped 结构。 <>
static eProsima_user_DllExport size_t getKeyMaxCdrSerializedSize(size_t current_alignment=0)
此函数返回对象键的最大序列化尺寸,取决于缓冲区对齐。
static eProsima_user_DllExport size_t getCdrSerializedSize(const geometry_msgs::msg::TransformStamped &data, size_t current_alignment=0)
此函数返回数据的序列化尺寸,取决于缓冲区对齐。
static eProsima_user_DllExport size_t getMaxCdrSerializedSize(size_t current_alignment=0)
此函数返回对象的最大序列化尺寸,取决于缓冲区对齐。
eProsima_user_DllExport void deserialize(eprosima::fastcdr::Cdr &cdr)
此函数使用 CDR 序列化对象反序列化对象。
eProsima_user_DllExport void serialize(eprosima::fastcdr::Cdr &cdr) const
此函数使用 CDR 序列化对象序列化对象。
static eProsima_user_DllExport bool isKeyDefined()
此函数告知您是否已为此类型定义键。
eProsima_user_DllExport void serializeKey(eprosima::fastcdr::Cdr &cdr) const
此函数使用 CDR 序列化对象序列化对象的键成员。