Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/cdr plain strings #106

Draft
wants to merge 4 commits into
base: rolling
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ROSIDL_TYPESUPPORT_FASTRTPS_CPP__SERIALIZATION_HELPERS_HPP_
#define ROSIDL_TYPESUPPORT_FASTRTPS_CPP__SERIALIZATION_HELPERS_HPP_

#include <rosidl_typesupport_fastrtps_cpp/visibility_control.h>

#include <rosidl_runtime_cpp/cdr_compatible_fixed_capacity_string.hpp>
#include <fastcdr/Cdr.h>

#include <string>

namespace eprosima {
namespace fastcdr {

template<uint32_t Capacity>
inline eprosima::fastcdr::Cdr& operator << (
eprosima::fastcdr::Cdr& cdr, const rosidl_runtime_cpp::CDRCompatibleFixedCapacityString<Capacity>& str)
{
cdr << Capacity;
cdr.serializeArray(str.c_str(), Capacity);
return cdr;
}

template<uint32_t Capacity>
inline eprosima::fastcdr::Cdr& operator >> (
eprosima::fastcdr::Cdr& cdr, rosidl_runtime_cpp::CDRCompatibleFixedCapacityString<Capacity>& str)
{
std::string tmp_str;
cdr >> tmp_str;
str = tmp_str;
return cdr;
}

} // namespace fastcdr
} // namespace eprosima

namespace rosidl_typesupport_fastrtps_cpp {

template<typename Allocator>
inline void get_string_size(
const std::basic_string<char, std::char_traits<char>, Allocator>& str,
size_t& current_alignment)
{
const size_t padding = 4;
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
str.size() + 1;
}

template<typename Allocator>
inline void get_string_size(
const std::basic_string<char16_t, std::char_traits<char16_t>, Allocator>& str,
size_t& current_alignment)
{
const size_t padding = 4;
const size_t wchar_size = 4;

current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
wchar_size * (str.size() + 1);
}

template<uint32_t Capacity>
inline void get_string_size(
const rosidl_runtime_cpp::CDRCompatibleFixedCapacityString<Capacity>& /* str */,
size_t& current_alignment)
{
const size_t padding = 4;
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
Capacity;
}

template <typename T>
struct max_string_size_helper
{
};

template <typename Allocator>
struct max_string_size_helper<std::basic_string<char, std::char_traits<char>, Allocator> >
{
static inline void max_string_size(
bool& full_bounded,
bool& is_plain,
size_t& current_alignment,
const size_t array_size,
const size_t max_size)
{
const size_t padding = 4;

full_bounded = false;
is_plain = false;
for (size_t index = 0; index < array_size; ++index) {
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
max_size + 1;
}
}
};

template <typename Allocator>
struct max_string_size_helper<std::basic_string<char16_t, std::char_traits<char16_t>, Allocator> >
{
static inline void max_string_size(
bool& full_bounded,
bool& is_plain,
size_t& current_alignment,
const size_t array_size,
const size_t max_size)
{
const size_t padding = 4;
const size_t wchar_size = 4;

full_bounded = false;
is_plain = false;
for (size_t index = 0; index < array_size; ++index) {
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
wchar_size * (max_size + 1);
}
}
};

template<uint32_t Capacity>
struct max_string_size_helper<rosidl_runtime_cpp::CDRCompatibleFixedCapacityString<Capacity> >
{
static inline void max_string_size(
bool& /*full_bounded*/,
bool& /*is_plain*/,
size_t& current_alignment,
const size_t array_size,
const size_t /*max_size*/)
{
const size_t padding = 4;
for (size_t index = 0; index < array_size; ++index) {
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
Capacity;
}
}
};

template<typename T, std::size_t N>
struct max_string_size_helper<std::array<T, N> > : public max_string_size_helper<T>
{};

template<typename T, typename Allocator>
struct max_string_size_helper<std::vector<T, Allocator> >
{
static inline void max_string_size(
bool& full_bounded,
bool& is_plain,
size_t& current_alignment,
const size_t array_size,
const size_t max_size)
{
full_bounded = false;
is_plain = false;

max_string_size_helper<T>::max_string_size(full_bounded, is_plain, current_alignment, array_size, max_size);
}
};

template<typename T, std::size_t N, typename Allocator>
struct max_string_size_helper<rosidl_runtime_cpp::BoundedVector<T, N, Allocator> >
{
static inline void max_string_size(
bool& full_bounded,
bool& is_plain,
size_t& current_alignment,
const size_t array_size,
const size_t max_size)
{
is_plain = false;

max_string_size_helper<T>::max_string_size(full_bounded, is_plain, current_alignment, array_size, max_size);
}
};

} // namespace rosidl_typesupport_fastrtps_cpp

#endif // ROSIDL_TYPESUPPORT_FASTRTPS_CPP__SERIALIZATION_HELPERS_HPP_
43 changes: 11 additions & 32 deletions rosidl_typesupport_fastrtps_cpp/resource/msg__type_support.cpp.em
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@# Included from rosidl_typesupport_fastrtps_cpp/resource/idl__type_support.cpp.em
@{
from rosidl_generator_c import idl_structure_type_to_c_typename
from rosidl_generator_cpp import msg_type_to_cpp
from rosidl_generator_type_description import GET_DESCRIPTION_FUNC
from rosidl_generator_type_description import GET_HASH_FUNC
from rosidl_generator_type_description import GET_SOURCES_FUNC
Expand All @@ -21,6 +22,7 @@ header_files = [
'rosidl_typesupport_fastrtps_cpp/identifier.hpp',
'rosidl_typesupport_fastrtps_cpp/message_type_support.h',
'rosidl_typesupport_fastrtps_cpp/message_type_support_decl.hpp',
'rosidl_typesupport_fastrtps_cpp/serialization_helpers.hpp',
'rosidl_typesupport_fastrtps_cpp/wstring_conversion.hpp',
'fastcdr/Cdr.h',
]
Expand Down Expand Up @@ -298,9 +300,7 @@ get_serialized_size(
size_t initial_alignment = current_alignment;

const size_t padding = 4;
const size_t wchar_size = 4;
(void)padding;
(void)wchar_size;

@[for member in message.structure.members]@
// Member: @(member.name)
Expand All @@ -321,12 +321,8 @@ get_serialized_size(
@[ end if]@
@[ if isinstance(member.type.value_type, AbstractGenericString)]@
for (size_t index = 0; index < array_size; ++index) {
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
@[ if isinstance(member.type.value_type, AbstractWString)]@
wchar_size *
@[ end if]@
(ros_message.@(member.name)[index].size() + 1);
rosidl_typesupport_fastrtps_cpp::get_string_size(
ros_message.@(member.name)[index], current_alignment);
}
@[ elif isinstance(member.type.value_type, BasicType)]@
size_t item_size = sizeof(ros_message.@(member.name)[0]);
Expand All @@ -342,12 +338,8 @@ get_serialized_size(
}
@[ else]@
@[ if isinstance(member.type, AbstractGenericString)]@
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
@[ if isinstance(member.type, AbstractWString)]@
wchar_size *
@[ end if]@
(ros_message.@(member.name).size() + 1);
rosidl_typesupport_fastrtps_cpp::get_string_size(
ros_message.@(member.name), current_alignment);
@[ elif isinstance(member.type, BasicType)]@
{
size_t item_size = sizeof(ros_message.@(member.name));
Expand Down Expand Up @@ -375,9 +367,7 @@ max_serialized_size_@(message.structure.namespaced_type.name)(
size_t initial_alignment = current_alignment;

const size_t padding = 4;
const size_t wchar_size = 4;
(void)padding;
(void)wchar_size;

full_bounded = true;
is_plain = true;
Expand Down Expand Up @@ -410,22 +400,11 @@ if isinstance(type_, AbstractNestedType):
type_ = type_.value_type
}@
@[ if isinstance(type_, AbstractGenericString)]@
full_bounded = false;
is_plain = false;
for (size_t index = 0; index < array_size; ++index) {
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
@[ if type_.has_maximum_size()]@
@[ if isinstance(type_, AbstractWString)]@
wchar_size *
@[ end if]@
@(type_.maximum_size) +
@[ end if]@
@[ if isinstance(type_, AbstractWString)]@
wchar_size *
@[ end if]@
1;
}
rosidl_typesupport_fastrtps_cpp::max_string_size_helper<
decltype(@('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name] + [member.name])))>
::max_string_size(
full_bounded, is_plain, current_alignment, array_size,
@(type_.has_maximum_size() ? type_.maximum_size : 0));
@[ elif isinstance(type_, BasicType)]@
@[ if type_.typename in ('boolean', 'octet', 'char', 'uint8', 'int8')]@
current_alignment += array_size * sizeof(uint8_t);
Expand Down