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

Implement resize function for String #806

Merged
merged 4 commits into from
Apr 30, 2024
Merged
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
14 changes: 14 additions & 0 deletions rosidl_runtime_c/include/rosidl_runtime_c/string_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@ bool
rosidl_runtime_c__String__assign(
rosidl_runtime_c__String * str, const char * value);

/// Resize the char pointer.
/**
* This function resize the input value pointer.
*
* \param[inout] str a pointer to a rosidl_runtime_c__String structure
* \param[in] n the new size of the internal buffer
* \return true if successful, false if the passed string pointer is null
* or if the size is higher than SIZE_MAX or if the memory reallocation failed.
*/
ROSIDL_GENERATOR_C_PUBLIC
bool
rosidl_runtime_c__String__resize(
rosidl_runtime_c__String * str, size_t n);

/// Initialize a rosidl_runtime_c__String__Sequence__init structure.
/**
* The rosidl_runtime_c__String__Sequence is initialized with the size passed to the function.
Expand Down
23 changes: 23 additions & 0 deletions rosidl_runtime_c/src/string_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,29 @@ rosidl_runtime_c__String__copy(
output, input->data, input->size);
}

bool
rosidl_runtime_c__String__resize(
rosidl_runtime_c__String *str, size_t n)
{
if(!str) {
return false;
}
// check valid range of n before allocating n + 1 characters
if(n > SIZE_MAX / sizeof(char) - 1) {
return false;
}
rcutils_allocator_t allocator = rcutils_get_default_allocator();
char * data = allocator.reallocate(str->data, (n + 1) * sizeof(char), allocator.state);
if(!data) {
return false;
}
data[n] = 0;
str->data = data;
str->size = n;
str->capacity = n + 1;
return true;
}

bool
rosidl_runtime_c__String__Sequence__init(
rosidl_runtime_c__String__Sequence * sequence, size_t size)
Expand Down
12 changes: 12 additions & 0 deletions rosidl_runtime_c/test/test_string_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ TEST(string_functions, resize_assignn) {
EXPECT_TRUE(rosidl_runtime_c__String__init(&s));
EXPECT_TRUE(rosidl_runtime_c__String__init(&t));

EXPECT_FALSE(rosidl_runtime_c__String__resize(nullptr, s_size));

// If you're here because this test crashed your computer, it might be because it just tried
// to allocate SIZE_MAX * 2 bytes, which means someone removed an important check.
EXPECT_FALSE(rosidl_runtime_c__String__resize(nullptr, SIZE_MAX * 2));

EXPECT_TRUE(rosidl_runtime_c__String__resize(&s, s_size));
EXPECT_EQ(s.size, s_size);
EXPECT_EQ(s.capacity, s_size + 1u);
EXPECT_NE(s.data, nullptr);
EXPECT_EQ(s.data[s_size], 0);

EXPECT_FALSE(rosidl_runtime_c__String__assign(nullptr, nullptr));
EXPECT_FALSE(rosidl_runtime_c__String__assignn(nullptr, nullptr, 0));
EXPECT_FALSE(rosidl_runtime_c__String__assignn(&s, nullptr, 0));
Expand Down
Loading