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

Define, implement & test handling of Float Elements #116

Open
FreezyLemon opened this issue Apr 4, 2023 · 1 comment
Open

Define, implement & test handling of Float Elements #116

FreezyLemon opened this issue Apr 4, 2023 · 1 comment
Labels
spec-compliance Related to EBML or Matroska specification compliance

Comments

@FreezyLemon
Copy link
Contributor

FreezyLemon commented Apr 4, 2023

TL;DR

Float Elements need some special handling:

  • If the Element Size is 0 ("empty float"), interpret as default value (or 0.0, if no default)
  • some NaN stuff (low priority, probably not an issue in practice)

Read on for (a lot) more detail

Summary of the spec

The EBML Float Element consists of an Element ID, an Element Size and the Element Data (like most Elements). The Element ID and Element Size are VINTs.

The EBML spec says that the size can be 0, 4, or 8. A size of 4 or 8 means that the data is a big-endian 32- or 64-bit floating-point number as defined in IEEE 754. A size of 0 (what I might call an "empty float") is equivalent to the default value of that Element, or 0.0 if the Element has no default. Any other Element Size is not allowed.

Like most Elements, Float Elements are optional if

  • minOccurs is 0 (or not specified) OR
  • minOccurs = maxOccurs = 1 AND the Element has a default value in the spec.

Otherwise, they are required.

NaN

The Rust docs for f32 have a small explanation of the issues with signalling and quiet NaN handling:

However there is one caveat: prior to the 2008 version of IEEE 754, how to interpret the NaN signaling bit wasn’t actually specified. Most platforms (notably x86 and ARM) picked the interpretation that was ultimately standardized in 2008, but some didn’t (notably MIPS). As a result, all signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.

I wasn't aware of this and thought it was still not specified. Now it might make sense to test IEEE 754-2008 compliance, but it's probably not required. I'm not sure NaNs (and more specifically, correct NaN handling in terms of quiet and signalling NaNs) will ever be an issue for Matroska.

Error & edge case handling

(originally addressed in #115)

When parsing a Float Element, there's 3 relevant edge cases we should maybe handle:

  1. A nom VerifyError -> Float Element with that ID doesn't exist
  2. A ParseError::EmptyFloat -> Element exists but has a length of 0.
  3. A ParseError::FloatWidthIncorrect -> Element exists but has a length that is not 0, 4 or 8.

The type we use on the Rust side is either an Option<f64> (optional, if minOccurs = 0) or an f64 (required, if minOccurs = maxOccurs = 1).

I think we want this behaviour:

No. Output type VerifyError EmptyFloat
1 Option<f64> None Some(0)
2 f64, no default Err 0
3 f64, default d d d
@FreezyLemon
Copy link
Contributor Author

I changed the original issue a bit and added a short summary. I realize I made this more complicated than it needed to be.

Float Elements can generally be handled like any other Element, except for the case that the Element Size is zero.

@FreezyLemon FreezyLemon added the spec-compliance Related to EBML or Matroska specification compliance label Apr 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spec-compliance Related to EBML or Matroska specification compliance
Projects
None yet
Development

No branches or pull requests

1 participant