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

[XTypes/PL_CDR2] Member header issue for sequences with an inner type of 2 bytes length (short, unsigned short) #334

Open
lexamor opened this issue May 1, 2024 · 0 comments

Comments

@lexamor
Copy link

lexamor commented May 1, 2024

In some cases NEXTINT is not serialized for a sequence with an inner type of 2 bytes length (short, unsigned short), also the incorrect Length code value is assigned.

According to XTypes spec (7.4.3.4.2 Member Header (EMHEADER), Length Code (LC) and NEXTINT).

LC = 4 = 0b100 indicates serialized member length is NEXTINT

The Member header for the sequences of (unsigned) shorts should always be 8 bytes in length (i.e include NEXTINT) and has a Length code of 4, but in some cases depending on the sequence length NEXTINT is not serialized at all, and incorrect LC code value is assigned.

// IDL 
module test 
{
    @mutable
    struct with_short_seq
    {
        sequence<short> the_shorts_;
    };
};

// empty seq
000b0000080000000000002000000000
Screenshot from 2024-05-01 09-27-47

// single el
000b00000a00000000000000010000002a000000
Screenshot from 2024-05-01 09-29-39

//two elements
000b00000c00000000000030020000002a002b00
Screenshot from 2024-05-01 09-31-17

//three elements
000b000012000000000000400a000000030000002a002b002c000000
Screenshot from 2024-05-01 09-32-46

// four elements
000b000014000000000000400c000000040000002a002b002c002d00
Screenshot from 2024-05-01 09-41-07

Looks like that the proper encoding started from the sequences with a length of three elements (correct length code + nextint).

//Reproducible example
//DataWriter

typename test::with_short_seqPubSubType::type data;
for (int i = 0; i < 5; ++i)
{
    std::cout << "Pub: " << i << " seq lenght: " << data.the_shorts_().size() <<"\n";
    writer_->write(&data);
    data.the_shorts_().emplace_back(i + 42);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}

Screenshot from 2024-05-01 09-46-34

//DataReader
void on_data_available(fastdds::DataReader* reader) override

{
    fastdds::SampleInfo info;
    while (reader->take_next_sample(&msg_, &info) == ReturnCode_t::RETCODE_OK)
    {
        if (info.valid_data)
        {
            std::cout << "Rec seq length: " << msg_.the_shorts_().size() << std::endl;
        }
    }
}

Screenshot from 2024-05-01 09-46-20

*Subscriber cannot handle the sequence with a single element, because of malformed member header.

Seems it happened because the generated code calls serialize_member function (from << op) with subsequent xcdr2_begin_serialize_member always with default header_selerction (XCdrHeaderSelection header_selection = XCdrHeaderSelection::AUTO_WITH_SHORT_HEADER_BY_DEFAULT). Later on in the xcdr2_end_serialize_member not switched to the long header because the member length is less or equal than 8 bytes for sequence < 3 elements (8 bytes - length (uint32_t) + 2 * 2B).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant