Skip to content

Commit 32d7a75

Browse files
authored
feat: add opt-in strict bool normalization (#315) (#319)
Signed-off-by: Mirko Morati <mirkomorati@gmail.com>
1 parent d0e1c87 commit 32d7a75

12 files changed

Lines changed: 622 additions & 57 deletions

File tree

.github/workflows/reusable-ci.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,13 @@ jobs:
6868
matrix:
6969
cmake-build-type:
7070
- 'RelWithDebInfo'
71+
strict-bool:
72+
- false
73+
- true
7174

7275
steps:
7376
- name: Add ci-pending label if PR
74-
if: ${{ github.event_name == 'pull_request' && inputs.add-label == true}}
77+
if: ${{ github.event_name == 'pull_request' && inputs.add-label == true && matrix.strict-bool == false }}
7578
uses: eProsima/eProsima-CI/external/add_labels@v0
7679
with:
7780
labels: ci-pending
@@ -122,7 +125,7 @@ jobs:
122125
colcon_meta_file: ${{ github.workspace }}/src/fastcdr/.github/workflows/config/build.meta
123126
colcon_build_args: ${{ inputs.colcon-args }}
124127
colcon_build_args_default: --event-handlers=console_direct+
125-
cmake_args: ${{ inputs.cmake-args }}
128+
cmake_args: ${{ inputs.cmake-args }} ${{ matrix.strict-bool == true && '-DSTRICT_BOOL=ON' || '' }}
126129
cmake_args_default: ${{ env.colcon-build-default-cmake-args }} ${{ env.toolset }}
127130
cmake_build_type: ${{ matrix.cmake-build-type }}
128131
workspace: ${{ github.workspace }}
@@ -137,7 +140,7 @@ jobs:
137140
ctest_args: ${{ inputs.ctest-args }}
138141
packages_names: fastcdr
139142
workspace: ${{ github.workspace }}
140-
test_report_artifact: ${{ inputs.label }}
143+
test_report_artifact: ${{ inputs.label }}${{ matrix.strict-bool == true && '-strict-bool' || '' }}
141144

142145
- name: Fast CDR Test summary
143146
uses: eProsima/eProsima-CI/multiplatform/junit_summary@v0
@@ -153,5 +156,5 @@ jobs:
153156
if: always()
154157
uses: eProsima/eProsima-CI/external/upload-artifact@v0
155158
with:
156-
name: test-results-${{ inputs.label }}
159+
name: test-results-${{ inputs.label }}${{ matrix.strict-bool == true && '-strict-bool' || '' }}
157160
path: log/latest_test/fastcdr

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ endif()
6363
# unless the library was explicitly added as a static library.
6464
option(BUILD_SHARED_LIBS "Create shared libraries by default" ON)
6565

66+
###############################################################################
67+
# Strict bool
68+
###############################################################################
69+
option(STRICT_BOOL "Enforce bool values to 0/1 during serialization" OFF)
70+
6671
###############################################################################
6772
# Test system configuration
6873
###############################################################################

include/fastcdr/Cdr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3007,6 +3007,16 @@ class Cdr
30073007
std::wstring*& sequence_t,
30083008
size_t& num_elements);
30093009

3010+
/*!
3011+
* @brief Serializes the canonical @c uint8_t representation of @p bool_t.
3012+
*
3013+
* When @c FASTCDR_STRICT_BOOL is defined the serialized value is guaranteed to be exactly @c 0 or @c 1.
3014+
*
3015+
* @param[in] bool_t The boolean value to serialize.
3016+
*/
3017+
Cdr_DllAPI void serialize_bool(
3018+
bool bool_t);
3019+
30103020
/*!
30113021
* @brief This function template detects the content type of the STD container array and serializes the array.
30123022
* @param array_t The array that will be serialized in the buffer.

include/fastcdr/FastCdr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,6 +2041,16 @@ class Cdr_DllAPI FastCdr
20412041
FastCdr& deserialize_bool_sequence(
20422042
std::vector<bool>& vector_t);
20432043

2044+
/*!
2045+
* @brief Serializes the canonical @c uint8_t representation of @p bool_t.
2046+
*
2047+
* When @c FASTCDR_STRICT_BOOL is defined the serialized value is guaranteed to be exactly @c 0 or @c 1.
2048+
*
2049+
* @param[in] bool_t The boolean value to serialize.
2050+
*/
2051+
void serialize_bool(
2052+
bool bool_t);
2053+
20442054
FastCdr& deserialize_string_sequence(
20452055
std::string*& sequence_t,
20462056
size_t& num_elements);

src/cpp/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ set(${PROJECT_NAME}_source_files
3232
exceptions/Exception.cpp
3333
exceptions/LockedExternalAccessException.cpp
3434
exceptions/NotEnoughMemoryException.cpp
35+
helpers/memory_helpers.cpp
3536
FastCdr.rc
3637
)
3738

