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

Support absent fields in mutable structs #144

Merged
merged 4 commits into from
Feb 29, 2024
Merged

Conversation

snosenzo
Copy link
Collaborator

@snosenzo snosenzo commented Feb 28, 2024

Absent fields in structs do not write emHeaders, so the reading of the emHeader for the field will either return a future field's emHeader or a sentinelHeader. To allow for this, our reader stores the emHeader it reads for absent members and keeps them until it reads a field that is present or the struct ends.

Depends on: foxglove/cdr#24

In this PR, we only return undefined for these fields, however the XCDR spec states that non-optional members should return default values for their types specified here:

image

In the spirit of incremental delivery, this will be a followup PR and ticket.

Addresses: FG-6436

@snosenzo snosenzo requested review from achim-k and jtbandes February 28, 2024 16:47
@@ -149,18 +154,25 @@ export class MessageReader<T = unknown> {
): unknown {
let emHeaderSizeBytes;
if (emHeaderOptions.readMemberHeader) {
const { id, objectSize: objectSizeBytes, lengthCode } = reader.emHeader();
emHeaderSizeBytes = useEmHeaderAsLength(lengthCode) ? objectSizeBytes : undefined;
if (this.#unusedEmHeader?.readSentinelHeader === true) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use a comment to explain what is going on

Comment on lines +147 to +151
/** Holds the return value of the previously unused emHeader.
* emHeaders remain unused if their return ID does not match the field ID.
* They become used if a field is encountered that uses the unusedEmHeader.id or
* if the unusedEmheader is a sentinel header.
**/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a behavior described by the spec? If so maybe reference a relevant section/paragraph?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not defined in the spec, just a quirk of our architecture 🤷

Comment on lines 73 to 75
// clear emHeader for aggregated type, since if it was defined, it would've likely been used
// as the sentinel header
this.#unusedEmHeader = undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not totally sure I understand why this is needed – so in lieu of understanding it I will ask: will one of your tests fail if it is removed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. If it is removed an inner struct's sentinel header(representing the end of a struct), if encountered instead of an emHeader due to an absent final field(s) within the inner struct, will not be cleared, causing subsequent fields read in the outer struct to return undefined because the sentinel header is still stored in unusedEmHeader. This would prevent further reading of the message at all essentially.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the comment to hopefully be more clear

@snosenzo
Copy link
Collaborator Author

Something weird happened with this commit and most of the changes are already on main 🤔 . I'm going to merge this to fix

@snosenzo snosenzo merged commit c1eb034 into main Feb 29, 2024
2 checks passed
@snosenzo snosenzo deleted the support-absent-fields branch February 29, 2024 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants