Skip to content

Commit

Permalink
add WString support (#22)
Browse files Browse the repository at this point in the history
* add WString support

Signed-off-by: Dirk Thomas <dirk-thomas@users.noreply.github.com>

* fix type of string literal

Signed-off-by: Dirk Thomas <dirk-thomas@users.noreply.github.com>

* check wstring_to_u16_string function

Signed-off-by: Dirk Thomas <dirk-thomas@users.noreply.github.com>

* fix style

Signed-off-by: Dirk Thomas <dirk-thomas@users.noreply.github.com>

* fix dll linkage warnings

Signed-off-by: Dirk Thomas <dirk-thomas@users.noreply.github.com>
  • Loading branch information
dirk-thomas authored May 2, 2019
1 parent 94555d8 commit de8aa3f
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 30 deletions.
4 changes: 3 additions & 1 deletion rosidl_typesupport_fastrtps_c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ ament_export_include_directories(include)

ament_python_install_package(${PROJECT_NAME})

add_library(${PROJECT_NAME} SHARED src/identifier.cpp)
add_library(${PROJECT_NAME} SHARED
src/identifier.cpp
src/wstring_conversion.cpp)
if(WIN32)
target_compile_definitions(${PROJECT_NAME}
PRIVATE "ROSIDL_TYPESUPPORT_FASTRTPS_C_BUILDING_DLL")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// 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_C__WSTRING_CONVERSION_HPP_
#define ROSIDL_TYPESUPPORT_FASTRTPS_C__WSTRING_CONVERSION_HPP_

#include <string>

#include "rosidl_generator_c/u16string.h"
#include "rosidl_typesupport_fastrtps_c/visibility_control.h"

namespace rosidl_typesupport_fastrtps_c
{

ROSIDL_TYPESUPPORT_FASTRTPS_C_PUBLIC
void u16string_to_wstring(
const rosidl_generator_c__U16String & u16str, std::wstring & wstr);

ROSIDL_TYPESUPPORT_FASTRTPS_C_PUBLIC
bool wstring_to_u16string(
const std::wstring & wstr, rosidl_generator_c__U16String & u16str);

} // namespace rosidl_typesupport_fastrtps_c

#endif // ROSIDL_TYPESUPPORT_FASTRTPS_C__WSTRING_CONVERSION_HPP_
86 changes: 67 additions & 19 deletions rosidl_typesupport_fastrtps_c/resource/msg__type_support_c.cpp.em
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ header_files = [
'string',
# Provides the rosidl_typesupport_fastrtps_c__identifier symbol declaration.
'rosidl_typesupport_fastrtps_c/identifier.h',
'rosidl_typesupport_fastrtps_c/wstring_conversion.hpp',
# Provides the definition of the message_type_support_callbacks_t struct.
'rosidl_typesupport_fastrtps_cpp/message_type_support.h',
package_name + '/msg/rosidl_typesupport_fastrtps_c__visibility_control.h',
Expand Down Expand Up @@ -197,6 +198,21 @@ if isinstance(type_, AbstractNestedType):
}
cdr << str->data;
}
@[ elif isinstance(member.type.value_type, AbstractWString)]@
std::wstring wstr;
for (size_t i = 0; i < size; ++i) {
const rosidl_generator_c__U16String * str = &array_ptr[i];
if (str->capacity == 0 || str->capacity <= str->size) {
fprintf(stderr, "string capacity not greater than size\n");
return false;
}
if (str->data[str->size] != u'\0') {
fprintf(stderr, "string not null-terminated\n");
return false;
}
rosidl_typesupport_fastrtps_c::u16string_to_wstring(*str, wstr);
cdr << wstr;
}
@[ elif isinstance(member.type.value_type, BasicType)]@
cdr.serializeArray(array_ptr, size);
@[ else]@
Expand All @@ -219,6 +235,10 @@ if isinstance(type_, AbstractNestedType):
return false;
}
cdr << str->data;
@[ elif isinstance(member.type, AbstractWString)]@
std::wstring wstr;
rosidl_typesupport_fastrtps_c::u16string_to_wstring(ros_message->@(member.name), wstr);
cdr << wstr;
@[ elif isinstance(member.type, BasicType) and member.type.typename == 'boolean']@
cdr << (ros_message->@(member.name) ? true : false);
@[ elif isinstance(member.type, BasicType)]@
Expand Down Expand Up @@ -291,26 +311,37 @@ else:
}
auto array_ptr = ros_message->@(member.name).data;
@[ end if]@
@[ if isinstance(member.type.value_type, AbstractGenericString)]@
@{
string_type = 'std::string' if isinstance(member.type.value_type, AbstractString) else 'std::u16string'
string_typename = 'rosidl_generator_c__String' if isinstance(member.type.value_type, AbstractString) else 'rosidl_generator_c__U16string'
}@
@[ if isinstance(member.type.value_type, AbstractString)]@
for (size_t i = 0; i < size; ++i) {
@(string_type) tmp;
std::string tmp;
cdr >> tmp;
auto & ros_i = array_ptr[i];
if (!ros_i.data) {
@(string_typename)__init(&ros_i);
rosidl_generator_c__String__init(&ros_i);
}
bool succeeded = @(string_typename)__assign(
bool succeeded = rosidl_generator_c__String__assign(
&ros_i,
tmp.c_str());
if (!succeeded) {
fprintf(stderr, "failed to assign string into field '@(member.name)'\n");
return false;
}
}
@[ elif isinstance(member.type.value_type, AbstractWString)]@
std::wstring wstr;
for (size_t i = 0; i < size; ++i) {
auto & ros_i = array_ptr[i];
if (!ros_i.data) {
rosidl_generator_c__U16String__init(&ros_i);
}
cdr >> wstr;
bool succeeded = rosidl_typesupport_fastrtps_c::wstring_to_u16string(wstr, ros_i);
if (!succeeded) {
fprintf(stderr, "failed to create wstring from u16string\n");
rosidl_generator_c__U16String__fini(&ros_i);
return false;
}
}
@[ elif isinstance(member.type.value_type, BasicType)]@
cdr.deserializeArray(array_ptr, size);
@[ else]@
Expand All @@ -322,23 +353,31 @@ string_typename = 'rosidl_generator_c__String' if isinstance(member.type.value_t
}
}
@[ end if]@
@[ elif isinstance(member.type, AbstractGenericString)]@
@{
string_type = 'std::string' if isinstance(member.type, AbstractString) else 'std::u16string'
string_typename = 'rosidl_generator_c__String' if isinstance(member.type, AbstractString) else 'rosidl_generator_c__U16string'
}@
@(string_type) tmp;
@[ elif isinstance(member.type, AbstractString)]@
std::string tmp;
cdr >> tmp;
if (!ros_message->@(member.name).data) {
@(string_typename)__init(&ros_message->@(member.name));
rosidl_generator_c__String__init(&ros_message->@(member.name));
}
bool succeeded = @(string_typename)__assign(
bool succeeded = rosidl_generator_c__String__assign(
&ros_message->@(member.name),
tmp.c_str());
if (!succeeded) {
fprintf(stderr, "failed to assign string into field '@(member.name)'\n");
return false;
}
@[ elif isinstance(member.type, AbstractWString)]@
if (!ros_message->@(member.name).data) {
rosidl_generator_c__U16String__init(&ros_message->@(member.name));
}
std::wstring wstr;
cdr >> wstr;
bool succeeded = rosidl_typesupport_fastrtps_c::wstring_to_u16string(wstr, ros_message->@(member.name));
if (!succeeded) {
fprintf(stderr, "failed to create wstring from u16string\n");
rosidl_generator_c__U16String__fini(&ros_message->@(member.name));
return false;
}
@[ elif isinstance(member.type, BasicType)]@
cdr >> ros_message->@(member.name);
@[ else]@
Expand Down Expand Up @@ -379,10 +418,13 @@ size_t get_serialized_size_@('__'.join([package_name] + list(interface_path.pare
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding);
@[ end if]@
@[ if isinstance(member.type.value_type, AbstractString)]@
@[ 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)]@
2 *
@[ end if]@
array_ptr[index].size + 1;
}
@[ elif isinstance(member.type.value_type, BasicType)]@
Expand All @@ -398,9 +440,12 @@ size_t get_serialized_size_@('__'.join([package_name] + list(interface_path.pare
@[ end if]@
}
@[ else]@
@[ if isinstance(member.type, AbstractString)]@
@[ if isinstance(member.type, AbstractGenericString)]@
current_alignment += padding +
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
@[ if isinstance(member.type, AbstractWString)]@
2 *
@[ end if]@
ros_message->@(member.name).size + 1;
@[ elif isinstance(member.type, BasicType)]@
{
Expand Down Expand Up @@ -461,12 +506,15 @@ type_ = member.type
if isinstance(type_, AbstractNestedType):
type_ = type_.value_type
}@
@[ if isinstance(type_, AbstractString)]@
@[ if isinstance(type_, AbstractGenericString)]@
full_bounded = false;
for (size_t index = 0; index < array_size; ++index) {
current_alignment += padding +
@[ if type_.has_maximum_size()]@
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) +
@[ if isinstance(type_, AbstractWString)]@
2 *
@[ end if]@
@(type_.maximum_size) + 1;

This comment has been minimized.

Copy link
@sloretz

sloretz May 4, 2019

Contributor

@dirk-thomas This might need parenthesis to be 2 * (@(type_.maximum_size) + 1) because NULL at the end is an extra code point instead of just 1 byte. same in a few other places

This comment has been minimized.

Copy link
@sloretz

sloretz May 4, 2019

Contributor

Ah nevermind, didn't see #23

@[ else]@
eprosima::fastcdr::Cdr::alignment(current_alignment, padding) + 1;
Expand Down
42 changes: 42 additions & 0 deletions rosidl_typesupport_fastrtps_c/src/wstring_conversion.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// 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.

#include <rosidl_typesupport_fastrtps_c/wstring_conversion.hpp>

#include "rosidl_generator_c/u16string_functions.h"

namespace rosidl_typesupport_fastrtps_c
{

void u16string_to_wstring(const rosidl_generator_c__U16String & u16str, std::wstring & wstr)
{
wstr.resize(u16str.size);
for (size_t i = 0; i < u16str.size; ++i) {
wstr[i] = static_cast<wchar_t>(u16str.data[i]);
}
}

bool wstring_to_u16string(const std::wstring & wstr, rosidl_generator_c__U16String & u16str)
{
bool succeeded = rosidl_generator_c__U16String__resize(&u16str, wstr.size());
if (!succeeded) {
return false;
}
for (size_t i = 0; i < wstr.size(); ++i) {
u16str.data[i] = static_cast<char16_t>(wstr[i]);
}
return true;
}

} // namespace rosidl_typesupport_fastrtps_c
4 changes: 3 additions & 1 deletion rosidl_typesupport_fastrtps_cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ ament_export_include_directories(include)

ament_python_install_package(${PROJECT_NAME})

add_library(${PROJECT_NAME} SHARED src/identifier.cpp)
add_library(${PROJECT_NAME} SHARED
src/identifier.cpp
src/wstring_conversion.cpp)
if(WIN32)
target_compile_definitions(${PROJECT_NAME}
PRIVATE "ROSIDL_TYPESUPPORT_FASTRTPS_CPP_BUILDING_DLL")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// 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__WSTRING_CONVERSION_HPP_
#define ROSIDL_TYPESUPPORT_FASTRTPS_CPP__WSTRING_CONVERSION_HPP_

#include <rosidl_typesupport_fastrtps_cpp/visibility_control.h>

#include <string>

namespace rosidl_typesupport_fastrtps_cpp
{

ROSIDL_TYPESUPPORT_FASTRTPS_CPP_PUBLIC
void u16string_to_wstring(const std::u16string & u16str, std::wstring & wstr);

ROSIDL_TYPESUPPORT_FASTRTPS_CPP_PUBLIC
bool wstring_to_u16string(const std::wstring & wstr, std::u16string & u16str);

} // namespace rosidl_typesupport_fastrtps_cpp

#endif // ROSIDL_TYPESUPPORT_FASTRTPS_CPP__WSTRING_CONVERSION_HPP_
Loading

0 comments on commit de8aa3f

Please sign in to comment.