Skip to content

Commit

Permalink
Refs #18687. Autoselect of cdr version
Browse files Browse the repository at this point in the history
Signed-off-by: Ricardo González Moreno <ricardo@richiware.dev>
  • Loading branch information
richiware committed Jul 11, 2023
1 parent 639d9d9 commit 555c4de
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 15 deletions.
6 changes: 5 additions & 1 deletion include/fastcdr/Cdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class Cdr_DllAPI Cdr
{
public:

//! Represents endianness types.
typedef enum : uint8_t
{
//! @brief Big endianness.
Expand Down Expand Up @@ -4760,6 +4759,11 @@ class Cdr_DllAPI Cdr
EncodingAlgorithmFlag type_encoding,
std::function<bool (Cdr&, const MemberId&)> functor);

/*!
* @brief Resets the internal callbacks depending on the current selected Cdr version.
*/
void reset_callbacks();

using begin_serialize_member_functor = Cdr& (Cdr::*)(
const MemberId&,
bool,
Expand Down
49 changes: 39 additions & 10 deletions src/cpp/Cdr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,25 @@ Cdr::Cdr(
, offset_(cdrBuffer.begin())
, origin_(cdrBuffer.begin())
, end_(cdrBuffer.end())
{
switch (cdr_version_)
{
case CdrVersion::XCDRv2:
align64_ = 4;
break;
case CdrVersion::XCDRv1:
encoding_flag_ = EncodingAlgorithmFlag::PLAIN_CDR;
current_encoding_ = EncodingAlgorithmFlag::PLAIN_CDR;
break;
default:
encoding_flag_ = EncodingAlgorithmFlag::PLAIN_CDR;
current_encoding_ = EncodingAlgorithmFlag::PLAIN_CDR;
break;
}
reset_callbacks();
}

void Cdr::reset_callbacks()
{
switch (cdr_version_)
{
Expand All @@ -102,7 +121,6 @@ Cdr::Cdr(
begin_serialize_type_ = &Cdr::xcdr2_begin_serialize_type;
end_serialize_type_ = &Cdr::xcdr2_end_serialize_type;
deserialize_type_ = &Cdr::xcdr2_deserialize_type;
align64_ = 4;
break;
case CdrVersion::XCDRv1:
begin_serialize_member_ = &Cdr::xcdr1_begin_serialize_member;
Expand All @@ -112,12 +130,15 @@ Cdr::Cdr(
begin_serialize_type_ = &Cdr::xcdr1_begin_serialize_type;
end_serialize_type_ = &Cdr::xcdr1_end_serialize_type;
deserialize_type_ = &Cdr::xcdr1_deserialize_type;
encoding_flag_ = EncodingAlgorithmFlag::PLAIN_CDR;
current_encoding_ = EncodingAlgorithmFlag::PLAIN_CDR;
break;
default:
encoding_flag_ = EncodingAlgorithmFlag::PLAIN_CDR;
current_encoding_ = EncodingAlgorithmFlag::PLAIN_CDR;
begin_serialize_member_ = nullptr;
end_serialize_member_ = nullptr;
begin_serialize_opt_member_ = nullptr;
end_serialize_opt_member_ = nullptr;
begin_serialize_type_ = nullptr;
end_serialize_type_ = nullptr;
deserialize_type_ = nullptr;
break;
}
}
Expand Down Expand Up @@ -158,29 +179,37 @@ Cdr& Cdr::read_encapsulation()
case EncodingAlgorithmFlag::PLAIN_CDR2:
case EncodingAlgorithmFlag::DELIMIT_CDR2:
case EncodingAlgorithmFlag::PL_CDR2:
if (CdrVersion::XCDRv2 != cdr_version_)
if (CdrVersion::XCDRv1 <= cdr_version_)
{
cdr_version_ = CdrVersion::XCDRv2;
}
else
{
throw BadParamException(
"Unexpected encoding algorithm received in Cdr::read_encapsulation. XCDRv2 should be selected.");
}
break;
case EncodingAlgorithmFlag::PL_CDR:
if (CdrVersion::XCDRv1 != cdr_version_)
if (CdrVersion::XCDRv1 <= cdr_version_)
{
cdr_version_ = CdrVersion::XCDRv1;
}
else
{
throw BadParamException(
"Unexpected encoding algorithm received in Cdr::read_encapsulation. XCDRv1 should be selected");
}
break;
case EncodingAlgorithmFlag::PLAIN_CDR:
if (CdrVersion::XCDRv1 < cdr_version_)
if (CdrVersion::XCDRv1 <= cdr_version_)
{
throw BadParamException(
"Unexpected encoding algorithm received in Cdr::read_encapsulation. XCDRv2 shouldn't be selected");
cdr_version_ = CdrVersion::XCDRv1;
}
break;
default:
throw BadParamException("Unexpected encoding algorithm received in Cdr::read_encapsulation for DDS CDR");
}
reset_callbacks();

encoding_flag_ = static_cast<EncodingAlgorithmFlag>(encoding_flag);
current_encoding_ = encoding_flag_;
Expand Down
69 changes: 67 additions & 2 deletions test/xcdr/xcdrv1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,66 @@ using XCdrStreamValues =
std::array<std::vector<unsigned char>,
1 + Cdr::XCdrHeaderSelection::AUTO_WITH_LONG_HEADER_BY_DEFAULT>;

class XCdrv1Test : public ::testing::TestWithParam< Cdr::XCdrHeaderSelection>
class XCdrv1Test : public ::testing::TestWithParam<std::tuple<EncodingAlgorithmFlag, CdrVersion>>
{
};

TEST_P(XCdrv1Test, pl_octet_opt_member)
class XCdrv1PLTest : public ::testing::TestWithParam< Cdr::XCdrHeaderSelection>
{
};

TEST_P(XCdrv1Test, auto_selection_on_decode)
{
EncodingAlgorithmFlag encoding = std::get<0>(GetParam());
Cdr::Endianness endianness = Cdr::Endianness::LITTLE_ENDIANNESS;
auto buffer =
std::unique_ptr<char, void (*)(
void*)>{reinterpret_cast<char*>(calloc(100, sizeof(char))), free};
FastBuffer fast_buffer(buffer.get(), 100);

//{ Encode a ushort and a ulong.
Cdr cdr(fast_buffer, endianness, CdrVersion::XCDRv1);
const uint16_t us {0x01FC};
const uint32_t ul {0x01FC1FCD};
cdr.set_encoding_flag(encoding);
cdr.serialize_encapsulation();
Cdr::state enc_state(cdr);
cdr.begin_serialize_type(enc_state, encoding);
cdr << MemberId(0) << us;
cdr << MemberId(1) << ul;
cdr.end_serialize_type(enc_state);
//}

//{ Decode a ushort and a ulong.
Cdr dcdr(fast_buffer, endianness, std::get<1>(GetParam()));
uint16_t dus{0};
uint32_t dul{0};
dcdr.read_encapsulation();
ASSERT_EQ(dcdr.get_encoding_flag(), encoding);
ASSERT_EQ(dcdr.endianness(), endianness);
dcdr.deserialize_type(encoding, [&](Cdr& dcdr_inner, const MemberId& mid) -> bool
{
bool ret_value = true;
switch (mid.id)
{
case 0:
dcdr_inner >> dus;
break;
case 1:
dcdr_inner >> dul;
break;
default:
ret_value = false;
break;
}

return ret_value;
});
ASSERT_EQ(us, dus);
ASSERT_EQ(ul, dul);
}

TEST_P(XCdrv1PLTest, pl_octet_opt_member)
{
constexpr unsigned char octet_value = 0xCD;

Expand Down Expand Up @@ -113,6 +168,16 @@ TEST_P(XCdrv1Test, pl_octet_opt_member)
INSTANTIATE_TEST_SUITE_P(
XCdrTest,
XCdrv1Test,
::testing::Values(
std::make_tuple(EncodingAlgorithmFlag::PLAIN_CDR, CdrVersion::XCDRv1),
std::make_tuple(EncodingAlgorithmFlag::PLAIN_CDR, CdrVersion::XCDRv2),
std::make_tuple(EncodingAlgorithmFlag::PL_CDR, CdrVersion::XCDRv1),
std::make_tuple(EncodingAlgorithmFlag::PL_CDR, CdrVersion::XCDRv2)
));

INSTANTIATE_TEST_SUITE_P(
XCdrTest,
XCdrv1PLTest,
::testing::Values(
Cdr::XCdrHeaderSelection::SHORT_HEADER,
Cdr::XCdrHeaderSelection::LONG_HEADER,
Expand Down
71 changes: 69 additions & 2 deletions test/xcdr/xcdrv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,66 @@ using XCdrStreamValues =
std::array<std::vector<unsigned char>,
1 + Cdr::XCdrHeaderSelection::AUTO_WITH_LONG_HEADER_BY_DEFAULT>;

class XCdrv2Test : public ::testing::TestWithParam< Cdr::XCdrHeaderSelection>
class XCdrv2Test : public ::testing::TestWithParam<std::tuple<EncodingAlgorithmFlag, CdrVersion>>
{
};

TEST_P(XCdrv2Test, pl_octet_opt_member)
class XCdrv2PLTest : public ::testing::TestWithParam< Cdr::XCdrHeaderSelection>
{
};

TEST_P(XCdrv2Test, auto_selection_on_decode)
{
EncodingAlgorithmFlag encoding = std::get<0>(GetParam());
Cdr::Endianness endianness = Cdr::Endianness::LITTLE_ENDIANNESS;
auto buffer =
std::unique_ptr<char, void (*)(
void*)>{reinterpret_cast<char*>(calloc(100, sizeof(char))), free};
FastBuffer fast_buffer(buffer.get(), 100);

//{ Encode a ushort and a ulong.
Cdr cdr(fast_buffer, endianness, CdrVersion::XCDRv2);
const uint16_t us {0x01FC};
const uint32_t ul {0x01FC1FCD};
cdr.set_encoding_flag(encoding);
cdr.serialize_encapsulation();
Cdr::state enc_state(cdr);
cdr.begin_serialize_type(enc_state, encoding);
cdr << MemberId(0) << us;
cdr << MemberId(1) << ul;
cdr.end_serialize_type(enc_state);
//}

//{ Decode a ushort and a ulong.
Cdr dcdr(fast_buffer, endianness, std::get<1>(GetParam()));
uint16_t dus{0};
uint32_t dul{0};
dcdr.read_encapsulation();
ASSERT_EQ(dcdr.get_encoding_flag(), encoding);
ASSERT_EQ(dcdr.endianness(), endianness);
dcdr.deserialize_type(encoding, [&](Cdr& dcdr_inner, const MemberId& mid) -> bool
{
bool ret_value = true;
switch (mid.id)
{
case 0:
dcdr_inner >> dus;
break;
case 1:
dcdr_inner >> dul;
break;
default:
ret_value = false;
break;
}

return ret_value;
});
ASSERT_EQ(us, dus);
ASSERT_EQ(ul, dul);
}

TEST_P(XCdrv2PLTest, pl_octet_opt_member)
{
constexpr unsigned char octet_value = 0xCD;

Expand Down Expand Up @@ -109,6 +164,18 @@ TEST_P(XCdrv2Test, pl_octet_opt_member)
INSTANTIATE_TEST_SUITE_P(
XCdrTest,
XCdrv2Test,
::testing::Values(
std::make_tuple(EncodingAlgorithmFlag::PLAIN_CDR2, CdrVersion::XCDRv1),
std::make_tuple(EncodingAlgorithmFlag::PLAIN_CDR2, CdrVersion::XCDRv2),
std::make_tuple(EncodingAlgorithmFlag::DELIMIT_CDR2, CdrVersion::XCDRv1),
std::make_tuple(EncodingAlgorithmFlag::DELIMIT_CDR2, CdrVersion::XCDRv2),
std::make_tuple(EncodingAlgorithmFlag::PL_CDR2, CdrVersion::XCDRv1),
std::make_tuple(EncodingAlgorithmFlag::PL_CDR2, CdrVersion::XCDRv2)
));

INSTANTIATE_TEST_SUITE_P(
XCdrTest,
XCdrv2PLTest,
::testing::Values(
Cdr::XCdrHeaderSelection::SHORT_HEADER,
Cdr::XCdrHeaderSelection::LONG_HEADER,
Expand Down

0 comments on commit 555c4de

Please sign in to comment.