Skip to content

Commit

Permalink
Unify and simplify de/serializeROSmessage processing
Browse files Browse the repository at this point in the history
For most type_id, there is no difference for serialization between array and normal field as normal field
can be treated as array_size = 1. In original code, for bool and string, there is extra check or logic for normal
but array does not. Although it is weird, this commit keep the logic intact.

Signed-off-by: jwang <jing.j.wang@intel.com>
  • Loading branch information
jwang11 committed Oct 31, 2017
1 parent 71c69ac commit 0214385
Showing 1 changed file with 124 additions and 216 deletions.
340 changes: 124 additions & 216 deletions rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/TypeSupport_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ void serialize_array(
void * field,
eprosima::fastcdr::Cdr & ser)
{
if (member->array_size_ && !member->is_upper_bound_) {
ser.serializeArray(static_cast<T *>(field), member->array_size_);
if (!member->is_array_ || (member->array_size_ && !member->is_upper_bound_)) {
ser.serializeArray(static_cast<T *>(field), member->is_array_ ? member->array_size_ : 1);
} else {
std::vector<T> & data = *reinterpret_cast<std::vector<T> *>(field);
ser << data;
Expand All @@ -223,8 +223,8 @@ void serialize_array(
void * field,
eprosima::fastcdr::Cdr & ser)
{
if (member->array_size_ && !member->is_upper_bound_) {
ser.serializeArray(static_cast<T *>(field), member->array_size_);
if (!member->is_array_ || (member->array_size_ && !member->is_upper_bound_)) {
ser.serializeArray(static_cast<T *>(field), member->is_array_ ? member->array_size_ : 1);
} else {
auto & data = *reinterpret_cast<typename GenericCArray<T>::type *>(field);
ser.serializeSequence(reinterpret_cast<T *>(data.data), data.size);
Expand Down Expand Up @@ -304,114 +304,68 @@ bool TypeSupport<MembersType>::serializeROSmessage(
for (uint32_t i = 0; i < members->member_count_; ++i) {
const auto member = members->members_ + i;
void * field = const_cast<char *>(static_cast<const char *>(ros_message)) + member->offset_;

if (!member->is_array_) {
switch (member->type_id_) {
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BOOL:
{
bool sb = false;
// don't cast to bool here because if the bool is
// uninitialized the random value can't be deserialized
if (*static_cast<uint8_t *>(field)) {sb = true;}
ser << sb;
}
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BYTE:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT8:
ser << *static_cast<uint8_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_CHAR:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT8:
ser << *static_cast<char *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT32:
ser << *static_cast<float *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT64:
ser << *static_cast<double *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT16:
ser << *static_cast<int16_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT16:
ser << *static_cast<uint16_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT32:
ser << *static_cast<int32_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT32:
ser << *static_cast<uint32_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT64:
ser << *static_cast<int64_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT64:
ser << *static_cast<uint64_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING:
{
auto && str = StringHelper<MembersType>::convert_to_std_string(field);

// Control maximum length.
if (member->string_upper_bound_ && str.length() > member->string_upper_bound_ + 1) {
throw std::runtime_error("string overcomes the maximum length");
}
ser << str;
}
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE:
{
auto sub_members = (const MembersType *)member->members_->data;
serializeROSmessage(ser, sub_members, field);
}
break;
default:
throw std::runtime_error("unknown type");
}
} else {
switch (member->type_id_) {
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BOOL:
switch (member->type_id_) {
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BOOL:
if (!member->is_array_) {
bool sb = false;
// don't cast to bool here because if the bool is
// uninitialized the random value can't be deserialized
if (*static_cast<uint8_t *>(field)) {sb = true;}
ser << sb;
} else {
serialize_array<bool>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BYTE:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT8:
serialize_array<uint8_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_CHAR:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT8:
serialize_array<char>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT32:
serialize_array<float>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT64:
serialize_array<double>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT16:
serialize_array<int16_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT16:
serialize_array<uint16_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT32:
serialize_array<int32_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT32:
serialize_array<uint32_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT64:
serialize_array<int64_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT64:
serialize_array<uint64_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING:
}
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BYTE:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT8:
serialize_array<uint8_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_CHAR:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT8:
serialize_array<char>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT32:
serialize_array<float>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT64:
serialize_array<double>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT16:
serialize_array<int16_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT16:
serialize_array<uint16_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT32:
serialize_array<int32_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT32:
serialize_array<uint32_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT64:
serialize_array<int64_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT64:
serialize_array<uint64_t>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING:
if (!member->is_array_) {
auto && str = StringHelper<MembersType>::convert_to_std_string(field);
// Control maximum length.
if (member->string_upper_bound_ && str.length() > member->string_upper_bound_ + 1) {
throw std::runtime_error("string overcomes the maximum length");
}
ser << str;
} else {
serialize_array<std::string>(member, field, ser);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE:
{
auto sub_members =
static_cast<const MembersType *>(member->members_->data);
}
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE:
{
auto sub_members = static_cast<const MembersType *>(member->members_->data);
if (!member->is_array_) {
serializeROSmessage(ser, sub_members, field);
} else {
void * subros_message = nullptr;
size_t array_size = 0;
size_t sub_members_size = sub_members->size_of_;
Expand All @@ -434,10 +388,10 @@ bool TypeSupport<MembersType>::serializeROSmessage(
subros_message = align_(max_align, subros_message);
}
}
break;
default:
throw std::runtime_error("unknown type");
}
}
break;
default:
throw std::runtime_error("unknown type");
}
}

Expand All @@ -451,8 +405,8 @@ void deserialize_array(
eprosima::fastcdr::Cdr & deser,
bool call_new)
{
if (member->array_size_ && !member->is_upper_bound_) {
deser.deserializeArray(static_cast<T *>(field), member->array_size_);
if (!member->is_array_ || (member->array_size_ && !member->is_upper_bound_)) {
deser.deserializeArray(static_cast<T *>(field), member->is_array_ ? member->array_size_ : 1);
} else {
auto & vector = *reinterpret_cast<std::vector<T> *>(field);
if (call_new) {
Expand All @@ -470,8 +424,8 @@ void deserialize_array(
bool call_new)
{
(void)call_new;
if (member->array_size_ && !member->is_upper_bound_) {
deser.deserializeArray(static_cast<T *>(field), member->array_size_);
if (!member->is_array_ || (member->array_size_ && !member->is_upper_bound_)) {
deser.deserializeArray(static_cast<T *>(field), member->is_array_ ? member->array_size_ : 1);
} else {
auto & data = *reinterpret_cast<typename GenericCArray<T>::type *>(field);
int32_t dsize = 0;
Expand Down Expand Up @@ -571,101 +525,55 @@ bool TypeSupport<MembersType>::deserializeROSmessage(
for (uint32_t i = 0; i < members->member_count_; ++i) {
const auto * member = members->members_ + i;
void * field = static_cast<char *>(ros_message) + member->offset_;

if (!member->is_array_) {
switch (member->type_id_) {
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BOOL:
deser >> *static_cast<bool *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BYTE:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT8:
deser >> *static_cast<uint8_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_CHAR:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT8:
deser >> *static_cast<char *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT32:
deser >> *static_cast<float *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT64:
deser >> *static_cast<double *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT16:
deser >> *static_cast<int16_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT16:
deser >> *static_cast<uint16_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT32:
deser >> *static_cast<int32_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT32:
deser >> *static_cast<uint32_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT64:
deser >> *static_cast<int64_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT64:
deser >> *static_cast<uint64_t *>(field);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING:
{
StringHelper<MembersType>::assign(deser, field, call_new);
}
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE:
{
auto sub_members = (const MembersType *)member->members_->data;
deserializeROSmessage(deser, sub_members, field, call_new);
}
break;
default:
throw std::runtime_error("unknown type");
}
} else {
switch (member->type_id_) {
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BOOL:
deserialize_array<bool>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BYTE:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT8:
deserialize_array<uint8_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_CHAR:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT8:
deserialize_array<char>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT32:
deserialize_array<float>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT64:
deserialize_array<double>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT16:
deserialize_array<int16_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT16:
deserialize_array<uint16_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT32:
deserialize_array<int32_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT32:
deserialize_array<uint32_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT64:
deserialize_array<int64_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT64:
deserialize_array<uint64_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING:
switch (member->type_id_) {
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BOOL:
deserialize_array<bool>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BYTE:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT8:
deserialize_array<uint8_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_CHAR:
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT8:
deserialize_array<char>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT32:
deserialize_array<float>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT64:
deserialize_array<double>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT16:
deserialize_array<int16_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT16:
deserialize_array<uint16_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT32:
deserialize_array<int32_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT32:
deserialize_array<uint32_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT64:
deserialize_array<int64_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT64:
deserialize_array<uint64_t>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING:
if (!member->is_array_) {
StringHelper<MembersType>::assign(deser, field, call_new);
} else {
deserialize_array<std::string>(member, field, deser, call_new);
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE:
{
auto sub_members = (const MembersType *)member->members_->data;
}
break;
case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE:
{
auto sub_members = (const MembersType *)member->members_->data;
if (!member->is_array_) {
deserializeROSmessage(deser, sub_members, field, call_new);
} else {
void * subros_message = nullptr;
size_t array_size = 0;
size_t sub_members_size = sub_members->size_of_;
Expand All @@ -688,10 +596,10 @@ bool TypeSupport<MembersType>::deserializeROSmessage(
subros_message = align_(max_align, subros_message);
}
}
break;
default:
throw std::runtime_error("unknown type");
}
}
break;
default:
throw std::runtime_error("unknown type");
}
}

Expand Down

0 comments on commit 0214385

Please sign in to comment.