@@ -57,6 +58,7 @@ set_target_properties(${PROJECT_NAME} PROPERTIES
5758
target_compile_definitions(${PROJECT_NAME}
5859
PRIVATE
5960
${PROJECT_NAME_UPPER}_SOURCE
61+
$<$<BOOL:${STRICT_BOOL}>:${PROJECT_NAME_UPPER}_STRICT_BOOL>
6062
INTERFACE
6163
$<$<BOOL:${WIN32}>:${PROJECT_NAME_UPPER}_NO_LIB>
6264
PUBLIC

src/cpp/Cdr.cpp

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <limits>
1717

1818
#include <fastcdr/Cdr.h>
19+
#include "helpers/memory_helpers.hpp"
1920

2021
namespace eprosima {
2122
namespace fastcdr {
@@ -821,14 +822,7 @@ Cdr& Cdr::serialize(
821822
// Save last datasize.
822823
last_data_size_ = sizeof(uint8_t);
823824

824-
if (bool_t)
825-
{
826-
offset_++ << static_cast<uint8_t>(1);
827-
}
828-
else
829-
{
830-
offset_++ << static_cast<uint8_t>(0);
831-
}
825+
serialize_bool(bool_t);
832826

833827
return *this;
834828
}
@@ -929,13 +923,7 @@ Cdr& Cdr::serialize_array(
929923

930924
for (size_t count = 0; count < num_elements; ++count)
931925
{
932-
uint8_t value = 0;
933-
934-
if (bool_t[count])
935-
{
936-
value = 1;
937-
}
938-
offset_++ << value;
926+
serialize_bool(bool_t[count]);
939927
}
940928

941929
return *this;
@@ -2179,6 +2167,16 @@ Cdr& Cdr::operator <<(
21792167
return *this;
21802168
}
21812169

2170+
inline void Cdr::serialize_bool(
2171+
bool bool_t)
2172+
{
2173+
#if FASTCDR_STRICT_BOOL
2174+
offset_++ << static_cast<uint8_t>(normalize_bool(bool_t));
2175+
#else
2176+
offset_++ << (bool_t ? static_cast<uint8_t>(1) : static_cast<uint8_t>(0));
2177+
#endif // if FASTCDR_STRICT_BOOL
2178+
}
2179+
21822180
Cdr& Cdr::serialize_bool_array(
21832181
const std::vector<bool>& vector_t)
21842182
{
@@ -2193,14 +2191,7 @@ Cdr& Cdr::serialize_bool_array(
21932191

21942192
for (size_t count = 0; count < vector_t.size(); ++count)
21952193
{
2196-
uint8_t value = 0;
2197-
std::vector<bool>::const_reference ref = vector_t[count];
2198-
2199-
if (ref)
2200-
{
2201-
value = 1;
2202-
}
2203-
offset_++ << value;
2194+
serialize_bool(vector_t[count]);
22042195
}
22052196
}
22062197
else
@@ -2233,14 +2224,7 @@ Cdr& Cdr::serialize_bool_sequence(
22332224

22342225
for (size_t count = 0; count < vector_t.size(); ++count)
22352226
{
2236-
uint8_t value = 0;
2237-
std::vector<bool>::const_reference ref = vector_t[count];
2238-
2239-
if (ref)
2240-
{
2241-
value = 1;
2242-
}
2243-
offset_++ << value;
2227+
serialize_bool(vector_t[count]);
22442228
}
22452229
}
22462230
else

src/cpp/FastCdr.cpp

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <fastcdr/FastCdr.h>
1616
#include <fastcdr/exceptions/BadParamException.h>
1717
#include <string.h>
18+
#include "helpers/memory_helpers.hpp"
1819

1920
using namespace eprosima::fastcdr;
2021
using namespace ::exception;
@@ -90,15 +91,9 @@ bool FastCdr::resize(
9091
FastCdr& FastCdr::serialize(
9192
const bool bool_t)
9293
{
93-
uint8_t value = 0;
94-
9594
if (((last_position_ - current_position_) >= sizeof(uint8_t)) || resize(sizeof(uint8_t)))
9695
{
97-
if (bool_t)
98-
{
99-
value = 1;
100-
}
101-
current_position_++ << value;
96+
serialize_bool(bool_t);
10297

10398
return *this;
10499
}
@@ -190,13 +185,7 @@ FastCdr& FastCdr::serialize_array(
190185
{
191186
for (size_t count = 0; count < num_elements; ++count)
192187
{
193-
uint8_t value = 0;
194-
195-
if (bool_t[count])
196-
{
197-
value = 1;
198-
}
199-
current_position_++ << value;
188+
serialize_bool(bool_t[count]);
200189
}
201190

202191
return *this;
@@ -691,6 +680,16 @@ FastCdr& FastCdr::deserialize_array(
691680
throw NotEnoughMemoryException(NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT);
692681
}
693682

683+
inline void FastCdr::serialize_bool(
684+
bool bool_t)
685+
{
686+
#if FASTCDR_STRICT_BOOL
687+
current_position_++ << static_cast<uint8_t>(normalize_bool(bool_t));
688+
#else
689+
current_position_++ << (bool_t ? static_cast<uint8_t>(1) : static_cast<uint8_t>(0));
690+
#endif // if FASTCDR_STRICT_BOOL
691+
}
692+
694693
FastCdr& FastCdr::serialize_bool_sequence(
695694
const std::vector<bool>& vector_t)
696695
{
@@ -704,14 +703,7 @@ FastCdr& FastCdr::serialize_bool_sequence(
704703
{
705704
for (size_t count = 0; count < vector_t.size(); ++count)
706705
{
707-
uint8_t value = 0;
708-
std::vector<bool>::const_reference ref = vector_t[count];
709-
710-
if (ref)
711-
{
712-
value = 1;
713-
}
714-
current_position_++ << value;
706+
serialize_bool(vector_t[count]);
715707
}
716708
}
717709
else

src/cpp/helpers/memory_helpers.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2026 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "memory_helpers.hpp"
16+
17+
namespace {
18+
void const volatile* volatile global_force_escape_pointer;
19+
} // namespace
20+
21+
void eprosima::fastcdr::internal::use_char_pointer(
22+
char const volatile *const v)
23+
{
24+
global_force_escape_pointer = reinterpret_cast<void const volatile*>(v);
25+
}

0 commit comments

Comments
 (0)